Beginning work to improve rails.
This commit is contained in:
parent
c4db433190
commit
4bc51c905a
1 changed files with 104 additions and 73 deletions
|
|
@ -3,7 +3,27 @@
|
|||
#include "SDL_mixer.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
#define SEG_NONE 0
|
||||
|
||||
#define SEG_LEFT 1
|
||||
#define SEG_RIGHT 2
|
||||
#define SEG_TOP 4
|
||||
#define SEG_BOTTOM 8
|
||||
|
||||
#define SEG_LEFT_RIGHT (SEG_LEFT | SEG_RIGHT)
|
||||
#define SEG_TOP_BOTTOM (SEG_TOP | SEG_BOTTOM)
|
||||
#define SEG_RIGHT_TOP (SEG_RIGHT | SEG_TOP)
|
||||
#define SEG_RIGHT_BOTTOM (SEG_RIGHT | SEG_BOTTOM)
|
||||
#define SEG_LEFT_TOP (SEG_LEFT | SEG_TOP)
|
||||
#define SEG_LEFT_BOTTOM (SEG_LEFT | SEG_BOTTOM)
|
||||
#define SEG_LEFT_RIGHT_TOP (SEG_LEFT | SEG_RIGHT | SEG_TOP)
|
||||
#define SEG_LEFT_RIGHT_BOTTOM (SEG_LEFT | SEG_RIGHT | SEG_BOTTOM)
|
||||
#define SEG_LEFT_TOP_BOTTOM (SEG_LEFT | SEG_TOP | SEG_BOTTOM)
|
||||
#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;
|
||||
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
|
||||
|
|
@ -17,7 +37,7 @@ 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 * rails_one, * rails_three, * rails_four;
|
||||
SDL_Surface * rails_one, * rails_three, * rails_four, * rails_corner;
|
||||
|
||||
Uint32 rails_api_version(void)
|
||||
{
|
||||
|
|
@ -38,18 +58,23 @@ 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 *)*3);
|
||||
rails_images=(char **)malloc(sizeof(char *)*4);
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
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_three.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);
|
||||
|
|
@ -107,9 +132,10 @@ void rails_shutdown(magic_api * api)
|
|||
SDL_FreeSurface(rails_one);
|
||||
SDL_FreeSurface(rails_three);
|
||||
SDL_FreeSurface(rails_four);
|
||||
SDL_FreeSurface(rails_corner);
|
||||
SDL_FreeSurface(canvas_backup);
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
for (i = 0; i < 4; i++)
|
||||
free(rails_images[i]);
|
||||
free(rails_images);
|
||||
free(rails_status_of_segments);
|
||||
|
|
@ -124,8 +150,8 @@ void rails_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas)
|
|||
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,40);
|
||||
rails_segments_y=rails_math_ceil(canvas->h,40);
|
||||
rails_segments_x=rails_math_ceil(canvas->w,img_w);
|
||||
rails_segments_y=rails_math_ceil(canvas->h,img_h);
|
||||
rails_status_of_segments=(Uint8 *)calloc(rails_segments_x*rails_segments_y,sizeof(Uint8));
|
||||
}
|
||||
|
||||
|
|
@ -151,8 +177,8 @@ 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, 40);
|
||||
yy=rails_math_ceil(y, 40);
|
||||
xx=rails_math_ceil(x, img_w);
|
||||
yy=rails_math_ceil(y, img_h);
|
||||
|
||||
return (yy-1)*rails_segments_x+xx;
|
||||
|
||||
|
|
@ -160,8 +186,8 @@ inline unsigned int rails_get_segment(int x, int y)
|
|||
|
||||
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)*40; //useful to set update_rect as small as possible
|
||||
*y=(int)(segment/rails_segments_x)*40;
|
||||
*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)
|
||||
|
|
@ -206,65 +232,46 @@ void rails_click(magic_api * api, int which, int mode,
|
|||
static Uint8 rails_select_image(Uint8 segment)
|
||||
{
|
||||
int take_up, take_down, take_left, take_right;
|
||||
int val_up, val_down, val_left, val_right;
|
||||
|
||||
take_up=segment-rails_segments_x;
|
||||
if (take_up<=0) take_up=-1; //= upper sector doesn't exist
|
||||
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>rails_segments_x*rails_segments_y) take_down=-1; //= lower sector doesn't exist
|
||||
else take_down=segment+rails_segments_x;
|
||||
if (take_down>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) take_left=-1;
|
||||
else take_left=segment-1;
|
||||
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) take_right=-1;
|
||||
else take_right=segment+1;
|
||||
if ((segment%rails_segments_x)==0) val_right=SEG_NONE;
|
||||
else val_right = rails_status_of_segments[segment+1];
|
||||
|
||||
if ((take_up!=-1) && (take_down!=-1) && (take_left!=-1) && (take_right!=-1)) //all the neighbours exists
|
||||
{
|
||||
if ( (rails_status_of_segments[take_left]==2) && (rails_status_of_segments[take_right]==2) &&
|
||||
(rails_status_of_segments[take_up]==1) && (rails_status_of_segments[take_down]==1))
|
||||
return 4;
|
||||
}
|
||||
if ( (val_left & SEG_RIGHT) && (val_right & SEG_LEFT) &&
|
||||
(val_up & SEG_BOTTOM) && (val_down & SEG_TOP))
|
||||
return SEG_LEFT_RIGHT_TOP_BOTTOM;
|
||||
|
||||
|
||||
if ((take_left!=-1) && (take_right!=-1)) //at least 2 neightbours exists
|
||||
{
|
||||
if (take_up!=-1)
|
||||
if ( (rails_status_of_segments[take_left]==2) && (rails_status_of_segments[take_right]==2) &&
|
||||
(rails_status_of_segments[take_up]==1))
|
||||
return 31;
|
||||
if ( (val_left & SEG_RIGHT) && (val_right & SEG_LEFT) &&
|
||||
(val_up & SEG_BOTTOM))
|
||||
return SEG_LEFT_RIGHT_TOP;
|
||||
|
||||
if (take_down!=-1)
|
||||
if ( (rails_status_of_segments[take_left]==2) && (rails_status_of_segments[take_right]==2) &&
|
||||
(rails_status_of_segments[take_down]==1))
|
||||
return 32;
|
||||
if ( (val_left & SEG_RIGHT) && (val_right & SEG_LEFT) &&
|
||||
(val_down & SEG_TOP))
|
||||
return SEG_LEFT_RIGHT_BOTTOM;
|
||||
|
||||
if ( (rails_status_of_segments[take_left]==2) && (rails_status_of_segments[take_right]==2))
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((take_up!=-1) && (take_down!=-1))
|
||||
{
|
||||
if (take_left!=-1)
|
||||
if ( (rails_status_of_segments[take_left]==2) && (rails_status_of_segments[take_up]==1) &&
|
||||
(rails_status_of_segments[take_down]==1))
|
||||
return 33;
|
||||
|
||||
if (take_right!=-1)
|
||||
if ( (rails_status_of_segments[take_right]==2) && (rails_status_of_segments[take_up]==1) &&
|
||||
(rails_status_of_segments[take_down]==1))
|
||||
return 34;
|
||||
}
|
||||
if ( (val_right & SEG_LEFT) &&
|
||||
(val_down & SEG_TOP) && (val_up & SEG_BOTTOM) )
|
||||
return SEG_LEFT_TOP_BOTTOM;
|
||||
|
||||
if ( (val_right & SEG_LEFT) &&
|
||||
(val_down & SEG_TOP) && (val_up & SEG_BOTTOM) )
|
||||
return SEG_RIGHT_TOP_BOTTOM;
|
||||
|
||||
if ( (val_right & SEG_LEFT) && (val_left & SEG_RIGHT))
|
||||
return SEG_LEFT_RIGHT;
|
||||
|
||||
if (rails_status_of_segments[segment]==0) return 1;
|
||||
|
||||
if (rails_status_of_segments[segment]==1) return 2;
|
||||
|
||||
if (rails_status_of_segments[segment]==2) return 1;
|
||||
|
||||
return 0;
|
||||
return SEG_TOP_BOTTOM;
|
||||
}
|
||||
|
||||
static void rails_draw(void * ptr, int which, SDL_Surface * canvas, SDL_Surface * last,
|
||||
|
|
@ -277,66 +284,90 @@ static void rails_draw(void * ptr, int which, SDL_Surface * canvas, SDL_Surface
|
|||
|
||||
use_temp=0;
|
||||
rails_segment_modified=rails_get_segment(x,y);
|
||||
|
||||
result=SDL_CreateRGBSurface(SDL_ANYFORMAT, 40, 40, 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, 40, 40, rails_one->format->BitsPerPixel,
|
||||
rails_one->format->Rmask, rails_one->format->Gmask, rails_one->format->Bmask, rails_one->format->Amask);
|
||||
|
||||
//modification_rect.x and modification_rect.y are set by function
|
||||
rails_extract_coords_from_segment(rails_segment_modified, &modification_rect.x, &modification_rect.y);
|
||||
modification_rect.h=40;
|
||||
modification_rect.w=40;
|
||||
modification_rect.h=img_w;
|
||||
modification_rect.w=img_h;
|
||||
|
||||
image=rails_select_image(rails_segment_modified); //select the image to display
|
||||
|
||||
if (rails_status_of_segments[rails_segment_modified] == image)
|
||||
return;
|
||||
|
||||
rails_status_of_segments[rails_segment_modified]=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 2:
|
||||
case SEG_TOP_BOTTOM:
|
||||
SDL_BlitSurface(canvas_backup, &modification_rect, result, NULL);
|
||||
SDL_BlitSurface(rails_one, NULL, result, NULL);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
case SEG_LEFT_RIGHT:
|
||||
SDL_BlitSurface(canvas_backup, &modification_rect, result, NULL);
|
||||
rails_rotate(api, temp, rails_one, 1);
|
||||
use_temp=1;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
case SEG_LEFT_RIGHT_TOP_BOTTOM:
|
||||
SDL_BlitSurface(canvas_backup, &modification_rect, result, NULL);
|
||||
SDL_BlitSurface(rails_four, NULL, result, NULL);
|
||||
break;
|
||||
|
||||
case 31:
|
||||
case SEG_LEFT_RIGHT_TOP:
|
||||
SDL_BlitSurface(rails_three, NULL, result, NULL);
|
||||
break;
|
||||
|
||||
case 32:
|
||||
case SEG_LEFT_RIGHT_BOTTOM:
|
||||
rails_flip(api, temp, rails_three);
|
||||
use_temp=1;
|
||||
break;
|
||||
|
||||
case 33:
|
||||
case SEG_LEFT_TOP_BOTTOM:
|
||||
rails_rotate(api, temp, rails_three, 0);
|
||||
use_temp=1;
|
||||
break;
|
||||
|
||||
case 34:
|
||||
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_rotate(api, temp, rails_corner, 0);
|
||||
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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue