(file) Return to emdr.c CVS log (file) (dir) Up to [venge] / src / emdr

File: [venge] / src / emdr / emdr.c (download)
Revision: 1.2, Fri Apr 28 01:08:33 2000 UTC (10 years, 4 months ago) by graydon
Branch: MAIN
CVS Tags: HEAD
Changes since 1.1: +240 -34 lines
rewrote emdr. now quite adjustable (width, height, speed, color)

/** 
    
    this is some simple free software to assist in delivering 
    EMDR (eye movement desensitization and reprocessing) therapy,
    which is a psychological therapy for people afflicted with
    post traumatic stress disorder. 

    copyright (C) 2000 vengeance software
    written by graydon hoare <graydon@pobox.com>

*/

#include <stdio.h>
#include <SDL/SDL.h>

#define VALUE 1
#define POINTER 0
#define TRUE 1
#define FALSE 0
#define MAX(A,B) (A>B?A:B)
#define MIN(A,B) (A<B?A:B)

struct _emdr;
typedef void (*painter_fn)(struct _emdr *state, SDL_Surface *screen, int blank);

typedef struct {
  char *name;
  void *ptr;
} named_ptr;


typedef struct _emdr {
  named_ptr *painter;
  int x,y,w,h;
  int r,g,b;
  int step;
  named_ptr *sample;
  int pitch,volume;
} emdr;

typedef struct {
  char key;
  char *msg;
  int adj_type;
  named_ptr *min_ptr, **adj_ptr, *max_ptr;
  int min_val, *adj_val, max_val;
} adjustable;

void paint_rect(emdr *state, SDL_Surface *screen, int blank) {
  SDL_Rect rect;
  Uint32 col;

  rect.x = state->x;
  rect.y = state->y;
  rect.h = state->h;
  rect.w = state->w;

  if (blank)
    col = SDL_MapRGB(screen->format, 0, 0, 0); 
  else 
    col = SDL_MapRGB(screen->format, state->r, state->g, state->b); 
  SDL_FillRect(screen, &(rect), col); 
}

void paint_ellipse(emdr *state, int blank) {
}


static named_ptr painters[2] = 
{
  {"rectangle", &paint_rect},
  {"ellipse", &paint_ellipse}
};



void init_emdr(emdr *curr, FILE *file) {

  curr->painter = painters;
  curr->x = 0;
  curr->y = 240;
  curr->w = 50;
  curr->h = 10;
  curr->r = 0;
  curr->g = 127;
  curr->b = 127;
  curr->step = 15;
  curr->sample = NULL;
  curr->pitch = 127;
  curr->volume = 127;
}

void handle_key_event(Uint16 key, emdr *state, 	      
		      emdr *states, int num_states, 
		      adjustable **adj,
		      adjustable *controls, int num_ctrls,		      
		      FILE *file) {
  int i;
  switch(key) {
  case 'r':
  case 'g':
  case 'b':
  case 'w':
  case 'h':
  case 's':
    
    for(i = 0; i < num_ctrls; i++) {
      if ((controls + i)->key == key) {
	*adj = (controls + i);
	return;
      }
    }
    break;
    
  case '+':
    if ((*adj)->adj_type == VALUE) {
      int *v = ((*adj)->adj_val);
      *v = MIN(*v + 1, ((*adj)->max_val));
    } else {
      named_ptr **p = ((*adj)->adj_ptr);
      *p = MIN(*p + 1, ((*adj)->max_ptr));
    }
    break;

  case '-':
    if ((*adj)->adj_type == VALUE) {
      int *v = ((*adj)->adj_val);
      *v = MAX(*v - 1, ((*adj)->min_val));
    } else {
      named_ptr **p = ((*adj)->adj_ptr);
      *p = MAX(*p - 1, ((*adj)->min_ptr));
    }
    break;

  case 'q':
    exit(0);
    break;
  }  
}

void run_emdr(emdr *state,
	      emdr *states, int num_states, 
	      adjustable *controls, int num_ctrls, 
	      SDL_Surface *screen, int screenwidth,
	      FILE *file) {

  SDL_Rect rect[2];
  SDL_Event event;
  int going_right = 1;
  adjustable *adj = controls;

  *state = states[0];
  SDL_EventState(SDL_KEYDOWN, SDL_ENABLE);
  SDL_EnableUNICODE(1);
  SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);

#define LEFT_SIDE (state->x)
#define RIGHT_SIDE (state->x + state->w)
#define LEFT_EDGE 0
#define RIGHT_EDGE screenwidth

  while((LEFT_SIDE >= LEFT_EDGE) && 
	(RIGHT_SIDE < RIGHT_EDGE)) {
    
    /* compute motion */
    if (going_right) {
      if (RIGHT_SIDE + state->step >= RIGHT_EDGE) {
	going_right = FALSE;
	LEFT_SIDE -= state->step;
      } else {
	LEFT_SIDE += state->step;
      }
    } else {
      /* going left */
      if (LEFT_SIDE - state->step <= LEFT_EDGE) {
	going_right = TRUE;
	LEFT_SIDE += state->step;
      } else {
	LEFT_SIDE -= state->step;
      }
    }
      
    /* paint the current image */
    ((painter_fn)(state->painter->ptr))(state, screen, 0);
    rect[1].x = state->x;
    rect[1].y = state->y;
    rect[1].h = state->h;
    rect[1].w = state->w;
    
    /* flush image and wait 10 msecs */
    SDL_UpdateRects(screen,2,rect);
    SDL_Delay(10);
    
    /* blank painted region in preparation for new paint */
    ((painter_fn)(state->painter->ptr))(state, screen, 1);
    rect[0].x = state->x;
    rect[0].y = state->y;
    rect[0].h = state->h;
    rect[0].w = state->w;
    
    /* handle any pending key signals */
    if (SDL_PollEvent(&event)) {
      if (event.type == SDL_KEYDOWN) {
	handle_key_event(event.key.keysym.unicode, state,
			 states, num_states, &adj,
			 controls, num_ctrls,
			 file);
      }
    }            
  }
}

int main(int argc, char **argv) {

#define num_ctrls 10
#define num_states 10

  int i;
  emdr states[num_states]; 
  SDL_Surface *screen;
  int screenwidth = 640, screenheight = 480;
  FILE *file;
  
  static emdr state;
  static adjustable controls[num_ctrls] = {
    {'r', "red", VALUE, NULL, NULL, NULL, 0, &(state.r), 255},
    {'g', "green", VALUE, NULL, NULL, NULL, 0, &(state.g), 255},
    {'b', "blue", VALUE, NULL, NULL, NULL, 0, &(state.b), 255},
    {'w', "width", VALUE, NULL, NULL, NULL, 0, &(state.w), 255},
    {'h', "height", VALUE, NULL, NULL, NULL, 0, &(state.h), 255},
    {'s', "step", VALUE, NULL, NULL, NULL, 0, &(state.step), 255},
    {'p', "pitch", VALUE, NULL, NULL, NULL, 0, &(state.pitch), 255},
    {'v', "volume", VALUE, NULL, NULL, NULL, 0, &(state.volume), 255},
    {'a', "sample", POINTER, NULL, &(state.sample), NULL, 0, NULL, 255},
    {'i', "image", POINTER, painters, &(state.painter), painters+1, 0, NULL, 255},
  };
  
  file = fopen("emdr.config","r+");

  /* Initialize the SDL library */
  if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
    fprintf(stderr,
	    "Couldn't initialize SDL: %s\n", SDL_GetError());
    exit(1);
  }
  
  /* Clean up on exit */
  atexit(SDL_Quit);
  
  /* Initialize the display */
  screen = SDL_SetVideoMode(screenwidth, screenheight, 8, SDL_SWSURFACE);
  if ( screen == NULL ) {
    fprintf(stderr, "Couldn't set video mode: %s\n",
	    SDL_GetError());
    exit(1);
  }


  for (i = 0; i < num_states; i++)
    init_emdr(states + i, file);

  run_emdr(&state,
	   states, num_states, 
	   controls, num_ctrls, 
	   screen, screenwidth, file);  
  return 0;
}


graydon hoare
Powered by
ViewCVS 0.9.2