From 73a294297bee210901dac7c4dde1503be24bc314 Mon Sep 17 00:00:00 2001 From: Thomas Perl Date: Tue, 4 Aug 2009 19:53:11 +0200 Subject: [PATCH] Split input handling + stepping; type changes in GameState This is in preparation for better network compatibility. --- game.c | 110 ++++++++++++++++++++++++++++++++--------------------------------- game.h | 30 +++++++++--------- 2 files changed, 69 insertions(+), 71 deletions(-) diff --git a/game.c b/game.c index 8be0157..b05b0ca 100644 --- a/game.c +++ b/game.c @@ -46,7 +46,6 @@ GameState *gamestate_new() { { NULL, -1, GAME_X_MIN-RACKET_X_MID*2, GAME_Y_MID, 0.0, POWER_UP_FACTOR, POWER_DOWN_FACTOR, true, 0, DESIRE_NORMAL, PLAYER_TYPE_AI, 0, {0}, PLAYER_ACCEL_DEFAULT }, { NULL, -1, GAME_X_MAX+RACKET_X_MID*2, GAME_Y_MID, 0.0, POWER_UP_FACTOR, POWER_DOWN_FACTOR, true, 0, DESIRE_NORMAL, PLAYER_TYPE_AI, 0, {0}, PLAYER_ACCEL_DEFAULT }, }, - 0, 1, REFEREE_NORMAL, 0, @@ -72,7 +71,7 @@ GameState *gamestate_new() { int gamestate_save(GameState* s, const char* filename) { - Location *location; + const Location *location; InputDevice* input_devices[MAXPLAYERS]; int i, result = 0; FILE* fp = NULL; @@ -211,8 +210,8 @@ void gameloop(GameState *s) { ot = nt; while( accumulator >= dt) { - quit = step(s); - s->time += dt; + step(s); + quit = handle_input(s); accumulator -= dt; } @@ -238,11 +237,26 @@ void gameloop(GameState *s) { stop_sample(SOUND_RAIN); } -bool step( GameState* s) { - Uint8 *keys; +void step(GameState* s) { bool ground_event = false; int p; + s->ball.z += s->ball.move_z; + if (!s->ball.inhibit_gravity) { + s->ball.move_z += GRAVITY; + } + + s->ball.x += s->ball.move_x; + s->ball.y += s->ball.move_y; + + for (p=1; p<=MAXPLAYERS; p++) { + if (PLAYER(s, p).use_power) { + PLAYER(s, p).power = fmaxf(0.0, fminf( + PLAYER(s, p).power*PLAYER(s, p).power_down_factor, + PLAYER_POWER_MAX)); + } + } + if (s->ball.z < 0) { /* ground event */ ground_event = true; @@ -312,11 +326,11 @@ bool step( GameState* s) { if (s->score_event != SCORE_UNDECIDED) { /* we have some scoring to do */ - if (s->score_time == 0) { + if (s->score_time < SCORING_DELAY/GAME_TICKS) { /* schedule scoring in the future */ - s->score_time = s->time + SCORING_DELAY; + s->score_time++; s->referee = REFEREE_OUT; - } else if (s->time >= s->score_time) { + } else if (s->score_time >= SCORING_DELAY/GAME_TICKS) { /* time has ran out - score now */ switch (score_game(s)) { case WINNER_PLAYER1: @@ -376,48 +390,41 @@ bool step( GameState* s) { } } } +} + +bool handle_input(GameState* s) { + static GameState tmp; + Uint8* keys = NULL; + int p; SDL_PumpEvents(); keys = SDL_GetKeyState(NULL); - if(s->winner == WINNER_NONE) { + if (keys['1']) { + memcpy(&tmp, s, sizeof(GameState)); + } else if (keys['2']) { + memcpy(s, &tmp, sizeof(GameState)); + } + + if (s->winner == WINNER_NONE) { for (p=1; p<=MAXPLAYERS; p++) { if( PLAYER(s, p).type == PLAYER_TYPE_HUMAN) { input_human(s, p); } else { input_ai(s, p); } + + /* Make sure player coordinates are valid */ + if (PLAYER(s, p).y < PLAYER_Y_MIN) { + PLAYER(s, p).y = PLAYER_Y_MIN; + } else if (PLAYER(s, p).y > PLAYER_Y_MAX) { + PLAYER(s, p).y = PLAYER_Y_MAX; + } } } - /* Maemo: The "F6" button is the "Fullscreen" button */ - /*if( keys['f'] || keys[SDLK_F6]) SDL_WM_ToggleFullScreen( screen);*/ - if( keys['y']) SDL_SaveBMP( screen, "screenshot.bmp"); - /* Maemo: The "F4" button is the "Open menu" button */ - if(keys[SDLK_ESCAPE] || keys['q'] - || keys['p'] || keys[SDLK_F4]) { - return true; - } - - limit_value( &PLAYER(s, 1).y, PLAYER_Y_MIN, PLAYER_Y_MAX); - limit_value( &PLAYER(s, 2).y, PLAYER_Y_MIN, PLAYER_Y_MAX); - - s->ball.z += s->ball.move_z; - if (!s->ball.inhibit_gravity) { - s->ball.move_z += GRAVITY; - } - - s->ball.x += s->ball.move_x; - s->ball.y += s->ball.move_y; - - for (p=1; p<=MAXPLAYERS; p++) { - if (PLAYER(s, p).use_power) { - PLAYER(s, p).power = fmaxf(0.0, fminf(PLAYER(s, p).power*PLAYER(s, p).power_down_factor, PLAYER_POWER_MAX)); - } - } - - return false; + return (keys[SDLK_ESCAPE] || keys['q']); } void render(const GameState* s, RenderState* r) { @@ -427,6 +434,7 @@ void render(const GameState* s, RenderState* r) { float rotate; int t=1000; soundevent_t sounds; + Uint32 time = SDL_GetTicks(); /* The bits in sound_events flip when the sound should play */ if ((sounds = (r->sound_events ^ s->sound_events)) != 0) { @@ -506,7 +514,7 @@ void render(const GameState* s, RenderState* r) { t = 400; break; } - t = (s->time/t)%4; + t = (time/t)%4; switch (t) { case 0: t=0; @@ -523,7 +531,7 @@ void render(const GameState* s, RenderState* r) { } show_sprite( GR_REFEREE, s->referee*3+t, 12, 250, 10, 255); if (voice_finished_flag == 0) { - show_sprite(GR_TALK, (s->time/150)%2, 2, 280, 45, 255); + show_sprite(GR_TALK, (time/150)%2, 2, 280, 45, 255); } } r->referee = s->referee; @@ -542,9 +550,9 @@ void render(const GameState* s, RenderState* r) { rectangle(WIDTH-PLAYER_POWER_MAX-10, HEIGHT-30, (int)(PLAYER(s, 2).power), 10, 200, 200, 200); if( s->ball.move_x > 0) { - b = (s->time/100)%BALL_STATES; + b = (time/100)%BALL_STATES; } else if( s->ball.move_x < 0) { - b = BALL_STATES-1-(s->time/100)%BALL_STATES; + b = BALL_STATES-1-(time/100)%BALL_STATES; } else { b = 0; } @@ -553,7 +561,7 @@ void render(const GameState* s, RenderState* r) { zoom = fmaxf(0.5, fminf(1.0, (float)(30.-(s->ball.z))/10.)); show_image_rotozoom(GR_SHADOW, s->ball.x, s->ball.y+3, rotate, zoom); - rotate = (-s->ball.move_x * (float)((float)s->time/10.)); + rotate = (-s->ball.move_x * (float)((float)time/10.)); zoom = 1.0 + fmaxf(0.0, (s->ball.z-10.)/100.); show_image_rotozoom(GR_BALL, s->ball.x, s->ball.y - s->ball.z, rotate, zoom); @@ -600,13 +608,13 @@ void render(const GameState* s, RenderState* r) { switch (s->location->fog) { default: case 4: - fill_image_offset(GR_FOG2, 0, 0, WIDTH, HEIGHT, -s->time/150, 0); + fill_image_offset(GR_FOG2, 0, 0, WIDTH, HEIGHT, -time/150, 0); case 3: - fill_image_offset(GR_FOG, 0, 0, WIDTH, HEIGHT, -s->time/100, 20); + fill_image_offset(GR_FOG, 0, 0, WIDTH, HEIGHT, -time/100, 20); case 2: - fill_image_offset(GR_FOG2, 0, 0, WIDTH, HEIGHT, -s->time/180, 80); + fill_image_offset(GR_FOG2, 0, 0, WIDTH, HEIGHT, -time/180, 80); case 1: - fill_image_offset(GR_FOG, 0, 0, WIDTH, HEIGHT, s->time/200, 0); + fill_image_offset(GR_FOG, 0, 0, WIDTH, HEIGHT, time/200, 0); case 0: break; } @@ -617,14 +625,6 @@ void render(const GameState* s, RenderState* r) { updatescr(); } -void limit_value( float* value, float min, float max) { - if( *value < min) { - *value = min; - } else if( *value > max) { - *value = max; - } -} - float get_move_y( GameState* s, unsigned char player) { float pct, dest, x_len, y_len; float py, by, pa, move_x; @@ -906,7 +906,7 @@ const char* format_status(const GameState* s) { } } -int game_get_winner( GameState* s) { +winner_t game_get_winner(const GameState* s) { unsigned int i; int sets[2] = {0}; diff --git a/game.h b/game.h index 8ab43b9..4983431 100644 --- a/game.h +++ b/game.h @@ -55,12 +55,14 @@ enum { REFEREE_COUNT }; +typedef unsigned char winner_t; enum { WINNER_NONE, WINNER_PLAYER1, WINNER_PLAYER2 }; +typedef unsigned char soundevent_t; enum { SOUND_EVENT_NONE = 0<<0, SOUND_EVENT_GROUND = 1<<0, @@ -68,12 +70,8 @@ enum { SOUND_EVENT_APPLAUSE = 1<<2, SOUND_EVENT_RACKET = 1<<3 }; - #define SOUND_EVENT_COUNT 4 -typedef unsigned char soundevent_t; - - typedef struct { const char* name; const char* area; @@ -134,8 +132,9 @@ enum { }; /* wait 2 seconds before we score the game */ -#define SCORING_DELAY 2000 +#define SCORING_DELAY 1000 +typedef unsigned char scoreevent_t; enum { SCORE_UNDECIDED, SCORE_EVENT_NET, @@ -146,7 +145,7 @@ enum { SCORE_EVENT_MAX }; -typedef unsigned int eventcounter_t; +typedef unsigned char eventcounter_t; enum { EVENTCOUNTER_RENDERSTATE_START = 0, EVENTCOUNTER_GAMESTATE_START = 1 @@ -168,17 +167,16 @@ enum { typedef struct { const Location* location; - int current_location; /* index of loc. in global location table */ + char current_location; /* index of loc. in global location table */ Ball ball; Player players[MAXPLAYERS]; - Uint32 time; - unsigned int serving_player; + unsigned char serving_player; referee_t referee; - unsigned int current_set; - int winner; + unsigned char current_set; + winner_t winner; soundevent_t sound_events; - int score_event; - unsigned int score_time; + scoreevent_t score_event; + unsigned char score_time; eventcounter_t ec_game; eventcounter_t ec_sets; statusmessage_t status_message; @@ -283,16 +281,16 @@ GameState* gamestate_load(const char* filename); /* Game module functions */ void gameloop(GameState*); +void step(GameState*); +bool handle_input(GameState*); void render(const GameState*, RenderState*); -bool step( GameState*); -void limit_value( float*, float, float); float get_move_y( GameState*, unsigned char); void input_human(GameState*, int); void input_ai(GameState*, int); void game_setup_serve( GameState*); int score_game(GameState*); -int game_get_winner( GameState*); +winner_t game_get_winner(const GameState*); /* Helper functions for the renderer */ const char* format_sets(const GameState*); -- 2.11.4.GIT