X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=blobdiff_plain;f=src%2Fgame.c;h=26cc84cc2a8a61d0e95a9cd347f74368a549ebff;hp=a48ad78bad3944432795406b1fae03677445dbe4;hb=0918c3eb2f6219a8cc72aa85bd9c4889788dd474;hpb=3dc317d10b44cc6b75db10ac194966ad8114d390 diff --git a/src/game.c b/src/game.c index a48ad78b..26cc84cc 100644 --- a/src/game.c +++ b/src/game.c @@ -23,51 +23,81 @@ #include "joystick.h" #include "network.h" -#ifdef DEBUG -static unsigned int getStateCheckSum(int counter) -{ - int x, y; - unsigned int mult = 1; - unsigned int checksum = 0; - static short lastFeld[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; - static boolean first_game = TRUE; - - for (y=0; yelement_nr); - printf("[Local player is %d and currently %s.]\n", - local_player->element_nr, - local_player->active ? "active" : "not active"); + if (options.verbose) + { + printf("Player %d activated.\n", player->element_nr); + printf("[Local player is %d and currently %s.]\n", + local_player->element_nr, + local_player->active ? "active" : "not active"); + } } Feld[x][y] = EL_LEERRAUM; @@ -340,20 +375,38 @@ void InitGame() } } - /* when in single player mode, eliminate all but the first active player */ - if (!options.network && !setup.team_mode) + if (tape.playing) + { + /* when playing a tape, eliminate all players who do not participate */ + + for (i=0; ijx, jy = player->jy; + + player->active = FALSE; + StorePlayer[jx][jy] = 0; + Feld[jx][jy] = EL_LEERRAUM; + } + } + } + else if (!options.network && !setup.team_mode) /* && !tape.playing */ { + /* when in single player mode, eliminate all but the first active player */ + for (i=0; ijx, jy = player->jy; - - if (player->active) + if (stored_player[j].active) { + struct PlayerInfo *player = &stored_player[j]; + int jx = player->jx, jy = player->jy; + player->active = FALSE; StorePlayer[jx][jy] = 0; Feld[jx][jy] = EL_LEERRAUM; @@ -363,19 +416,29 @@ void InitGame() } } - for (i=0; ipresent, - player->connected, - player->active); - if (local_player == player) - printf("Player %d is local player.\n", i+1); + for (i=0; ipresent, + player->connected, + player->active); + if (local_player == player) + printf("Player %d is local player.\n", i+1); + } + } game_emulation = (emulate_bd ? EMU_BOULDERDASH : emulate_sb ? EMU_SOKOBAN : EMU_NONE); @@ -434,11 +497,12 @@ void InitGame() XAutoRepeatOff(display); - - for (i=0; i<4; i++) - printf("Spieler %d %saktiv.\n", - i+1, (stored_player[i].active ? "" : "nicht ")); - + if (options.verbose) + { + for (i=0; i<4; i++) + printf("Spieler %d %saktiv.\n", + i+1, (stored_player[i].active ? "" : "nicht ")); + } } void InitMovDir(int x, int y) @@ -623,15 +687,15 @@ boolean NewHiScore() LoadScore(level_nr); - if (!strcmp(setup.player_name, EMPTY_ALIAS) || - local_player->score < highscore[MAX_SCORE_ENTRIES-1].Score) + if (strcmp(setup.player_name, EMPTY_PLAYER_NAME) == 0 || + local_player->score < highscore[MAX_SCORE_ENTRIES - 1].Score) return -1; for (k=0; kscore > highscore[k].Score) { - /* Spieler kommt in Highscore-Liste */ + /* player has made it to the hall of fame */ if (k < MAX_SCORE_ENTRIES - 1) { @@ -641,7 +705,7 @@ boolean NewHiScore() for (l=k; l=TILEX) /* Zielfeld erreicht */ + if (ABS(MovPos[x][y])>=TILEX) /* object reached its destination */ { Feld[x][y] = EL_LEERRAUM; Feld[newx][newy] = element; @@ -2148,7 +2213,7 @@ void ContinueMoving(int x, int y) Stop[newx][newy] = TRUE; JustHit[x][newy] = 3; - if (DONT_TOUCH(element)) /* Käfer oder Flieger */ + if (DONT_TOUCH(element)) /* object may be nasty to player or others */ { TestIfBadThingHitsHero(newx, newy); TestIfBadThingHitsFriend(newx, newy); @@ -2161,7 +2226,7 @@ void ContinueMoving(int x, int y) (newy == lev_fieldy-1 || !IS_FREE(x, newy+1))) Impact(x, newy); } - else /* noch in Bewegung */ + else /* still moving on */ DrawLevelField(x, y); } @@ -2302,10 +2367,10 @@ void AmoebeUmwandeln2(int ax, int ay, int new_element) void AmoebeWaechst(int x, int y) { - static long sound_delay = 0; - static int sound_delay_value = 0; + static unsigned long sound_delay = 0; + static unsigned long sound_delay_value = 0; - if (!MovDelay[x][y]) /* neue Phase / noch nicht gewartet */ + if (!MovDelay[x][y]) /* start new growing cycle */ { MovDelay[x][y] = 7; @@ -2316,7 +2381,7 @@ void AmoebeWaechst(int x, int y) } } - if (MovDelay[x][y]) /* neue Phase / in Wartezustand */ + if (MovDelay[x][y]) /* wait some time before growing bigger */ { MovDelay[x][y]--; if (MovDelay[x][y]/2 && IN_SCR_FIELD(SCREENX(x), SCREENY(y))) @@ -2351,17 +2416,17 @@ void AmoebeAbleger(int ax, int ay) return; } - if (!MovDelay[ax][ay]) /* neue Amoebe / noch nicht gewartet */ + if (!MovDelay[ax][ay]) /* start making new amoeba field */ MovDelay[ax][ay] = RND(FRAMES_PER_SECOND * 25/(1+level.tempo_amoebe)); - if (MovDelay[ax][ay]) /* neue Amoebe / in Wartezustand */ + if (MovDelay[ax][ay]) /* wait some time before making new amoeba */ { MovDelay[ax][ay]--; if (MovDelay[ax][ay]) return; } - if (element == EL_AMOEBE_NASS) /* tropfende Amöbe */ + if (element == EL_AMOEBE_NASS) /* object is an acid / amoeba drop */ { int start = RND(4); int x = ax+xy[start][0]; @@ -2380,7 +2445,7 @@ void AmoebeAbleger(int ax, int ay) if (newax == ax && neway == ay) return; } - else /* normale oder "gefüllte" Amöbe */ + else /* normal or "filled" amoeba */ { int start = RND(4); boolean waiting_for_player = FALSE; @@ -2413,7 +2478,7 @@ void AmoebeAbleger(int ax, int ay) DrawLevelField(ax, ay); AmoebaCnt[AmoebaNr[ax][ay]]--; - if (AmoebaCnt[AmoebaNr[ax][ay]]<=0) /* Amöbe vollständig tot */ + if (AmoebaCnt[AmoebaNr[ax][ay]]<=0) /* amoeba is completely dead */ { if (element == EL_AMOEBE_VOLL) AmoebeUmwandeln(ax, ay); @@ -2463,17 +2528,17 @@ void AmoebeAbleger(int ax, int ay) void Life(int ax, int ay) { int x1, y1, x2, y2; - static int life[4] = { 2, 3, 3, 3 }; /* "Life"-Parameter */ + static int life[4] = { 2, 3, 3, 3 }; /* parameters for "game of life" */ int life_time = 40; int element = Feld[ax][ay]; if (Stop[ax][ay]) return; - if (!MovDelay[ax][ay]) /* neue Phase / noch nicht gewartet */ + if (!MovDelay[ax][ay]) /* start new "game of life" cycle */ MovDelay[ax][ay] = life_time; - if (MovDelay[ax][ay]) /* neue Phase / in Wartezustand */ + if (MovDelay[ax][ay]) /* wait some time before next cycle */ { MovDelay[ax][ay]--; if (MovDelay[ax][ay]) @@ -2502,7 +2567,7 @@ void Life(int ax, int ay) nachbarn++; } - if (xx == ax && yy == ay) /* mittleres Feld mit Amoebe */ + if (xx == ax && yy == ay) /* field in the middle */ { if (nachbarnlife[1]) { @@ -2513,7 +2578,7 @@ void Life(int ax, int ay) } } else if (IS_FREE(xx, yy) || Feld[xx][yy] == EL_ERDREICH) - { /* Randfeld ohne Amoebe */ + { /* free border field */ if (nachbarn>=life[2] && nachbarn<=life[3]) { Feld[xx][yy] = element; @@ -2528,10 +2593,10 @@ void Life(int ax, int ay) void Ablenk(int x, int y) { - if (!MovDelay[x][y]) /* neue Phase / noch nicht gewartet */ + if (!MovDelay[x][y]) /* next animation frame */ MovDelay[x][y] = level.dauer_ablenk * FRAMES_PER_SECOND; - if (MovDelay[x][y]) /* neue Phase / in Wartezustand */ + if (MovDelay[x][y]) /* wait some time before next frame */ { MovDelay[x][y]--; if (MovDelay[x][y]) @@ -2552,10 +2617,10 @@ void Ablenk(int x, int y) void Birne(int x, int y) { - if (!MovDelay[x][y]) /* neue Phase / noch nicht gewartet */ + if (!MovDelay[x][y]) /* next animation frame */ MovDelay[x][y] = 800; - if (MovDelay[x][y]) /* neue Phase / in Wartezustand */ + if (MovDelay[x][y]) /* wait some time before next frame */ { MovDelay[x][y]--; if (MovDelay[x][y]) @@ -2589,10 +2654,10 @@ void Blubber(int x, int y) void NussKnacken(int x, int y) { - if (!MovDelay[x][y]) /* neue Phase / noch nicht gewartet */ + if (!MovDelay[x][y]) /* next animation frame */ MovDelay[x][y] = 7; - if (MovDelay[x][y]) /* neue Phase / in Wartezustand */ + if (MovDelay[x][y]) /* wait some time before next frame */ { MovDelay[x][y]--; if (MovDelay[x][y]/2 && IN_SCR_FIELD(SCREENX(x), SCREENY(y))) @@ -2634,10 +2699,10 @@ void AusgangstuerOeffnen(int x, int y) { int delay = 6; - if (!MovDelay[x][y]) /* neue Phase / noch nicht gewartet */ + if (!MovDelay[x][y]) /* next animation frame */ MovDelay[x][y] = 5*delay; - if (MovDelay[x][y]) /* neue Phase / in Wartezustand */ + if (MovDelay[x][y]) /* wait some time before next frame */ { int tuer; @@ -2668,10 +2733,10 @@ void EdelsteinFunkeln(int x, int y) DrawGraphicAnimation(x, y, GFX_EDELSTEIN_BD, 4, 4, ANIM_REVERSE); else { - if (!MovDelay[x][y]) /* neue Phase / noch nicht gewartet */ + if (!MovDelay[x][y]) /* next animation frame */ MovDelay[x][y] = 11 * !SimpleRND(500); - if (MovDelay[x][y]) /* neue Phase / in Wartezustand */ + if (MovDelay[x][y]) /* wait some time before next frame */ { MovDelay[x][y]--; @@ -2709,10 +2774,10 @@ void MauerWaechst(int x, int y) { int delay = 6; - if (!MovDelay[x][y]) /* neue Phase / noch nicht gewartet */ + if (!MovDelay[x][y]) /* next animation frame */ MovDelay[x][y] = 3*delay; - if (MovDelay[x][y]) /* neue Phase / in Wartezustand */ + if (MovDelay[x][y]) /* wait some time before next frame */ { int phase; @@ -2764,10 +2829,10 @@ void MauerAbleger(int ax, int ay) boolean oben_massiv = FALSE, unten_massiv = FALSE; boolean links_massiv = FALSE, rechts_massiv = FALSE; - if (!MovDelay[ax][ay]) /* neue Mauer / noch nicht gewartet */ + if (!MovDelay[ax][ay]) /* start building new wall */ MovDelay[ax][ay] = 6; - if (MovDelay[ax][ay]) /* neue Mauer / in Wartezustand */ + if (MovDelay[ax][ay]) /* wait some time before building new wall */ { MovDelay[ax][ay]--; if (MovDelay[ax][ay]) @@ -2992,8 +3057,8 @@ static void PlayerActions(struct PlayerInfo *player, byte player_action) void GameActions() { - static long action_delay = 0; - long action_delay_value; + static unsigned long action_delay = 0; + unsigned long action_delay_value; int sieb_x = 0, sieb_y = 0; int i, x, y, element; byte *recorded_player_action; @@ -3005,8 +3070,40 @@ void GameActions() action_delay_value = (tape.playing && tape.fast_forward ? FfwdFrameDelay : GameFrameDelay); + /* + if (tape.playing && tape.fast_forward) + { + char buf[100]; + + sprintf(buf, "FFWD: %ld ms", action_delay_value); + print_debug(buf); + } + */ + + /* main game synchronization point */ + + + + +#if 1 WaitUntilDelayReached(&action_delay, action_delay_value); +#else + + while (!DelayReached(&action_delay, action_delay_value)) + { + char buf[100]; + + sprintf(buf, "%ld %ld %ld", + Counter(), action_delay, action_delay_value); + print_debug(buf); + } + print_debug("done"); + +#endif + + + if (network_playing && !network_player_action_received) { @@ -3016,8 +3113,10 @@ void GameActions() #endif */ +#ifndef MSDOS /* last chance to get network player actions without main loop delay */ HandleNetworking(); +#endif if (game_status != PLAYING) return; @@ -3059,8 +3158,10 @@ void GameActions() stored_player[i].effective_action = stored_player[i].action; } +#ifndef MSDOS if (network_playing) SendToServer_MovePlayer(summarized_player_action); +#endif if (!options.network && !setup.team_mode) local_player->effective_action = summarized_player_action; @@ -3093,6 +3194,7 @@ void GameActions() #ifdef DEBUG + /* if (TimeFrames == 0 && !local_player->gone) { extern unsigned int last_RND(); @@ -3102,13 +3204,16 @@ void GameActions() last_RND(), getStateCheckSum(level.time - TimeLeft)); } + */ #endif #ifdef DEBUG + /* if (GameFrameDelay >= 500) printf("FrameCounter == %d\n", FrameCounter); + */ #endif @@ -3405,11 +3510,11 @@ boolean MoveFigure(struct PlayerInfo *player, int dx, int dy) if (player->MovPos) { - /* should only happen if pre-1.0 tape recordings are played */ + /* should only happen if pre-1.2 tape recordings are played */ /* this is only for backward compatibility */ #if DEBUG - printf("THIS SHOULD ONLY HAPPEN WITH PRE-1.0 LEVEL TAPES.\n"); + printf("THIS SHOULD ONLY HAPPEN WITH PRE-1.2 LEVEL TAPES.\n"); #endif while (player->MovPos) @@ -3517,7 +3622,7 @@ boolean MoveFigure(struct PlayerInfo *player, int dx, int dy) else if (old_jx == jx && old_jy != jy) player->MovDir = (old_jy < jy ? MV_DOWN : MV_UP); - DrawLevelField(jx, jy); /* für "ErdreichAnbroeckeln()" */ + DrawLevelField(jx, jy); /* for "ErdreichAnbroeckeln()" */ player->last_move_dir = player->MovDir; } @@ -3579,7 +3684,7 @@ void ScrollFigure(struct PlayerInfo *player, int mode) void ScrollScreen(struct PlayerInfo *player, int mode) { - static long screen_frame_counter = 0; + static unsigned long screen_frame_counter = 0; if (mode == SCROLL_INIT) { @@ -3970,7 +4075,7 @@ int DigField(struct PlayerInfo *player, case EL_AUSGANG_ZU: case EL_AUSGANG_ACT: - /* Tür ist (noch) nicht offen! */ + /* door is not (yet) open */ return MF_NO_ACTION; break;