diff --git a/magic/src/rails.c b/magic/src/rails.c index 9b82d33a7..1f7895f65 100644 --- a/magic/src/rails.c +++ b/magic/src/rails.c @@ -21,96 +21,94 @@ #define SEG_RIGHT_TOP_BOTTOM (SEG_RIGHT | SEG_TOP | SEG_BOTTOM) #define SEG_LEFT_RIGHT_TOP_BOTTOM (SEG_LEFT | SEG_RIGHT | SEG_TOP | SEG_BOTTOM) -Mix_Chunk * rails_snd; +Mix_Chunk *rails_snd; unsigned int img_w, img_h; -unsigned int rails_segments_x, rails_segments_y; //how many segments do we have? -static int rails_math_ceil(int x, int y); //ceil() in cstdlib returns float and is relative slow, so we'll use our one -static Uint8 * rails_status_of_segments; //a place to store an info about bitmap used for selected segment -static char ** rails_images; //the pathes to all the images needed -static unsigned int rails_segment_modified; //which segment was modified this time? -static unsigned int rails_segment_modified_last =0; //which segment was last modified -static unsigned int rails_segment_to_add =0; //a segment that should be added to solve corner joints +unsigned int rails_segments_x, rails_segments_y; //how many segments do we have? +static int rails_math_ceil(int x, int y); //ceil() in cstdlib returns float and is relative slow, so we'll use our one +static Uint8 *rails_status_of_segments; //a place to store an info about bitmap used for selected segment +static char **rails_images; //the pathes to all the images needed +static unsigned int rails_segment_modified; //which segment was modified this time? +static unsigned int rails_segment_modified_last = 0; //which segment was last modified +static unsigned int rails_segment_to_add = 0; //a segment that should be added to solve corner joints static SDL_Rect modification_rect; -static SDL_Surface * canvas_backup; -// Housekeeping functions +static SDL_Surface *canvas_backup; -SDL_Surface * rails_one, * rails_three, * rails_four, * rails_corner; +// Housekeeping functions + +SDL_Surface *rails_one, *rails_three, *rails_four, *rails_corner; Uint32 rails_api_version(void); int rails_modes(magic_api * api, int which); void rails_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b); int rails_init(magic_api * api); int rails_get_tool_count(magic_api * api); -SDL_Surface * rails_get_icon(magic_api * api, int which); -char * rails_get_name(magic_api * api, int which); -char * rails_get_description(magic_api * api, int which, int mode); +SDL_Surface *rails_get_icon(magic_api * api, int which); +char *rails_get_name(magic_api * api, int which); +char *rails_get_description(magic_api * api, int which, int mode); int rails_requires_colors(magic_api * api, int which); void rails_release(magic_api * api, int which, - SDL_Surface * canvas, SDL_Surface * snapshot, - int x, int y, SDL_Rect * update_rect); + SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect); void rails_shutdown(magic_api * api); void rails_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas); void rails_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas); static int rails_math_ceil(int x, int y); -inline unsigned int rails_get_segment(int x, int y); +inline unsigned int rails_get_segment(int x, int y); inline void rails_extract_coords_from_segment(unsigned int segment, Sint16 * x, Sint16 * y); -static void rails_flip(void * ptr, SDL_Surface * dest, SDL_Surface * src); -static void rails_flip_flop(void * ptr, SDL_Surface * dest, SDL_Surface * src); -static void rails_rotate (void * ptr, SDL_Surface * dest, SDL_Surface * src, unsigned int direction); +static void rails_flip(void *ptr, SDL_Surface * dest, SDL_Surface * src); +static void rails_flip_flop(void *ptr, SDL_Surface * dest, SDL_Surface * src); +static void rails_rotate(void *ptr, SDL_Surface * dest, SDL_Surface * src, unsigned int direction); void rails_click(magic_api * api, int which, int mode, - SDL_Surface * canvas, SDL_Surface * snapshot, - int x, int y, SDL_Rect * update_rect); + SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect); static Uint8 rails_select_image(Uint16 segment); -static void rails_draw(void * ptr, int which, SDL_Surface * canvas, SDL_Surface * last, - int x, int y, unsigned int segment); +static void rails_draw(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, + int x, int y, unsigned int segment); -static void rails_draw_wrapper(void * ptr, int which, SDL_Surface * canvas, SDL_Surface * last, - int x, int y); +static void rails_draw_wrapper(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y); void rails_drag(magic_api * api, int which, SDL_Surface * canvas, - SDL_Surface * snapshot, int ox, int oy, int x, int y, - SDL_Rect * update_rect); + SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect); Uint32 rails_api_version(void) { - return(TP_MAGIC_API_VERSION); + return (TP_MAGIC_API_VERSION); } int rails_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) { - return(MODE_PAINT); + return (MODE_PAINT); } -void rails_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED, Uint8 b ATTRIBUTE_UNUSED) +void rails_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED, + Uint8 b ATTRIBUTE_UNUSED) { } int rails_init(magic_api * api) { - char fname[1024]; - Uint8 i; //is always < 3, so Uint8 seems to be a good idea - - rails_images=(char **)malloc(sizeof(char *)*4); - - for (i = 0; i < 4; i++) - rails_images[i]=(char *)malloc(sizeof(char)*1024); - - snprintf(rails_images[0], 1024*sizeof(char), "%s/images/magic/rails_one.png", api->data_directory); - snprintf(rails_images[1], 1024*sizeof(char), "%s/images/magic/rails_three.png", api->data_directory); - snprintf(rails_images[2], 1024*sizeof(char), "%s/images/magic/rails_four.png", api->data_directory); - snprintf(rails_images[3], 1024*sizeof(char), "%s/images/magic/rails_corner.png", api->data_directory); + char fname[1024]; + Uint8 i; //is always < 3, so Uint8 seems to be a good idea - rails_one=IMG_Load(rails_images[0]); - rails_three=IMG_Load(rails_images[1]); - rails_four=IMG_Load(rails_images[2]); - rails_corner=IMG_Load(rails_images[3]); + rails_images = (char **)malloc(sizeof(char *) * 4); - img_w = rails_one->w; - img_h = rails_one->h; - - snprintf(fname, sizeof(fname), "%s/sounds/magic/rails.wav", api->data_directory); - rails_snd = Mix_LoadWAV(fname); + for (i = 0; i < 4; i++) + rails_images[i] = (char *)malloc(sizeof(char) * 1024); - return(1); + snprintf(rails_images[0], 1024 * sizeof(char), "%s/images/magic/rails_one.png", api->data_directory); + snprintf(rails_images[1], 1024 * sizeof(char), "%s/images/magic/rails_three.png", api->data_directory); + snprintf(rails_images[2], 1024 * sizeof(char), "%s/images/magic/rails_four.png", api->data_directory); + snprintf(rails_images[3], 1024 * sizeof(char), "%s/images/magic/rails_corner.png", api->data_directory); + + rails_one = IMG_Load(rails_images[0]); + rails_three = IMG_Load(rails_images[1]); + rails_four = IMG_Load(rails_images[2]); + rails_corner = IMG_Load(rails_images[3]); + + img_w = rails_one->w; + img_h = rails_one->h; + + snprintf(fname, sizeof(fname), "%s/sounds/magic/rails.wav", api->data_directory); + rails_snd = Mix_LoadWAV(fname); + + return (1); } int rails_get_tool_count(magic_api * api ATTRIBUTE_UNUSED) @@ -118,407 +116,434 @@ int rails_get_tool_count(magic_api * api ATTRIBUTE_UNUSED) return 1; } -SDL_Surface * rails_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED) +SDL_Surface *rails_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED) { char fname[1024]; - snprintf(fname, sizeof(fname), "%s/images/magic/rails.png", - api->data_directory); + snprintf(fname, sizeof(fname), "%s/images/magic/rails.png", api->data_directory); - return(IMG_Load(fname)); + return (IMG_Load(fname)); } -char * rails_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) { return strdup(gettext_noop("Rails")); } +char *rails_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) +{ + return strdup(gettext_noop("Rails")); +} -char * rails_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED) { return strdup(gettext_noop("Click and drag to draw train track rails on your picture.")); } +char *rails_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED) +{ + return strdup(gettext_noop("Click and drag to draw train track rails on your picture.")); +} -int rails_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) { return 0;} +int rails_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED) +{ + return 0; +} void rails_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, - SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * snapshot ATTRIBUTE_UNUSED, - int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED) + SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * snapshot ATTRIBUTE_UNUSED, + int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED) { } void rails_shutdown(magic_api * api ATTRIBUTE_UNUSED) { - Uint8 i; - - if (rails_snd!=NULL) - Mix_FreeChunk(rails_snd); - SDL_FreeSurface(rails_one); - SDL_FreeSurface(rails_three); - SDL_FreeSurface(rails_four); - SDL_FreeSurface(rails_corner); - SDL_FreeSurface(canvas_backup); - - for (i = 0; i < 4; i++) - free(rails_images[i]); - free(rails_images); - if (rails_status_of_segments != NULL) - free(rails_status_of_segments); + Uint8 i; + + if (rails_snd != NULL) + Mix_FreeChunk(rails_snd); + SDL_FreeSurface(rails_one); + SDL_FreeSurface(rails_three); + SDL_FreeSurface(rails_four); + SDL_FreeSurface(rails_corner); + SDL_FreeSurface(canvas_backup); + + for (i = 0; i < 4; i++) + free(rails_images[i]); + free(rails_images); + if (rails_status_of_segments != NULL) + free(rails_status_of_segments); } -void rails_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas) +void rails_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, + SDL_Surface * canvas) { - //we've to compute the quantity of segments in each direction + //we've to compute the quantity of segments in each direction - canvas_backup=SDL_CreateRGBSurface(SDL_ANYFORMAT, canvas->w, canvas->h, canvas->format->BitsPerPixel, - canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask, canvas->format->Amask); + canvas_backup = SDL_CreateRGBSurface(SDL_ANYFORMAT, canvas->w, canvas->h, canvas->format->BitsPerPixel, + canvas->format->Rmask, canvas->format->Gmask, canvas->format->Bmask, + canvas->format->Amask); - SDL_BlitSurface(canvas, NULL, canvas_backup, NULL); - rails_segments_x=rails_math_ceil(canvas->w,img_w); - rails_segments_y=rails_math_ceil(canvas->h,img_h); - //status_of_segments[0] will not be used, we write in rails_status_of_segments[1 to segments_x*segments_y] - rails_status_of_segments=(Uint8 *)calloc(rails_segments_x*rails_segments_y + 1, sizeof(Uint8)); + SDL_BlitSurface(canvas, NULL, canvas_backup, NULL); + rails_segments_x = rails_math_ceil(canvas->w, img_w); + rails_segments_y = rails_math_ceil(canvas->h, img_h); + //status_of_segments[0] will not be used, we write in rails_status_of_segments[1 to segments_x*segments_y] + rails_status_of_segments = (Uint8 *) calloc(rails_segments_x * rails_segments_y + 1, sizeof(Uint8)); } -void rails_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas ATTRIBUTE_UNUSED) +void rails_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED, + SDL_Surface * canvas ATTRIBUTE_UNUSED) { - if (rails_status_of_segments != NULL) - { - free(rails_status_of_segments); - rails_status_of_segments = NULL; - } + if (rails_status_of_segments != NULL) + { + free(rails_status_of_segments); + rails_status_of_segments = NULL; + } } // Interactivity functions static int rails_math_ceil(int x, int y) -{ - int temp; - temp=(int)x/y; - - if (x%y) - return temp+1; - else return temp; -} - -inline unsigned int rails_get_segment(int x, int y) { - int xx; //segments are numerated just like pixels - int yy; //in computer graphics: left upper (=1), ... ,right upper, - //left bottom, ... , right bottom - xx=rails_math_ceil(x, img_w); - yy=rails_math_ceil(y, img_h); - - return (yy-1)*rails_segments_x+xx; - + int temp; + + temp = (int)x / y; + + if (x % y) + return temp + 1; + else + return temp; +} + +inline unsigned int rails_get_segment(int x, int y) +{ + int xx; //segments are numerated just like pixels + int yy; //in computer graphics: left upper (=1), ... ,right upper, + + //left bottom, ... , right bottom + xx = rails_math_ceil(x, img_w); + yy = rails_math_ceil(y, img_h); + + return (yy - 1) * rails_segments_x + xx; + } inline void rails_extract_coords_from_segment(unsigned int segment, Sint16 * x, Sint16 * y) -{ //extracts the coords of the beginning and the segment - *x=((segment%rails_segments_x)-1)*img_w; //useful to set update_rect as small as possible - *y=(int)(segment/rails_segments_x)*img_h; +{ //extracts the coords of the beginning and the segment + *x = ((segment % rails_segments_x) - 1) * img_w; //useful to set update_rect as small as possible + *y = (int)(segment / rails_segments_x) * img_h; } -static void rails_flip(void * ptr, SDL_Surface * dest, SDL_Surface * src) +static void rails_flip(void *ptr, SDL_Surface * dest, SDL_Surface * src) { - magic_api * api = (magic_api *) ptr; + magic_api *api = (magic_api *) ptr; - Sint16 x, y; - - for (x=0; xw; x++) - for (y=0; yh; y++) - api->putpixel(dest, x, y, api->getpixel(src, x, src->h-y-1)); -} -static void rails_flip_flop(void * ptr, SDL_Surface * dest, SDL_Surface * src) -{ - magic_api * api = (magic_api *) ptr; Sint16 x, y; - for (x=0; xw; x++) - for (y=0; yh; y++) + + for (x = 0; x < dest->w; x++) + for (y = 0; y < dest->h; y++) + api->putpixel(dest, x, y, api->getpixel(src, x, src->h - y - 1)); +} + +static void rails_flip_flop(void *ptr, SDL_Surface * dest, SDL_Surface * src) +{ + magic_api *api = (magic_api *) ptr; + Sint16 x, y; + + for (x = 0; x < dest->w; x++) + for (y = 0; y < dest->h; y++) api->putpixel(dest, x, y, api->getpixel(src, y, x)); } -static void rails_rotate (void * ptr, SDL_Surface * dest, SDL_Surface * src, unsigned int direction) +static void rails_rotate(void *ptr, SDL_Surface * dest, SDL_Surface * src, unsigned int direction) //src and dest must have same size { - magic_api * api = (magic_api *) ptr; - Sint16 x,y; - - if (direction) //rotate -90 degs - { - for (x = 0; xw; x++) - for (y =0; yh; y++) - api->putpixel(dest, x, y, api->getpixel(src, y, src->w-x-1)); - } - else //rotate +90 degs - { - for (x=0; xw; x++) - for (y=0; yh; y++) - api->putpixel(dest,x,y,api->getpixel(src,src->h-y-1,x)); - } - + magic_api *api = (magic_api *) ptr; + Sint16 x, y; + + if (direction) //rotate -90 degs + { + for (x = 0; x < dest->w; x++) + for (y = 0; y < dest->h; y++) + api->putpixel(dest, x, y, api->getpixel(src, y, src->w - x - 1)); + } + else //rotate +90 degs + { + for (x = 0; x < dest->w; x++) + for (y = 0; y < dest->h; y++) + api->putpixel(dest, x, y, api->getpixel(src, src->h - y - 1, x)); + } + } void rails_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED, - SDL_Surface * canvas, SDL_Surface * snapshot, - int x, int y, SDL_Rect * update_rect) + SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect) { - rails_segment_modified_last = 0; - rails_drag(api, which, canvas, snapshot, x, y, x, y, update_rect); + rails_segment_modified_last = 0; + rails_drag(api, which, canvas, snapshot, x, y, x, y, update_rect); } static Uint8 rails_select_image(Uint16 segment) { - int take_up, take_down; - int val_up, val_down, val_left, val_right; - int from_top=0, from_bottom=0, from_left = 0, from_right = 0; - int from_top_right=0, from_top_left=0, from_bottom_right=0, from_bottom_left = 0; - int TOP=0, BOTTOM=0, LEFT=0, RIGHT = 0; - - //Checking from were we come... - if (rails_segment_modified_last>0) - { - if (segment == rails_segment_modified_last + 1) - from_left = 1; + int take_up, take_down; + int val_up, val_down, val_left, val_right; + int from_top = 0, from_bottom = 0, from_left = 0, from_right = 0; + int from_top_right = 0, from_top_left = 0, from_bottom_right = 0, from_bottom_left = 0; + int TOP = 0, BOTTOM = 0, LEFT = 0, RIGHT = 0; - if (segment == rails_segment_modified_last - 1) - from_right = 1; + //Checking from were we come... + if (rails_segment_modified_last > 0) + { + if (segment == rails_segment_modified_last + 1) + from_left = 1; - if (segment == rails_segment_modified_last - rails_segments_x) - from_bottom = 1; + if (segment == rails_segment_modified_last - 1) + from_right = 1; - if (segment == rails_segment_modified_last + rails_segments_x) - from_top = 1; + if (segment == rails_segment_modified_last - rails_segments_x) + from_bottom = 1; - // Segments are joining by the corner - // We need to add a new segment to join by side, adding clockwise - if (segment == rails_segment_modified_last + rails_segments_x + 1) - { - from_top_left = 1; - rails_segment_to_add = segment - rails_segments_x; - } + if (segment == rails_segment_modified_last + rails_segments_x) + from_top = 1; - if (segment == rails_segment_modified_last + rails_segments_x - 1) - { - from_top_right = 1; - rails_segment_to_add = segment + 1; - } + // Segments are joining by the corner + // We need to add a new segment to join by side, adding clockwise + if (segment == rails_segment_modified_last + rails_segments_x + 1) + { + from_top_left = 1; + rails_segment_to_add = segment - rails_segments_x; + } - if (segment == rails_segment_modified_last - rails_segments_x - 1) - { - from_bottom_right = 1; - rails_segment_to_add = segment + rails_segments_x; - } - if (segment == rails_segment_modified_last - rails_segments_x + 1) - { - from_bottom_left = 1; - rails_segment_to_add = segment -1; - } - } + if (segment == rails_segment_modified_last + rails_segments_x - 1) + { + from_top_right = 1; + rails_segment_to_add = segment + 1; + } - - - - - take_up=segment-rails_segments_x; - if (take_up<=0) val_up = SEG_NONE; - else val_up = rails_status_of_segments[take_up]; - - take_down=segment+rails_segments_x; - if (take_down>(signed)(rails_segments_x*rails_segments_y)) val_down = SEG_NONE; - else val_down = rails_status_of_segments[take_down]; - - if ((segment%rails_segments_x)==1) val_left=SEG_NONE; - else val_left = rails_status_of_segments[segment-1]; - - if ((segment%rails_segments_x)==0) val_right=SEG_NONE; - else val_right = rails_status_of_segments[segment+1]; - - if ( from_left || (val_left & SEG_RIGHT) || from_bottom_left) - { - LEFT = 1;} - if ( from_right || (val_right & SEG_LEFT) || from_top_right) - RIGHT=1; - if ( from_top || (val_up & SEG_BOTTOM) || from_top_left) - TOP=1; - if (from_bottom || (val_down & SEG_TOP) || from_bottom_right) - BOTTOM=1; - - - if (TOP && BOTTOM && LEFT && RIGHT) - return SEG_LEFT_RIGHT_TOP_BOTTOM; - if (LEFT && RIGHT && TOP) - return SEG_LEFT_RIGHT_TOP; - if (LEFT && RIGHT && BOTTOM) - return SEG_LEFT_RIGHT_BOTTOM; - if (TOP && BOTTOM && LEFT) - return SEG_LEFT_TOP_BOTTOM; - if (TOP && BOTTOM && RIGHT) - return SEG_RIGHT_TOP_BOTTOM; - if (LEFT &&RIGHT) - return SEG_LEFT_RIGHT; - if (TOP&&BOTTOM) - return SEG_TOP_BOTTOM; - if (LEFT&&TOP) - return SEG_LEFT_TOP; - if (LEFT&&BOTTOM) - return SEG_LEFT_BOTTOM; - if (RIGHT&&TOP) - return SEG_RIGHT_TOP; - if (RIGHT&&BOTTOM) - return SEG_RIGHT_BOTTOM; - if (LEFT|RIGHT) - return SEG_LEFT_RIGHT; - return SEG_TOP_BOTTOM; - - - -} - -static void rails_draw(void * ptr, int which ATTRIBUTE_UNUSED, ATTRIBUTE_UNUSED SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED, - int x, int y ATTRIBUTE_UNUSED, unsigned int segment) -{ - magic_api * api = (magic_api *) ptr; - SDL_Surface * result, * temp; - Uint8 image; - unsigned int use_temp; - - use_temp=0; - if (segment>rails_segments_x*rails_segments_y) - return; - //modification_rect.x and modification_rect.y are set by function - rails_extract_coords_from_segment(segment, &modification_rect.x, &modification_rect.y); - modification_rect.h=img_w; - modification_rect.w=img_h; - - image=rails_select_image(segment); //select the image to display - - if (rails_status_of_segments[segment] == image) - return; - - rails_status_of_segments[segment]=image; //and write it to global table - - - result=SDL_CreateRGBSurface(SDL_ANYFORMAT, img_w, img_h, rails_one->format->BitsPerPixel, - rails_one->format->Rmask, rails_one->format->Gmask, rails_one->format->Bmask, rails_one->format->Amask); - - temp=SDL_CreateRGBSurface(SDL_ANYFORMAT, img_w, img_h, rails_one->format->BitsPerPixel, - rails_one->format->Rmask, rails_one->format->Gmask, rails_one->format->Bmask, rails_one->format->Amask); - - SDL_BlitSurface(canvas_backup, &modification_rect, result, NULL); - - - switch(image) - { - case 0: - case SEG_TOP_BOTTOM: - SDL_BlitSurface(canvas_backup, &modification_rect, result, NULL); - SDL_BlitSurface(rails_one, NULL, result, NULL); - break; - - case SEG_LEFT_RIGHT: - SDL_BlitSurface(canvas_backup, &modification_rect, result, NULL); - rails_rotate(api, temp, rails_one, 1); - use_temp=1; - break; - - case SEG_LEFT_RIGHT_TOP_BOTTOM: - SDL_BlitSurface(canvas_backup, &modification_rect, result, NULL); - SDL_BlitSurface(rails_four, NULL, result, NULL); - break; - - case SEG_LEFT_RIGHT_TOP: - SDL_BlitSurface(rails_three, NULL, result, NULL); - break; - - case SEG_LEFT_RIGHT_BOTTOM: - rails_flip(api, temp, rails_three); - use_temp=1; - break; - - case SEG_LEFT_TOP_BOTTOM: - rails_rotate(api, temp, rails_three, 0); - use_temp=1; - break; - - case SEG_RIGHT_TOP_BOTTOM: - rails_rotate(api, temp, rails_three, 1); - use_temp=1; - break; - - case SEG_RIGHT_TOP: - SDL_BlitSurface(rails_corner, NULL, result, NULL); - break; - - case SEG_RIGHT_BOTTOM: - rails_flip(api, temp, rails_corner); - use_temp=1; - break; - - case SEG_LEFT_TOP: - rails_rotate(api, temp, rails_corner, 0); - use_temp=1; - break; - - case SEG_LEFT_BOTTOM: - rails_flip_flop(api, temp, rails_corner); - use_temp=1; - break; - } - - if (use_temp) - SDL_BlitSurface(temp, NULL, result, NULL); - - SDL_FreeSurface(temp); - SDL_BlitSurface(result, NULL, canvas, &modification_rect); - SDL_FreeSurface(result); - api->playsound(rails_snd, (x * 255) / canvas->w, 255); -} - -static void rails_draw_wrapper(void * ptr, int which, SDL_Surface * canvas, SDL_Surface * last, - int x, int y) -{ - rails_segment_modified=rails_get_segment(x,y); - - - if ( (rails_segment_modified == rails_segment_modified_last)) - return; -if (rails_segment_modified>0) - { - rails_draw((void *) ptr, which, canvas, last, x, y, rails_segment_modified); - } - if (rails_segment_modified_last>0) - rails_draw((void *) ptr, which, canvas, last, x, y, rails_segment_modified_last); - - if (rails_segment_to_add>0) - { - rails_draw((void *) ptr, which, canvas, last, x, y, rails_segment_to_add); - rails_draw((void *) ptr, which, canvas, last, x, y, rails_segment_modified_last); - rails_segment_to_add=0; + if (segment == rails_segment_modified_last - rails_segments_x - 1) + { + from_bottom_right = 1; + rails_segment_to_add = segment + rails_segments_x; + } + if (segment == rails_segment_modified_last - rails_segments_x + 1) + { + from_bottom_left = 1; + rails_segment_to_add = segment - 1; + } } -if (rails_segment_modified>0) - rails_segment_modified_last=rails_segment_modified; + + + + + + take_up = segment - rails_segments_x; + if (take_up <= 0) + val_up = SEG_NONE; + else + val_up = rails_status_of_segments[take_up]; + + take_down = segment + rails_segments_x; + if (take_down > (signed)(rails_segments_x * rails_segments_y)) + val_down = SEG_NONE; + else + val_down = rails_status_of_segments[take_down]; + + if ((segment % rails_segments_x) == 1) + val_left = SEG_NONE; + else + val_left = rails_status_of_segments[segment - 1]; + + if ((segment % rails_segments_x) == 0) + val_right = SEG_NONE; + else + val_right = rails_status_of_segments[segment + 1]; + + if (from_left || (val_left & SEG_RIGHT) || from_bottom_left) + { + LEFT = 1; + } + if (from_right || (val_right & SEG_LEFT) || from_top_right) + RIGHT = 1; + if (from_top || (val_up & SEG_BOTTOM) || from_top_left) + TOP = 1; + if (from_bottom || (val_down & SEG_TOP) || from_bottom_right) + BOTTOM = 1; + + + if (TOP && BOTTOM && LEFT && RIGHT) + return SEG_LEFT_RIGHT_TOP_BOTTOM; + if (LEFT && RIGHT && TOP) + return SEG_LEFT_RIGHT_TOP; + if (LEFT && RIGHT && BOTTOM) + return SEG_LEFT_RIGHT_BOTTOM; + if (TOP && BOTTOM && LEFT) + return SEG_LEFT_TOP_BOTTOM; + if (TOP && BOTTOM && RIGHT) + return SEG_RIGHT_TOP_BOTTOM; + if (LEFT && RIGHT) + return SEG_LEFT_RIGHT; + if (TOP && BOTTOM) + return SEG_TOP_BOTTOM; + if (LEFT && TOP) + return SEG_LEFT_TOP; + if (LEFT && BOTTOM) + return SEG_LEFT_BOTTOM; + if (RIGHT && TOP) + return SEG_RIGHT_TOP; + if (RIGHT && BOTTOM) + return SEG_RIGHT_BOTTOM; + if (LEFT | RIGHT) + return SEG_LEFT_RIGHT; + return SEG_TOP_BOTTOM; + + + +} + +static void rails_draw(void *ptr, int which ATTRIBUTE_UNUSED, ATTRIBUTE_UNUSED SDL_Surface * canvas, + SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y ATTRIBUTE_UNUSED, unsigned int segment) +{ + magic_api *api = (magic_api *) ptr; + SDL_Surface *result, *temp; + Uint8 image; + unsigned int use_temp; + + use_temp = 0; + if (segment > rails_segments_x * rails_segments_y) + return; + //modification_rect.x and modification_rect.y are set by function + rails_extract_coords_from_segment(segment, &modification_rect.x, &modification_rect.y); + modification_rect.h = img_w; + modification_rect.w = img_h; + + image = rails_select_image(segment); //select the image to display + + if (rails_status_of_segments[segment] == image) + return; + + rails_status_of_segments[segment] = image; //and write it to global table + + + result = SDL_CreateRGBSurface(SDL_ANYFORMAT, img_w, img_h, rails_one->format->BitsPerPixel, + rails_one->format->Rmask, rails_one->format->Gmask, rails_one->format->Bmask, + rails_one->format->Amask); + + temp = SDL_CreateRGBSurface(SDL_ANYFORMAT, img_w, img_h, rails_one->format->BitsPerPixel, + rails_one->format->Rmask, rails_one->format->Gmask, rails_one->format->Bmask, + rails_one->format->Amask); + + SDL_BlitSurface(canvas_backup, &modification_rect, result, NULL); + + + switch (image) + { + case 0: + case SEG_TOP_BOTTOM: + SDL_BlitSurface(canvas_backup, &modification_rect, result, NULL); + SDL_BlitSurface(rails_one, NULL, result, NULL); + break; + + case SEG_LEFT_RIGHT: + SDL_BlitSurface(canvas_backup, &modification_rect, result, NULL); + rails_rotate(api, temp, rails_one, 1); + use_temp = 1; + break; + + case SEG_LEFT_RIGHT_TOP_BOTTOM: + SDL_BlitSurface(canvas_backup, &modification_rect, result, NULL); + SDL_BlitSurface(rails_four, NULL, result, NULL); + break; + + case SEG_LEFT_RIGHT_TOP: + SDL_BlitSurface(rails_three, NULL, result, NULL); + break; + + case SEG_LEFT_RIGHT_BOTTOM: + rails_flip(api, temp, rails_three); + use_temp = 1; + break; + + case SEG_LEFT_TOP_BOTTOM: + rails_rotate(api, temp, rails_three, 0); + use_temp = 1; + break; + + case SEG_RIGHT_TOP_BOTTOM: + rails_rotate(api, temp, rails_three, 1); + use_temp = 1; + break; + + case SEG_RIGHT_TOP: + SDL_BlitSurface(rails_corner, NULL, result, NULL); + break; + + case SEG_RIGHT_BOTTOM: + rails_flip(api, temp, rails_corner); + use_temp = 1; + break; + + case SEG_LEFT_TOP: + rails_rotate(api, temp, rails_corner, 0); + use_temp = 1; + break; + + case SEG_LEFT_BOTTOM: + rails_flip_flop(api, temp, rails_corner); + use_temp = 1; + break; + } + + if (use_temp) + SDL_BlitSurface(temp, NULL, result, NULL); + + SDL_FreeSurface(temp); + SDL_BlitSurface(result, NULL, canvas, &modification_rect); + SDL_FreeSurface(result); + api->playsound(rails_snd, (x * 255) / canvas->w, 255); +} + +static void rails_draw_wrapper(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y) +{ + rails_segment_modified = rails_get_segment(x, y); + + + if ((rails_segment_modified == rails_segment_modified_last)) + return; + if (rails_segment_modified > 0) + { + rails_draw((void *)ptr, which, canvas, last, x, y, rails_segment_modified); + } + if (rails_segment_modified_last > 0) + rails_draw((void *)ptr, which, canvas, last, x, y, rails_segment_modified_last); + + if (rails_segment_to_add > 0) + { + rails_draw((void *)ptr, which, canvas, last, x, y, rails_segment_to_add); + rails_draw((void *)ptr, which, canvas, last, x, y, rails_segment_modified_last); + rails_segment_to_add = 0; + } + if (rails_segment_modified > 0) + rails_segment_modified_last = rails_segment_modified; } void rails_drag(magic_api * api, int which, SDL_Surface * canvas, - SDL_Surface * snapshot, int ox, int oy, int x, int y, - SDL_Rect * update_rect) -{ + SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect) +{ int start_x, end_x, start_y, end_y, segment_start, segment_end, w, h; + // avoiding to write out of the canvas - if ((xw)&&(yh)&&(oxw)&&(oyh)&&((signed)x>0)&&((signed)y>0)&&((signed)ox>0)&&((signed)oy>0)) + if ((x < canvas->w) && (y < canvas->h) && (ox < canvas->w) && (oy < canvas->h) && ((signed)x > 0) && ((signed)y > 0) + && ((signed)ox > 0) && ((signed)oy > 0)) { - api->line((void *) api, which, canvas, snapshot, ox, oy, x, y, img_w/2, rails_draw_wrapper); - - start_x=min(ox,x); - end_x=max(ox,x); - start_y=min(oy,y); - end_y=max(oy,y); + api->line((void *)api, which, canvas, snapshot, ox, oy, x, y, img_w / 2, rails_draw_wrapper); - segment_start=rails_get_segment(start_x-img_w, start_y-img_h); - segment_end=rails_get_segment(end_x+img_w,end_y+img_h); + start_x = min(ox, x); + end_x = max(ox, x); + start_y = min(oy, y); + end_y = max(oy, y); - x=((segment_start%rails_segments_x)-1)*img_w; - y=(int)(segment_start/rails_segments_x)*img_h; - w=((segment_end%rails_segments_x)-1)*img_w-x+img_w; - h=(int)(segment_end/rails_segments_x)*img_h-y+img_h; + segment_start = rails_get_segment(start_x - img_w, start_y - img_h); + segment_end = rails_get_segment(end_x + img_w, end_y + img_h); - update_rect->x=x; - update_rect->y=y; - update_rect->w=w; - update_rect->h=h;} + x = ((segment_start % rails_segments_x) - 1) * img_w; + y = (int)(segment_start / rails_segments_x) * img_h; + w = ((segment_end % rails_segments_x) - 1) * img_w - x + img_w; + h = (int)(segment_end / rails_segments_x) * img_h - y + img_h; + + update_rect->x = x; + update_rect->y = y; + update_rect->w = w; + update_rect->h = h; + } }