|
|
@ -1,7 +1,8 @@ |
|
|
|
#include <stdio.h> |
|
|
|
#include <SDL/SDL.h> |
|
|
|
#include <SDL/SDL_image.h> |
|
|
|
#include <unistd.h> /* exit */ |
|
|
|
#include <stdio.h> |
|
|
|
#include <math.h> /* sin, cos */ |
|
|
|
|
|
|
|
#include "api.h" |
|
|
|
#include "gui.h" |
|
|
@ -30,70 +31,64 @@ struct gui_resource_t display_start() { |
|
|
|
return res; |
|
|
|
} |
|
|
|
|
|
|
|
SDL_Rect coord_rotate(SDL_Rect coord, enum hole_t currentplayer) { |
|
|
|
SDL_Rect res; |
|
|
|
#define CENTER_X ((short)400) |
|
|
|
#define CENTER_Y ((short)300) |
|
|
|
coord.x -= CENTER_X; |
|
|
|
coord.y -= CENTER_Y; |
|
|
|
|
|
|
|
switch(currentplayer) { |
|
|
|
case 1: |
|
|
|
res.x = coord.x/2 + (coord.y*13)/15; // sin60°~13/15, cos60°=1/2 |
|
|
|
res.y = -(coord.x*13)/15 + coord.y/2; |
|
|
|
break; |
|
|
|
case 2: |
|
|
|
res.x = -coord.x/2 + (coord.y*13)/15; |
|
|
|
res.y = -(coord.x*13)/15 - coord.y/2; |
|
|
|
break; |
|
|
|
case 3: |
|
|
|
res.x = -coord.x; |
|
|
|
res.y = -coord.y; |
|
|
|
break; |
|
|
|
case 4: |
|
|
|
res.x = -coord.x/2 - (coord.y*13)/15; |
|
|
|
res.y = (coord.x*13)/15 - coord.y/2; |
|
|
|
break; |
|
|
|
case 5: |
|
|
|
res.x = coord.x/2 - (coord.y*13)/15; |
|
|
|
res.y = (coord.x*13)/15 + coord.y/2; |
|
|
|
break; |
|
|
|
default: |
|
|
|
res.x = coord.x; |
|
|
|
res.y = coord.y; |
|
|
|
break; |
|
|
|
SDL_Event display_until_event(struct gui_resource_t res) { |
|
|
|
#define FIXEDFRAMETIME 125 /* 125ms → 8fps */ |
|
|
|
SDL_Event event; |
|
|
|
uint32_t time1, time2; /* mesure du temps de rendu de frame */ |
|
|
|
for(;;) { |
|
|
|
time1 = SDL_GetTicks(); |
|
|
|
|
|
|
|
if(SDL_PollEvent(&event)) |
|
|
|
break; |
|
|
|
SDL_Flip(res.screen); |
|
|
|
|
|
|
|
/* attente du temps restant dans la frame */ |
|
|
|
time2 = SDL_GetTicks(); |
|
|
|
if(time2-time1 > FIXEDFRAMETIME) |
|
|
|
fprintf(stderr,"(rant) fixed image: the machine is slow, frame took %dms\n", time2-time1); |
|
|
|
else |
|
|
|
SDL_Delay(FIXEDFRAMETIME - (time2-time1)); |
|
|
|
} |
|
|
|
|
|
|
|
res.x += CENTER_X; |
|
|
|
res.y += CENTER_Y; |
|
|
|
return event; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
SDL_Rect coord_rotate(SDL_Rect coord, double sin, double cos) { |
|
|
|
SDL_Rect res; |
|
|
|
res.x = (short)round( cos * ((double)coord.x) + sin * ((double)coord.y) ); |
|
|
|
res.y = (short)round( ((double)cos) * ((double)coord.y) - sin * ((double)coord.x) ); |
|
|
|
return res; |
|
|
|
} |
|
|
|
|
|
|
|
void display_render_board(struct gui_resource_t res, struct game_state_t gamestate /*, enum hole_t currentplayer*/) { |
|
|
|
int i; |
|
|
|
void draw_all(struct gui_resource_t res, struct game_state_t gamestate, double angle) { |
|
|
|
/* pour ne les calculer qu'une fois */ |
|
|
|
double sinA = sin(angle), cosA = cos(angle); |
|
|
|
|
|
|
|
/* positions pour les images */ |
|
|
|
SDL_Rect zero_pos = {0, 0}, pawn_pos, pawn_pos_postrot; |
|
|
|
SDL_Rect zero_pos = {0, 0}, pawn_pos, pawn_pos_rot; |
|
|
|
|
|
|
|
/* dessin du fond */ |
|
|
|
SDL_BlitSurface(res.bgnd_img, NULL, res.screen, &zero_pos); |
|
|
|
SDL_BlitSurface(res.title_img, NULL, res.screen, &zero_pos); |
|
|
|
SDL_BlitSurface(res.board_img, NULL, res.screen, &zero_pos); |
|
|
|
/* #include <SDL/SDL_rotozoom.h> |
|
|
|
/* #include <SDL/SDL_rotozoom.h> TODO rotation image plateau |
|
|
|
SDL_Surface *rotated_board_img = rotozoomSurface(res.board_img, (360.0/6.0)*currentplayer, 0.0, 1); */ |
|
|
|
|
|
|
|
/* dessin du plateau */ |
|
|
|
SDL_BlitSurface(res.board_img, NULL, res.screen, &zero_pos); |
|
|
|
|
|
|
|
/* dessin des pions */ |
|
|
|
int index_lines[] = {1, 3, 6, 10, 23, 35, 46, 56, 65, 75, 86, 98, 111, 115, 118, 120}; |
|
|
|
int index_line_offsets[] = {0, 0, 2, 2, 8, 11, 11, 9, 9, 8, 10, 10, 12, 7, 3, 1, 1}; |
|
|
|
int line = 0; |
|
|
|
#define PAWNSIZE ((short)28) |
|
|
|
#define FUZZSPACING ((short)18) |
|
|
|
#define HORIZSPACING ((short)9) |
|
|
|
#define VERTSPACING ((short)4) |
|
|
|
pawn_pos.x = 400 - PAWNSIZE/2 - (PAWNSIZE+HORIZSPACING); |
|
|
|
pawn_pos.y = (PAWNSIZE/2+16); |
|
|
|
#define CENTER_X 400 |
|
|
|
#define CENTER_Y 300 |
|
|
|
#define PAWNSIZE 28 |
|
|
|
#define FUZZSPACING 19 |
|
|
|
#define HORIZSPACING 10 |
|
|
|
#define VERTSPACING 5 |
|
|
|
pawn_pos.x = CENTER_X - PAWNSIZE/2 - (PAWNSIZE+HORIZSPACING); |
|
|
|
pawn_pos.y = (PAWNSIZE/2+8); |
|
|
|
int i; |
|
|
|
for(i = 0; i < 121; i++) { |
|
|
|
if(i == index_lines[line]) { |
|
|
|
line++; |
|
|
@ -103,15 +98,47 @@ void display_render_board(struct gui_resource_t res, struct game_state_t gamesta |
|
|
|
pawn_pos.x += PAWNSIZE+HORIZSPACING; |
|
|
|
} |
|
|
|
/* matrix rotation on pawn_pos using param currentplayer (1/6ths of a circle) */ |
|
|
|
pawn_pos.x += PAWNSIZE/2; |
|
|
|
pawn_pos.y += PAWNSIZE/2; |
|
|
|
pawn_pos_postrot = coord_rotate(pawn_pos, 0); |
|
|
|
pawn_pos.x -= PAWNSIZE/2; |
|
|
|
pawn_pos.y -= PAWNSIZE/2; |
|
|
|
pawn_pos_postrot.x -= PAWNSIZE/2; |
|
|
|
pawn_pos_postrot.y -= PAWNSIZE/2; |
|
|
|
SDL_BlitSurface(res.pawn_img[gamestate.board[i]], NULL, res.screen, &pawn_pos_postrot); |
|
|
|
pawn_pos_rot.x = pawn_pos.x + PAWNSIZE/2 - CENTER_X; |
|
|
|
pawn_pos_rot.y = pawn_pos.y + PAWNSIZE/2 - CENTER_Y; |
|
|
|
pawn_pos_rot = coord_rotate(pawn_pos_rot, sinA, cosA); |
|
|
|
pawn_pos_rot.x -= PAWNSIZE/2 - CENTER_X; |
|
|
|
pawn_pos_rot.y -= PAWNSIZE/2 - CENTER_Y; |
|
|
|
SDL_BlitSurface(res.pawn_img[gamestate.board[i]], NULL, res.screen, &pawn_pos_rot); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void display_render_board(struct gui_resource_t res, struct game_state_t gamestate, enum hole_t currentplayer) { |
|
|
|
draw_all(res, gamestate, ((((double)currentplayer)-1)*M_PI)/3); |
|
|
|
} |
|
|
|
|
|
|
|
int display_anirotate_board(struct gui_resource_t res, struct game_state_t gamestate, enum hole_t currentplayer, enum hole_t nextplayer) { |
|
|
|
#define ANIFRAMETIME 40 /* 40ms → 25fps */ |
|
|
|
#define ANIMTIME 2000 /* 2000ms → 2s */ |
|
|
|
|
|
|
|
uint32_t time1, time2; /* mesure du temps de rendu de frame */ |
|
|
|
SDL_Event event; |
|
|
|
int frame; |
|
|
|
for(frame = 0; frame <= ANIMTIME/ANIFRAMETIME; frame++) { |
|
|
|
time1 = SDL_GetTicks(); |
|
|
|
|
|
|
|
while(SDL_PollEvent(&event)) |
|
|
|
if(event.type == SDL_QUIT) |
|
|
|
return 1; |
|
|
|
/* progrès non-linéaire (cosinus) */ |
|
|
|
double anim_progress = ( ((double)nextplayer) - ((double)currentplayer) ) * ( cos(M_PI*((double)frame)/((double)(ANIMTIME/ANIFRAMETIME))+M_PI) + 1 ) / 2; |
|
|
|
double angle = ( anim_progress + (((double)currentplayer)-1) ) * M_PI / 3; |
|
|
|
|
|
|
|
draw_all(res, gamestate, angle); |
|
|
|
SDL_Flip(res.screen); |
|
|
|
|
|
|
|
/* attente du temps restant dans la frame : stabilisation de la vitesse d'exécution */ |
|
|
|
time2 = SDL_GetTicks(); |
|
|
|
if(time2-time1 > ANIFRAMETIME) |
|
|
|
fprintf(stderr,"(rant) animation: the machine is slow, frame took %dms\n", time2-time1); |
|
|
|
else |
|
|
|
SDL_Delay(ANIFRAMETIME - (time2-time1)); |
|
|
|
} |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
void display_close(struct gui_resource_t res) { |
|
|
|