From 9ac3fd202f35f217d5844f4626c97a5808afb1b3 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Tue, 16 Oct 2018 00:00:53 +0200 Subject: [PATCH 01/14] Add a Snake minigame to the downloading screen --- src/d_clisrv.c | 205 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 205 insertions(+) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 3603bb20d..893bf47d6 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1152,6 +1152,191 @@ static void CV_LoadPlayerNames(UINT8 **p) } #ifdef CLIENT_LOADINGSCREEN +#define SNAKE_SPEED 4 +#define SNAKE_NUM_BLOCKS_X 24 +#define SNAKE_NUM_BLOCKS_Y 14 +#define SNAKE_BLOCK_SIZE 8 +#define SNAKE_MAP_WIDTH (SNAKE_NUM_BLOCKS_X * SNAKE_BLOCK_SIZE) +#define SNAKE_MAP_HEIGHT (SNAKE_NUM_BLOCKS_Y * SNAKE_BLOCK_SIZE) +#define SNAKE_BORDER_SIZE 8 +#define SNAKE_LEFT_X ((BASEVIDWIDTH - SNAKE_MAP_WIDTH) / 2 - SNAKE_BORDER_SIZE) +#define SNAKE_RIGHT_X (SNAKE_LEFT_X + SNAKE_MAP_WIDTH + SNAKE_BORDER_SIZE * 2 - 1) +#define SNAKE_BOTTOM_Y (BASEVIDHEIGHT - 64) +#define SNAKE_TOP_Y (SNAKE_BOTTOM_Y - SNAKE_MAP_HEIGHT - SNAKE_BORDER_SIZE * 2 + 1) + +typedef struct snake_s +{ + tic_t time; + tic_t nextupdate; + boolean gameover; + + UINT8 snakedir; + UINT8 snakeprevdir; + + UINT16 snakelength; + UINT8 snakex[SNAKE_NUM_BLOCKS_X * SNAKE_NUM_BLOCKS_Y]; + UINT8 snakey[SNAKE_NUM_BLOCKS_X * SNAKE_NUM_BLOCKS_Y]; + UINT8 snakecolor[SNAKE_NUM_BLOCKS_X * SNAKE_NUM_BLOCKS_Y]; + + UINT8 applex; + UINT8 appley; + UINT8 applecolor; +} snake_t; + +static snake_t *snake = NULL; + +static void CL_InitialiseSnake() +{ + if (!snake) + snake = malloc(sizeof(snake_t)); + + snake->time = 0; + snake->nextupdate = SNAKE_SPEED; + snake->gameover = false; + + snake->snakedir = 0; + snake->snakeprevdir = snake->snakedir; + + snake->snakelength = 1; + snake->snakex[0] = rand() % SNAKE_NUM_BLOCKS_X; + snake->snakey[0] = rand() % SNAKE_NUM_BLOCKS_Y; + snake->snakecolor[0] = rand() % 256; + + snake->applex = rand() % SNAKE_NUM_BLOCKS_X; + snake->appley = rand() % SNAKE_NUM_BLOCKS_Y; + snake->applecolor = rand() % 256; +} + +static void CL_HandleSnake(INT32 key) +{ + UINT8 x, y; + UINT16 i; + + snake->time++; + + // Update direction + switch (key) + { + case KEY_LEFTARROW: + if (snake->snakeprevdir != 2) + snake->snakedir = 1; + break; + case KEY_RIGHTARROW: + if (snake->snakeprevdir != 1) + snake->snakedir = 2; + break; + case KEY_UPARROW: + if (snake->snakeprevdir != 4) + snake->snakedir = 3; + break; + case KEY_DOWNARROW: + if (snake->snakeprevdir != 3) + snake->snakedir = 4; + break; + } + + snake->nextupdate--; + if (snake->nextupdate) + return; + snake->nextupdate = SNAKE_SPEED; + + snake->snakeprevdir = snake->snakedir; + + if (snake->gameover) + return; + + // Find new position + x = snake->snakex[0]; + y = snake->snakey[0]; + switch (snake->snakedir) + { + case 1: + x = x > 0 ? x - 1 : SNAKE_NUM_BLOCKS_X - 1; + break; + case 2: + x = x < SNAKE_NUM_BLOCKS_X - 1 ? x + 1 : 0; + break; + case 3: + y = y > 0 ? y - 1 : SNAKE_NUM_BLOCKS_Y - 1; + break; + case 4: + y = y < SNAKE_NUM_BLOCKS_Y - 1 ? y + 1 : 0; + break; + } + + // Check collision with snake + for (i = 1; i < snake->snakelength - 1; i++) + if (x == snake->snakex[i] && y == snake->snakey[i]) + { + snake->gameover = true; + S_StartSound(NULL, sfx_lose); + return; + } + + // Check collision with apple + if (x == snake->applex && y == snake->appley) + { + snake->snakelength++; + snake->snakex[snake->snakelength - 1] = snake->snakex[snake->snakelength - 2]; + snake->snakey[snake->snakelength - 1] = snake->snakey[snake->snakelength - 2]; + snake->snakecolor[snake->snakelength - 1] = snake->applecolor; + + snake->applex = rand() % SNAKE_NUM_BLOCKS_X; + snake->appley = rand() % SNAKE_NUM_BLOCKS_Y; + snake->applecolor = rand() % 256; + + S_StartSound(NULL, sfx_s3k6b); + } + + // Move + for (i = snake->snakelength - 1; i > 0; i--) + { + snake->snakex[i] = snake->snakex[i - 1]; + snake->snakey[i] = snake->snakey[i - 1]; + } + snake->snakex[0] = x; + snake->snakey[0] = y; +} + +static void CL_DrawSnake(void) +{ + UINT16 i; + + // Background + V_DrawFill(SNAKE_LEFT_X + SNAKE_BORDER_SIZE, SNAKE_TOP_Y + SNAKE_BORDER_SIZE, SNAKE_MAP_WIDTH, SNAKE_MAP_HEIGHT, 239); + + // Borders + V_DrawFill(SNAKE_LEFT_X, SNAKE_TOP_Y, SNAKE_BORDER_SIZE + SNAKE_MAP_WIDTH, SNAKE_BORDER_SIZE, 242); // Top + V_DrawFill(SNAKE_LEFT_X + SNAKE_BORDER_SIZE + SNAKE_MAP_WIDTH, SNAKE_TOP_Y, SNAKE_BORDER_SIZE, SNAKE_BORDER_SIZE + SNAKE_MAP_HEIGHT, 242); // Right + V_DrawFill(SNAKE_LEFT_X + SNAKE_BORDER_SIZE, SNAKE_TOP_Y + SNAKE_BORDER_SIZE + SNAKE_MAP_HEIGHT, SNAKE_BORDER_SIZE + SNAKE_MAP_WIDTH, SNAKE_BORDER_SIZE, 242); // Bottom + V_DrawFill(SNAKE_LEFT_X, SNAKE_TOP_Y + SNAKE_BORDER_SIZE, SNAKE_BORDER_SIZE, SNAKE_BORDER_SIZE + SNAKE_MAP_HEIGHT, 242); // Left + + // Apple + V_DrawFill( + SNAKE_LEFT_X + SNAKE_BORDER_SIZE + snake->applex * SNAKE_BLOCK_SIZE, + SNAKE_TOP_Y + SNAKE_BORDER_SIZE + snake->appley * SNAKE_BLOCK_SIZE, + SNAKE_BLOCK_SIZE, + SNAKE_BLOCK_SIZE, + snake->applecolor + ); + + // Snake + if (!snake->gameover || snake->time % 8 < 8 / 2) // Blink if game over + for (i = 0; i < snake->snakelength; i++) + { + V_DrawFill( + SNAKE_LEFT_X + SNAKE_BORDER_SIZE + snake->snakex[i] * SNAKE_BLOCK_SIZE, + SNAKE_TOP_Y + SNAKE_BORDER_SIZE + snake->snakey[i] * SNAKE_BLOCK_SIZE, + SNAKE_BLOCK_SIZE, + SNAKE_BLOCK_SIZE, + snake->snakecolor[i] + ); + } + + // Length + V_DrawString(SNAKE_RIGHT_X + 4, SNAKE_TOP_Y, V_MONOSPACE, va("%u", snake->snakelength)); +} + // // CL_DrawConnectionStatus // @@ -1215,6 +1400,8 @@ static inline void CL_DrawConnectionStatus(void) fileneeded_t *file = &fileneeded[lastfilenum]; char *filename = file->filename; + CL_DrawSnake(); + Net_GetNetStat(); dldlength = (INT32)((file->currentsize/(double)file->totalsize) * 256); if (dldlength > 256) @@ -1975,7 +2162,10 @@ static boolean CL_ServerConnectionSearchTicker(boolean viams, tic_t *asksent) } // no problem if can't send packet, we will retry later if (CL_SendRequestFile()) + { cl_mode = CL_DOWNLOADFILES; + CL_InitialiseSnake(); + } } } else @@ -2039,6 +2229,12 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic if (waitmore) break; // exit the case + if (snake) + { + free(snake); + snake = NULL; + } + cl_mode = CL_ASKJOIN; // don't break case continue to cljoin request now /* FALLTHRU */ @@ -2093,11 +2289,20 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic { CONS_Printf(M_GetText("Network game synchronization aborted.\n")); // M_StartMessage(M_GetText("Network game synchronization aborted.\n\nPress ESC\n"), NULL, MM_NOTHING); + + if (snake) + { + free(snake); + snake = NULL; + } + D_QuitNetGame(); CL_Reset(); D_StartTitle(); return false; } + else if (cl_mode == CL_DOWNLOADFILES && snake) + CL_HandleSnake(key); // why are these here? this is for servers, we're a client //if (key == 's' && server) From d235d401bc01eb59fa05013006d3f96c2cb05b59 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Wed, 1 Jan 2020 00:18:17 +0100 Subject: [PATCH 02/14] Improve controls handling in connection screen minigame --- src/d_clisrv.c | 44 +++++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 893bf47d6..d3fdd1ff9 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1215,24 +1215,25 @@ static void CL_HandleSnake(INT32 key) snake->time++; // Update direction - switch (key) + if (gamekeydown[KEY_LEFTARROW]) { - case KEY_LEFTARROW: - if (snake->snakeprevdir != 2) - snake->snakedir = 1; - break; - case KEY_RIGHTARROW: - if (snake->snakeprevdir != 1) - snake->snakedir = 2; - break; - case KEY_UPARROW: - if (snake->snakeprevdir != 4) - snake->snakedir = 3; - break; - case KEY_DOWNARROW: - if (snake->snakeprevdir != 3) - snake->snakedir = 4; - break; + if (snake->snakeprevdir != 2) + snake->snakedir = 1; + } + else if (gamekeydown[KEY_RIGHTARROW]) + { + if (snake->snakeprevdir != 1) + snake->snakedir = 2; + } + else if (gamekeydown[KEY_UPARROW]) + { + if (snake->snakeprevdir != 4) + snake->snakedir = 3; + } + else if (gamekeydown[KEY_DOWNARROW]) + { + if (snake->snakeprevdir != 3) + snake->snakedir = 4; } snake->nextupdate--; @@ -2281,11 +2282,11 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic // Call it only once by tic if (*oldtic != I_GetTime()) { - INT32 key; - I_OsPolling(); - key = I_GetKey(); - if (key == KEY_ESCAPE || key == KEY_JOY1+1) + for (; eventtail != eventhead; eventtail = (eventtail+1) & (MAXEVENTS-1)) + G_MapEventsToControls(&events[eventtail]); + + if (gamekeydown[KEY_ESCAPE] || gamekeydown[KEY_JOY1+1]) { CONS_Printf(M_GetText("Network game synchronization aborted.\n")); // M_StartMessage(M_GetText("Network game synchronization aborted.\n\nPress ESC\n"), NULL, MM_NOTHING); @@ -2299,6 +2300,7 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic D_QuitNetGame(); CL_Reset(); D_StartTitle(); + memset(gamekeydown, 0, NUMKEYS); return false; } else if (cl_mode == CL_DOWNLOADFILES && snake) From 10fbaaf781ab783a9bfe4bb598e5b1e8576a0f27 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Fri, 24 Apr 2020 22:19:05 +0200 Subject: [PATCH 03/14] Fix compiler warnings --- src/d_clisrv.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index d3fdd1ff9..a74a85cb3 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1185,7 +1185,7 @@ typedef struct snake_s static snake_t *snake = NULL; -static void CL_InitialiseSnake() +static void CL_InitialiseSnake(void) { if (!snake) snake = malloc(sizeof(snake_t)); @@ -1207,7 +1207,7 @@ static void CL_InitialiseSnake() snake->applecolor = rand() % 256; } -static void CL_HandleSnake(INT32 key) +static void CL_HandleSnake(void) { UINT8 x, y; UINT16 i; @@ -2304,7 +2304,7 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic return false; } else if (cl_mode == CL_DOWNLOADFILES && snake) - CL_HandleSnake(key); + CL_HandleSnake(); // why are these here? this is for servers, we're a client //if (key == 's' && server) From 7c9ce1faee11707397aff8d517aac617349d578a Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Sun, 26 Apr 2020 21:17:15 +0200 Subject: [PATCH 04/14] Prevent edge warping in Snake minigame --- src/d_clisrv.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index a74a85cb3..dfe8e0cf6 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1252,18 +1252,32 @@ static void CL_HandleSnake(void) switch (snake->snakedir) { case 1: - x = x > 0 ? x - 1 : SNAKE_NUM_BLOCKS_X - 1; + if (x > 0) + x--; + else + snake->gameover = true; break; case 2: - x = x < SNAKE_NUM_BLOCKS_X - 1 ? x + 1 : 0; + if (x < SNAKE_NUM_BLOCKS_X - 1) + x++; + else + snake->gameover = true; break; case 3: - y = y > 0 ? y - 1 : SNAKE_NUM_BLOCKS_Y - 1; + if (y > 0) + y--; + else + snake->gameover = true; break; case 4: - y = y < SNAKE_NUM_BLOCKS_Y - 1 ? y + 1 : 0; + if (y < SNAKE_NUM_BLOCKS_Y - 1) + y++; + else + snake->gameover = true; break; } + if (snake->gameover) + return; // Check collision with snake for (i = 1; i < snake->snakelength - 1; i++) From 380e246be349704c3bbcf0ebac43d2a00da8dd63 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Sun, 26 Apr 2020 21:57:17 +0200 Subject: [PATCH 05/14] Lower the download progress bar --- src/d_clisrv.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index dfe8e0cf6..2f5027fd5 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1161,7 +1161,7 @@ static void CV_LoadPlayerNames(UINT8 **p) #define SNAKE_BORDER_SIZE 8 #define SNAKE_LEFT_X ((BASEVIDWIDTH - SNAKE_MAP_WIDTH) / 2 - SNAKE_BORDER_SIZE) #define SNAKE_RIGHT_X (SNAKE_LEFT_X + SNAKE_MAP_WIDTH + SNAKE_BORDER_SIZE * 2 - 1) -#define SNAKE_BOTTOM_Y (BASEVIDHEIGHT - 64) +#define SNAKE_BOTTOM_Y (BASEVIDHEIGHT - 48) #define SNAKE_TOP_Y (SNAKE_BOTTOM_Y - SNAKE_MAP_HEIGHT - SNAKE_BORDER_SIZE * 2 + 1) typedef struct snake_s @@ -1366,8 +1366,8 @@ static inline void CL_DrawConnectionStatus(void) V_DrawFadeScreen(0xFF00, 16); // force default // Draw the bottom box. - M_DrawTextBox(BASEVIDWIDTH/2-128-8, BASEVIDHEIGHT-24-8, 32, 1); - V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-24-24, V_YELLOWMAP, "Press ESC to abort"); + M_DrawTextBox(BASEVIDWIDTH/2-128-8, BASEVIDHEIGHT-16-8, 32, 1); + V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-16-16, V_YELLOWMAP, "Press ESC to abort"); if (cl_mode != CL_DOWNLOADFILES) { @@ -1377,7 +1377,7 @@ static inline void CL_DrawConnectionStatus(void) const char *cltext; for (i = 0; i < 16; ++i) - V_DrawFill((BASEVIDWIDTH/2-128) + (i * 16), BASEVIDHEIGHT-24, 16, 8, palstart + ((animtime - i) & 15)); + V_DrawFill((BASEVIDWIDTH/2-128) + (i * 16), BASEVIDHEIGHT-16, 16, 8, palstart + ((animtime - i) & 15)); switch (cl_mode) { @@ -1387,9 +1387,9 @@ static inline void CL_DrawConnectionStatus(void) { cltext = M_GetText("Downloading game state..."); Net_GetNetStat(); - V_DrawString(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, V_20TRANS|V_MONOSPACE, + V_DrawString(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-16, V_20TRANS|V_MONOSPACE, va(" %4uK",fileneeded[lastfilenum].currentsize>>10)); - V_DrawRightAlignedString(BASEVIDWIDTH/2+128, BASEVIDHEIGHT-24, V_20TRANS|V_MONOSPACE, + V_DrawRightAlignedString(BASEVIDWIDTH/2+128, BASEVIDHEIGHT-16, V_20TRANS|V_MONOSPACE, va("%3.1fK/s ", ((double)getbps)/1024)); } else @@ -1404,7 +1404,7 @@ static inline void CL_DrawConnectionStatus(void) cltext = M_GetText("Connecting to server..."); break; } - V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-24-32, V_YELLOWMAP, cltext); + V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-16-24, V_YELLOWMAP, cltext); } else { @@ -1421,8 +1421,8 @@ static inline void CL_DrawConnectionStatus(void) dldlength = (INT32)((file->currentsize/(double)file->totalsize) * 256); if (dldlength > 256) dldlength = 256; - V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, 256, 8, 111); - V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, dldlength, 8, 96); + V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-16, 256, 8, 111); + V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-16, dldlength, 8, 96); memset(tempname, 0, sizeof(tempname)); // offset filename to just the name only part @@ -1440,15 +1440,15 @@ static inline void CL_DrawConnectionStatus(void) strncpy(tempname, filename, sizeof(tempname)-1); } - V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-24-32, V_YELLOWMAP, + V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-16-24, V_YELLOWMAP, va(M_GetText("Downloading \"%s\""), tempname)); - V_DrawString(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, V_20TRANS|V_MONOSPACE, + V_DrawString(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-16, V_20TRANS|V_MONOSPACE, va(" %4uK/%4uK",fileneeded[lastfilenum].currentsize>>10,file->totalsize>>10)); - V_DrawRightAlignedString(BASEVIDWIDTH/2+128, BASEVIDHEIGHT-24, V_20TRANS|V_MONOSPACE, + V_DrawRightAlignedString(BASEVIDWIDTH/2+128, BASEVIDHEIGHT-16, V_20TRANS|V_MONOSPACE, va("%3.1fK/s ", ((double)getbps)/1024)); } else - V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-24-32, V_YELLOWMAP, + V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-16-24, V_YELLOWMAP, M_GetText("Waiting to download files...")); } } From 58c0383e883f67e785af424c38dcf427ef086fb1 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Mon, 27 Apr 2020 13:01:14 +0200 Subject: [PATCH 06/14] Use sprites for snake and apple --- src/d_clisrv.c | 163 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 110 insertions(+), 53 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 2f5027fd5..d9e76e69f 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1153,12 +1153,12 @@ static void CV_LoadPlayerNames(UINT8 **p) #ifdef CLIENT_LOADINGSCREEN #define SNAKE_SPEED 4 -#define SNAKE_NUM_BLOCKS_X 24 -#define SNAKE_NUM_BLOCKS_Y 14 -#define SNAKE_BLOCK_SIZE 8 +#define SNAKE_NUM_BLOCKS_X 20 +#define SNAKE_NUM_BLOCKS_Y 10 +#define SNAKE_BLOCK_SIZE 12 #define SNAKE_MAP_WIDTH (SNAKE_NUM_BLOCKS_X * SNAKE_BLOCK_SIZE) #define SNAKE_MAP_HEIGHT (SNAKE_NUM_BLOCKS_Y * SNAKE_BLOCK_SIZE) -#define SNAKE_BORDER_SIZE 8 +#define SNAKE_BORDER_SIZE 12 #define SNAKE_LEFT_X ((BASEVIDWIDTH - SNAKE_MAP_WIDTH) / 2 - SNAKE_BORDER_SIZE) #define SNAKE_RIGHT_X (SNAKE_LEFT_X + SNAKE_MAP_WIDTH + SNAKE_BORDER_SIZE * 2 - 1) #define SNAKE_BOTTOM_Y (BASEVIDHEIGHT - 48) @@ -1170,17 +1170,13 @@ typedef struct snake_s tic_t nextupdate; boolean gameover; - UINT8 snakedir; - UINT8 snakeprevdir; - UINT16 snakelength; UINT8 snakex[SNAKE_NUM_BLOCKS_X * SNAKE_NUM_BLOCKS_Y]; UINT8 snakey[SNAKE_NUM_BLOCKS_X * SNAKE_NUM_BLOCKS_Y]; - UINT8 snakecolor[SNAKE_NUM_BLOCKS_X * SNAKE_NUM_BLOCKS_Y]; + UINT8 snakedir[SNAKE_NUM_BLOCKS_X * SNAKE_NUM_BLOCKS_Y]; UINT8 applex; UINT8 appley; - UINT8 applecolor; } snake_t; static snake_t *snake = NULL; @@ -1194,46 +1190,49 @@ static void CL_InitialiseSnake(void) snake->nextupdate = SNAKE_SPEED; snake->gameover = false; - snake->snakedir = 0; - snake->snakeprevdir = snake->snakedir; - snake->snakelength = 1; - snake->snakex[0] = rand() % SNAKE_NUM_BLOCKS_X; - snake->snakey[0] = rand() % SNAKE_NUM_BLOCKS_Y; - snake->snakecolor[0] = rand() % 256; + snake->snakex[0] = M_RandomKey(SNAKE_NUM_BLOCKS_X); + snake->snakey[0] = M_RandomKey(SNAKE_NUM_BLOCKS_Y); + snake->snakedir[0] = 0; + snake->snakedir[1] = 0; - snake->applex = rand() % SNAKE_NUM_BLOCKS_X; - snake->appley = rand() % SNAKE_NUM_BLOCKS_Y; - snake->applecolor = rand() % 256; + snake->applex = M_RandomKey(SNAKE_NUM_BLOCKS_X); + snake->appley = M_RandomKey(SNAKE_NUM_BLOCKS_Y); } static void CL_HandleSnake(void) { UINT8 x, y; + UINT8 oldx, oldy; UINT16 i; snake->time++; + x = snake->snakex[0]; + y = snake->snakey[0]; + oldx = snake->snakex[1]; + oldy = snake->snakey[1]; + // Update direction if (gamekeydown[KEY_LEFTARROW]) { - if (snake->snakeprevdir != 2) - snake->snakedir = 1; + if (snake->snakelength < 2 || x <= oldx) + snake->snakedir[0] = 1; } else if (gamekeydown[KEY_RIGHTARROW]) { - if (snake->snakeprevdir != 1) - snake->snakedir = 2; + if (snake->snakelength < 2 || x >= oldx) + snake->snakedir[0] = 2; } else if (gamekeydown[KEY_UPARROW]) { - if (snake->snakeprevdir != 4) - snake->snakedir = 3; + if (snake->snakelength < 2 || y <= oldy) + snake->snakedir[0] = 3; } else if (gamekeydown[KEY_DOWNARROW]) { - if (snake->snakeprevdir != 3) - snake->snakedir = 4; + if (snake->snakelength < 2 || y >= oldy) + snake->snakedir[0] = 4; } snake->nextupdate--; @@ -1241,15 +1240,11 @@ static void CL_HandleSnake(void) return; snake->nextupdate = SNAKE_SPEED; - snake->snakeprevdir = snake->snakedir; - if (snake->gameover) return; // Find new position - x = snake->snakex[0]; - y = snake->snakey[0]; - switch (snake->snakedir) + switch (snake->snakedir[0]) { case 1: if (x > 0) @@ -1294,28 +1289,53 @@ static void CL_HandleSnake(void) snake->snakelength++; snake->snakex[snake->snakelength - 1] = snake->snakex[snake->snakelength - 2]; snake->snakey[snake->snakelength - 1] = snake->snakey[snake->snakelength - 2]; - snake->snakecolor[snake->snakelength - 1] = snake->applecolor; + snake->snakedir[snake->snakelength - 1] = snake->snakedir[snake->snakelength - 2]; - snake->applex = rand() % SNAKE_NUM_BLOCKS_X; - snake->appley = rand() % SNAKE_NUM_BLOCKS_Y; - snake->applecolor = rand() % 256; + snake->applex = M_RandomKey(SNAKE_NUM_BLOCKS_X); + snake->appley = M_RandomKey(SNAKE_NUM_BLOCKS_Y); S_StartSound(NULL, sfx_s3k6b); } - // Move - for (i = snake->snakelength - 1; i > 0; i--) + if (snake->snakelength > 1) { - snake->snakex[i] = snake->snakex[i - 1]; - snake->snakey[i] = snake->snakey[i - 1]; + UINT8 dir = snake->snakedir[0]; + + // Move + for (i = snake->snakelength - 1; i > 0; i--) + { + snake->snakex[i] = snake->snakex[i - 1]; + snake->snakey[i] = snake->snakey[i - 1]; + snake->snakedir[i] = snake->snakedir[i - 1]; + } + + // Handle corners + if (x < oldx && dir == 3) + dir = 5; + else if (x > oldx && dir == 3) + dir = 6; + else if (x < oldx && dir == 4) + dir = 7; + else if (x > oldx && dir == 4) + dir = 8; + else if (y < oldy && dir == 1) + dir = 9; + else if (y < oldy && dir == 2) + dir = 10; + else if (y > oldy && dir == 1) + dir = 11; + else if (y > oldy && dir == 2) + dir = 12; + snake->snakedir[1] = dir; } + snake->snakex[0] = x; snake->snakey[0] = y; } static void CL_DrawSnake(void) { - UINT16 i; + INT16 i; // Background V_DrawFill(SNAKE_LEFT_X + SNAKE_BORDER_SIZE, SNAKE_TOP_Y + SNAKE_BORDER_SIZE, SNAKE_MAP_WIDTH, SNAKE_MAP_HEIGHT, 239); @@ -1327,26 +1347,63 @@ static void CL_DrawSnake(void) V_DrawFill(SNAKE_LEFT_X, SNAKE_TOP_Y + SNAKE_BORDER_SIZE, SNAKE_BORDER_SIZE, SNAKE_BORDER_SIZE + SNAKE_MAP_HEIGHT, 242); // Left // Apple - V_DrawFill( - SNAKE_LEFT_X + SNAKE_BORDER_SIZE + snake->applex * SNAKE_BLOCK_SIZE, - SNAKE_TOP_Y + SNAKE_BORDER_SIZE + snake->appley * SNAKE_BLOCK_SIZE, - SNAKE_BLOCK_SIZE, - SNAKE_BLOCK_SIZE, - snake->applecolor + V_DrawFixedPatch( + (SNAKE_LEFT_X + SNAKE_BORDER_SIZE + snake->applex * SNAKE_BLOCK_SIZE + SNAKE_BLOCK_SIZE / 2) * FRACUNIT, + (SNAKE_TOP_Y + SNAKE_BORDER_SIZE + snake->appley * SNAKE_BLOCK_SIZE + SNAKE_BLOCK_SIZE / 2) * FRACUNIT, + FRACUNIT / 4, + 0, + W_CachePatchName("DL_APPLE", PU_HUDGFX), + NULL ); // Snake if (!snake->gameover || snake->time % 8 < 8 / 2) // Blink if game over - for (i = 0; i < snake->snakelength; i++) + { + for (i = snake->snakelength - 1; i >= 0; i--) { - V_DrawFill( - SNAKE_LEFT_X + SNAKE_BORDER_SIZE + snake->snakex[i] * SNAKE_BLOCK_SIZE, - SNAKE_TOP_Y + SNAKE_BORDER_SIZE + snake->snakey[i] * SNAKE_BLOCK_SIZE, - SNAKE_BLOCK_SIZE, - SNAKE_BLOCK_SIZE, - snake->snakecolor[i] + const char *patchname; + UINT8 dir = snake->snakedir[i]; + + if (i == 0) // Head + { + switch (dir) + { + case 1: patchname = "DL_SNAKEHEAD_L"; break; + case 2: patchname = "DL_SNAKEHEAD_R"; break; + case 3: patchname = "DL_SNAKEHEAD_T"; break; + default: patchname = "DL_SNAKEHEAD_B"; + } + } + else // Body + { + switch (dir) + { + case 1: patchname = "DL_SNAKEBODY_L"; break; + case 2: patchname = "DL_SNAKEBODY_R"; break; + case 3: patchname = "DL_SNAKEBODY_T"; break; + case 4: patchname = "DL_SNAKEBODY_B"; break; + case 5: patchname = "DL_SNAKEBODY_LT"; break; + case 6: patchname = "DL_SNAKEBODY_RT"; break; + case 7: patchname = "DL_SNAKEBODY_LB"; break; + case 8: patchname = "DL_SNAKEBODY_RB"; break; + case 9: patchname = "DL_SNAKEBODY_TL"; break; + case 10: patchname = "DL_SNAKEBODY_TR"; break; + case 11: patchname = "DL_SNAKEBODY_BL"; break; + case 12: patchname = "DL_SNAKEBODY_BR"; break; + default: patchname = "DL_SNAKEBODY_B"; + } + } + + V_DrawFixedPatch( + (SNAKE_LEFT_X + SNAKE_BORDER_SIZE + snake->snakex[i] * SNAKE_BLOCK_SIZE + SNAKE_BLOCK_SIZE / 2) * FRACUNIT, + (SNAKE_TOP_Y + SNAKE_BORDER_SIZE + snake->snakey[i] * SNAKE_BLOCK_SIZE + SNAKE_BLOCK_SIZE / 2) * FRACUNIT, + FRACUNIT / 2, + 0, + W_CachePatchName(patchname, PU_HUDGFX), + NULL ); } + } // Length V_DrawString(SNAKE_RIGHT_X + 4, SNAKE_TOP_Y, V_MONOSPACE, va("%u", snake->snakelength)); From c7cd53d5b2cedfea0e70d5937e839285b4e644fb Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Mon, 27 Apr 2020 14:22:45 +0200 Subject: [PATCH 07/14] Call rand() a few times after calling srand() --- src/d_main.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/d_main.c b/src/d_main.c index 00aeb541d..d3539ed97 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1182,6 +1182,9 @@ void D_SRB2Main(void) // rand() needs seeded regardless of password srand((unsigned int)time(NULL)); + rand(); + rand(); + rand(); if (M_CheckParm("-password") && M_IsNextParm()) D_SetPassword(M_GetNextParm()); From 647d74bad5fbbf40b1baf6c51dfd982f73da5016 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Mon, 27 Apr 2020 15:31:38 +0200 Subject: [PATCH 08/14] Add a background to Snake minigame --- src/d_clisrv.c | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index d9e76e69f..af60889b2 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1164,11 +1164,25 @@ static void CV_LoadPlayerNames(UINT8 **p) #define SNAKE_BOTTOM_Y (BASEVIDHEIGHT - 48) #define SNAKE_TOP_Y (SNAKE_BOTTOM_Y - SNAKE_MAP_HEIGHT - SNAKE_BORDER_SIZE * 2 + 1) +static const char *snake_backgrounds[] = { + "RVPUMICF", + "FRSTRCKF", + "TAR", + "MMFLRB4", + "RVDARKF1", + "RVZWALF1", + "RVZWALF4", + "RVZWALF5", + "RVZGRS02", + "RVZGRS04", +}; + typedef struct snake_s { tic_t time; tic_t nextupdate; boolean gameover; + UINT8 background; UINT16 snakelength; UINT8 snakex[SNAKE_NUM_BLOCKS_X * SNAKE_NUM_BLOCKS_Y]; @@ -1189,6 +1203,7 @@ static void CL_InitialiseSnake(void) snake->time = 0; snake->nextupdate = SNAKE_SPEED; snake->gameover = false; + snake->background = M_RandomKey(sizeof(snake_backgrounds) / sizeof(*snake_backgrounds)); snake->snakelength = 1; snake->snakex[0] = M_RandomKey(SNAKE_NUM_BLOCKS_X); @@ -1338,7 +1353,13 @@ static void CL_DrawSnake(void) INT16 i; // Background - V_DrawFill(SNAKE_LEFT_X + SNAKE_BORDER_SIZE, SNAKE_TOP_Y + SNAKE_BORDER_SIZE, SNAKE_MAP_WIDTH, SNAKE_MAP_HEIGHT, 239); + V_DrawFlatFill( + SNAKE_LEFT_X + SNAKE_BORDER_SIZE, + SNAKE_TOP_Y + SNAKE_BORDER_SIZE, + SNAKE_MAP_WIDTH, + SNAKE_MAP_HEIGHT, + W_GetNumForName(snake_backgrounds[snake->background]) + ); // Borders V_DrawFill(SNAKE_LEFT_X, SNAKE_TOP_Y, SNAKE_BORDER_SIZE + SNAKE_MAP_WIDTH, SNAKE_BORDER_SIZE, 242); // Top @@ -2386,9 +2407,12 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic #ifdef CLIENT_LOADINGSCREEN if (client && cl_mode != CL_CONNECTED && cl_mode != CL_ABORTED) { - F_MenuPresTicker(true); // title sky - F_TitleScreenTicker(true); - F_TitleScreenDrawer(); + if (cl_mode != CL_DOWNLOADFILES && cl_mode != CL_DOWNLOADSAVEGAME) + { + F_MenuPresTicker(true); // title sky + F_TitleScreenTicker(true); + F_TitleScreenDrawer(); + } CL_DrawConnectionStatus(); I_UpdateNoVsync(); // page flip or blit buffer if (moviemode) From a3dcc100c0761dcff4cac4e58993b678e038af01 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Mon, 27 Apr 2020 22:06:32 +0200 Subject: [PATCH 09/14] Add pause and retry to Snake minigame --- src/d_clisrv.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index af60889b2..95fe919b2 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1179,6 +1179,8 @@ static const char *snake_backgrounds[] = { typedef struct snake_s { + boolean paused; + boolean pausepressed; tic_t time; tic_t nextupdate; boolean gameover; @@ -1200,6 +1202,8 @@ static void CL_InitialiseSnake(void) if (!snake) snake = malloc(sizeof(snake_t)); + snake->paused = false; + snake->pausepressed = false; snake->time = 0; snake->nextupdate = SNAKE_SPEED; snake->gameover = false; @@ -1221,6 +1225,26 @@ static void CL_HandleSnake(void) UINT8 oldx, oldy; UINT16 i; + // Handle retry + if (snake->gameover && (PLAYER1INPUTDOWN(gc_jump) || gamekeydown[KEY_ENTER])) + { + CL_InitialiseSnake(); + snake->pausepressed = true; // Avoid accidental pause on respawn + } + + // Handle pause + if (PLAYER1INPUTDOWN(gc_pause) || gamekeydown[KEY_ENTER]) + { + if (!snake->pausepressed) + snake->paused = !snake->paused; + snake->pausepressed = true; + } + else + snake->pausepressed = false; + + if (snake->paused) + return; + snake->time++; x = snake->snakex[0]; From dfdace22bbf02eb20eab43bd29f4d81212864230 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Mon, 27 Apr 2020 23:10:13 +0200 Subject: [PATCH 10/14] Add bonuses and maluses to Snake minigame --- src/d_clisrv.c | 226 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 206 insertions(+), 20 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 95fe919b2..a79d398fa 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1164,6 +1164,29 @@ static void CV_LoadPlayerNames(UINT8 **p) #define SNAKE_BOTTOM_Y (BASEVIDHEIGHT - 48) #define SNAKE_TOP_Y (SNAKE_BOTTOM_Y - SNAKE_MAP_HEIGHT - SNAKE_BORDER_SIZE * 2 + 1) +enum snake_bonustype_s { + SNAKE_BONUS_NONE = 0, + SNAKE_BONUS_SLOW, + SNAKE_BONUS_FAST, + SNAKE_BONUS_GHOST, + SNAKE_BONUS_NUKE, + SNAKE_BONUS_SCISSORS, + SNAKE_BONUS_REVERSE, + SNAKE_BONUS_EGGMAN, + SNAKE_NUM_BONUSES, +}; + +static const char *snake_bonuspatches[] = { + NULL, + "DL_SLOW", + "TVSSC0", + "TVIVC0", + "TVARC0", + "DL_SCISSORS", + "TVRCC0", + "TVEGC0", +}; + static const char *snake_backgrounds[] = { "RVPUMICF", "FRSTRCKF", @@ -1187,12 +1210,18 @@ typedef struct snake_s UINT8 background; UINT16 snakelength; + enum snake_bonustype_s snakebonus; + tic_t snakebonustime; UINT8 snakex[SNAKE_NUM_BLOCKS_X * SNAKE_NUM_BLOCKS_Y]; UINT8 snakey[SNAKE_NUM_BLOCKS_X * SNAKE_NUM_BLOCKS_Y]; UINT8 snakedir[SNAKE_NUM_BLOCKS_X * SNAKE_NUM_BLOCKS_Y]; UINT8 applex; UINT8 appley; + + enum snake_bonustype_s bonustype; + UINT8 bonusx; + UINT8 bonusy; } snake_t; static snake_t *snake = NULL; @@ -1210,6 +1239,7 @@ static void CL_InitialiseSnake(void) snake->background = M_RandomKey(sizeof(snake_backgrounds) / sizeof(*snake_backgrounds)); snake->snakelength = 1; + snake->snakebonus = SNAKE_BONUS_NONE; snake->snakex[0] = M_RandomKey(SNAKE_NUM_BLOCKS_X); snake->snakey[0] = M_RandomKey(SNAKE_NUM_BLOCKS_Y); snake->snakedir[0] = 0; @@ -1217,6 +1247,33 @@ static void CL_InitialiseSnake(void) snake->applex = M_RandomKey(SNAKE_NUM_BLOCKS_X); snake->appley = M_RandomKey(SNAKE_NUM_BLOCKS_Y); + + snake->bonustype = SNAKE_BONUS_NONE; +} + +static UINT8 Snake_GetOppositeDir(UINT8 dir) +{ + if (dir == 1 || dir == 3) + return dir + 1; + else if (dir == 2 || dir == 4) + return dir - 1; + else + return 12 + 5 - dir; +} + +static void Snake_FindFreeSlot(UINT8 *x, UINT8 *y) +{ + UINT16 i; + + do + { + *x = M_RandomKey(SNAKE_NUM_BLOCKS_X); + *y = M_RandomKey(SNAKE_NUM_BLOCKS_Y); + + for (i = 0; i < snake->snakelength; i++) + if (*x == snake->snakex[i] && *y == snake->snakey[i]) + break; + } while (i < snake->snakelength); } static void CL_HandleSnake(void) @@ -1274,10 +1331,22 @@ static void CL_HandleSnake(void) snake->snakedir[0] = 4; } + if (snake->snakebonustime) + { + snake->snakebonustime--; + if (!snake->snakebonustime) + snake->snakebonus = SNAKE_BONUS_NONE; + } + snake->nextupdate--; if (snake->nextupdate) return; - snake->nextupdate = SNAKE_SPEED; + if (snake->snakebonus == SNAKE_BONUS_SLOW) + snake->nextupdate = SNAKE_SPEED * 2; + else if (snake->snakebonus == SNAKE_BONUS_FAST) + snake->nextupdate = SNAKE_SPEED * 2 / 3; + else + snake->nextupdate = SNAKE_SPEED; if (snake->gameover) return; @@ -1310,36 +1379,64 @@ static void CL_HandleSnake(void) snake->gameover = true; break; } - if (snake->gameover) - return; // Check collision with snake - for (i = 1; i < snake->snakelength - 1; i++) - if (x == snake->snakex[i] && y == snake->snakey[i]) - { - snake->gameover = true; - S_StartSound(NULL, sfx_lose); - return; - } + if (snake->snakebonus != SNAKE_BONUS_GHOST) + for (i = 1; i < snake->snakelength - 1; i++) + if (x == snake->snakex[i] && y == snake->snakey[i]) + { + if (snake->snakebonus == SNAKE_BONUS_SCISSORS) + { + snake->snakebonus = SNAKE_BONUS_NONE; + snake->snakelength = i; + S_StartSound(NULL, sfx_adderr); + } + else + snake->gameover = true; + } + + if (snake->gameover) + { + S_StartSound(NULL, sfx_lose); + return; + } // Check collision with apple if (x == snake->applex && y == snake->appley) { - snake->snakelength++; - snake->snakex[snake->snakelength - 1] = snake->snakex[snake->snakelength - 2]; - snake->snakey[snake->snakelength - 1] = snake->snakey[snake->snakelength - 2]; - snake->snakedir[snake->snakelength - 1] = snake->snakedir[snake->snakelength - 2]; + if (snake->snakelength + 1 < SNAKE_NUM_BLOCKS_X * SNAKE_NUM_BLOCKS_Y) + { + snake->snakelength++; + snake->snakex [snake->snakelength - 1] = snake->snakex [snake->snakelength - 2]; + snake->snakey [snake->snakelength - 1] = snake->snakey [snake->snakelength - 2]; + snake->snakedir[snake->snakelength - 1] = snake->snakedir[snake->snakelength - 2]; + } - snake->applex = M_RandomKey(SNAKE_NUM_BLOCKS_X); - snake->appley = M_RandomKey(SNAKE_NUM_BLOCKS_Y); + // Spawn new apple + Snake_FindFreeSlot(&snake->applex, &snake->appley); + + // Spawn new bonus + if (!(snake->snakelength % 5)) + { + do + { + snake->bonustype = M_RandomKey(SNAKE_NUM_BONUSES - 1) + 1; + } while (snake->snakelength > SNAKE_NUM_BLOCKS_X * SNAKE_NUM_BLOCKS_Y * 3 / 4 + && (snake->bonustype == SNAKE_BONUS_EGGMAN || snake->bonustype == SNAKE_BONUS_FAST || snake->bonustype == SNAKE_BONUS_REVERSE)); + + Snake_FindFreeSlot(&snake->bonusx, &snake->bonusy); + } S_StartSound(NULL, sfx_s3k6b); } - if (snake->snakelength > 1) + if (snake->snakelength > 1 && snake->snakedir[0]) { UINT8 dir = snake->snakedir[0]; + oldx = snake->snakex[1]; + oldy = snake->snakey[1]; + // Move for (i = snake->snakelength - 1; i > 0; i--) { @@ -1370,6 +1467,71 @@ static void CL_HandleSnake(void) snake->snakex[0] = x; snake->snakey[0] = y; + + // Check collision with bonus + if (snake->bonustype != SNAKE_BONUS_NONE && x == snake->bonusx && y == snake->bonusy) + { + S_StartSound(NULL, sfx_ncchip); + + switch (snake->bonustype) + { + case SNAKE_BONUS_SLOW: + snake->snakebonus = SNAKE_BONUS_SLOW; + snake->snakebonustime = 20 * TICRATE; + break; + case SNAKE_BONUS_FAST: + snake->snakebonus = SNAKE_BONUS_FAST; + snake->snakebonustime = 20 * TICRATE; + break; + case SNAKE_BONUS_GHOST: + snake->snakebonus = SNAKE_BONUS_GHOST; + snake->snakebonustime = 10 * TICRATE; + break; + case SNAKE_BONUS_NUKE: + for (i = 0; i < snake->snakelength; i++) + { + snake->snakex [i] = snake->snakex [0]; + snake->snakey [i] = snake->snakey [0]; + snake->snakedir[i] = snake->snakedir[0]; + } + + S_StartSound(NULL, sfx_bkpoof); + break; + case SNAKE_BONUS_SCISSORS: + snake->snakebonus = SNAKE_BONUS_SCISSORS; + snake->snakebonustime = 60 * TICRATE; + break; + case SNAKE_BONUS_REVERSE: + for (i = 0; i < (snake->snakelength + 1) / 2; i++) + { + UINT16 i2 = snake->snakelength - 1 - i; + UINT8 tmpx = snake->snakex [i]; + UINT8 tmpy = snake->snakey [i]; + UINT8 tmpdir = snake->snakedir[i]; + + // Swap first segment with last segment + snake->snakex [i] = snake->snakex [i2]; + snake->snakey [i] = snake->snakey [i2]; + snake->snakedir[i] = Snake_GetOppositeDir(snake->snakedir[i2]); + snake->snakex [i2] = tmpx; + snake->snakey [i2] = tmpy; + snake->snakedir[i2] = Snake_GetOppositeDir(tmpdir); + } + + snake->snakedir[0] = 0; + + S_StartSound(NULL, sfx_gravch); + break; + default: + if (snake->snakebonus != SNAKE_BONUS_GHOST) + { + snake->gameover = true; + S_StartSound(NULL, sfx_lose); + } + } + + snake->bonustype = SNAKE_BONUS_NONE; + } } static void CL_DrawSnake(void) @@ -1401,6 +1563,17 @@ static void CL_DrawSnake(void) NULL ); + // Bonus + if (snake->bonustype != SNAKE_BONUS_NONE) + V_DrawFixedPatch( + (SNAKE_LEFT_X + SNAKE_BORDER_SIZE + snake->bonusx * SNAKE_BLOCK_SIZE + SNAKE_BLOCK_SIZE / 2 ) * FRACUNIT, + (SNAKE_TOP_Y + SNAKE_BORDER_SIZE + snake->bonusy * SNAKE_BLOCK_SIZE + SNAKE_BLOCK_SIZE / 2 + 4) * FRACUNIT, + FRACUNIT / 2, + 0, + W_CachePatchName(snake_bonuspatches[snake->bonustype], PU_HUDGFX), + NULL + ); + // Snake if (!snake->gameover || snake->time % 8 < 8 / 2) // Blink if game over { @@ -1416,7 +1589,8 @@ static void CL_DrawSnake(void) case 1: patchname = "DL_SNAKEHEAD_L"; break; case 2: patchname = "DL_SNAKEHEAD_R"; break; case 3: patchname = "DL_SNAKEHEAD_T"; break; - default: patchname = "DL_SNAKEHEAD_B"; + case 4: patchname = "DL_SNAKEHEAD_B"; break; + default: patchname = "DL_SNAKEHEAD_M"; } } else // Body @@ -1442,8 +1616,8 @@ static void CL_DrawSnake(void) V_DrawFixedPatch( (SNAKE_LEFT_X + SNAKE_BORDER_SIZE + snake->snakex[i] * SNAKE_BLOCK_SIZE + SNAKE_BLOCK_SIZE / 2) * FRACUNIT, (SNAKE_TOP_Y + SNAKE_BORDER_SIZE + snake->snakey[i] * SNAKE_BLOCK_SIZE + SNAKE_BLOCK_SIZE / 2) * FRACUNIT, - FRACUNIT / 2, - 0, + i == 0 && dir == 0 ? FRACUNIT / 5 : FRACUNIT / 2, + snake->snakebonus == SNAKE_BONUS_GHOST ? V_TRANSLUCENT : 0, W_CachePatchName(patchname, PU_HUDGFX), NULL ); @@ -1452,6 +1626,18 @@ static void CL_DrawSnake(void) // Length V_DrawString(SNAKE_RIGHT_X + 4, SNAKE_TOP_Y, V_MONOSPACE, va("%u", snake->snakelength)); + + // Bonus + if (snake->snakebonus != SNAKE_BONUS_NONE + && (snake->snakebonustime >= 3 * TICRATE || snake->time % 4 < 4 / 2)) + V_DrawFixedPatch( + (SNAKE_RIGHT_X + 10) * FRACUNIT, + (SNAKE_TOP_Y + 24) * FRACUNIT, + FRACUNIT / 2, + 0, + W_CachePatchName(snake_bonuspatches[snake->snakebonus], PU_HUDGFX), + NULL + ); } // From 231a835bf66bc2988ad64662e228d76a4ceec5ce Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Mon, 27 Apr 2020 23:15:18 +0200 Subject: [PATCH 11/14] Minor adjustements in Snake minigame --- src/d_clisrv.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index a79d398fa..9c138a468 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1152,13 +1152,16 @@ static void CV_LoadPlayerNames(UINT8 **p) } #ifdef CLIENT_LOADINGSCREEN -#define SNAKE_SPEED 4 +#define SNAKE_SPEED 5 + #define SNAKE_NUM_BLOCKS_X 20 #define SNAKE_NUM_BLOCKS_Y 10 #define SNAKE_BLOCK_SIZE 12 +#define SNAKE_BORDER_SIZE 12 + #define SNAKE_MAP_WIDTH (SNAKE_NUM_BLOCKS_X * SNAKE_BLOCK_SIZE) #define SNAKE_MAP_HEIGHT (SNAKE_NUM_BLOCKS_Y * SNAKE_BLOCK_SIZE) -#define SNAKE_BORDER_SIZE 12 + #define SNAKE_LEFT_X ((BASEVIDWIDTH - SNAKE_MAP_WIDTH) / 2 - SNAKE_BORDER_SIZE) #define SNAKE_RIGHT_X (SNAKE_LEFT_X + SNAKE_MAP_WIDTH + SNAKE_BORDER_SIZE * 2 - 1) #define SNAKE_BOTTOM_Y (BASEVIDHEIGHT - 48) @@ -1226,7 +1229,7 @@ typedef struct snake_s static snake_t *snake = NULL; -static void CL_InitialiseSnake(void) +static void Snake_Initialise(void) { if (!snake) snake = malloc(sizeof(snake_t)); @@ -1276,7 +1279,7 @@ static void Snake_FindFreeSlot(UINT8 *x, UINT8 *y) } while (i < snake->snakelength); } -static void CL_HandleSnake(void) +static void Snake_Handle(void) { UINT8 x, y; UINT8 oldx, oldy; @@ -1285,7 +1288,7 @@ static void CL_HandleSnake(void) // Handle retry if (snake->gameover && (PLAYER1INPUTDOWN(gc_jump) || gamekeydown[KEY_ENTER])) { - CL_InitialiseSnake(); + Snake_Initialise(); snake->pausepressed = true; // Avoid accidental pause on respawn } @@ -1534,7 +1537,7 @@ static void CL_HandleSnake(void) } } -static void CL_DrawSnake(void) +static void Snake_Draw(void) { INT16 i; @@ -1703,7 +1706,7 @@ static inline void CL_DrawConnectionStatus(void) fileneeded_t *file = &fileneeded[lastfilenum]; char *filename = file->filename; - CL_DrawSnake(); + Snake_Draw(); Net_GetNetStat(); dldlength = (INT32)((file->currentsize/(double)file->totalsize) * 256); @@ -2467,7 +2470,7 @@ static boolean CL_ServerConnectionSearchTicker(boolean viams, tic_t *asksent) if (CL_SendRequestFile()) { cl_mode = CL_DOWNLOADFILES; - CL_InitialiseSnake(); + Snake_Initialise(); } } } @@ -2606,7 +2609,7 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic return false; } else if (cl_mode == CL_DOWNLOADFILES && snake) - CL_HandleSnake(); + Snake_Handle(); // why are these here? this is for servers, we're a client //if (key == 's' && server) From 752b48de3a92273742c07e7669626b65fd551780 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Tue, 28 Apr 2020 00:37:58 +0200 Subject: [PATCH 12/14] Update sound and closed captions in connection screen --- src/d_clisrv.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 9c138a468..dc4631d86 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2630,6 +2630,8 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic I_UpdateNoVsync(); // page flip or blit buffer if (moviemode) M_SaveFrame(); + S_UpdateSounds(); + S_UpdateClosedCaptions(); } #else CON_Drawer(); From dc55ab9ae212aaea6e3eea87c9fa5edd4f9f594b Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Sun, 10 May 2020 11:02:45 +0200 Subject: [PATCH 13/14] Use W_CachePatchLongName in Snake minigame --- src/d_clisrv.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 63bb653fb..1857df04f 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1566,7 +1566,7 @@ static void Snake_Draw(void) (SNAKE_TOP_Y + SNAKE_BORDER_SIZE + snake->appley * SNAKE_BLOCK_SIZE + SNAKE_BLOCK_SIZE / 2) * FRACUNIT, FRACUNIT / 4, 0, - W_CachePatchName("DL_APPLE", PU_HUDGFX), + W_CachePatchLongName("DL_APPLE", PU_HUDGFX), NULL ); @@ -1577,7 +1577,7 @@ static void Snake_Draw(void) (SNAKE_TOP_Y + SNAKE_BORDER_SIZE + snake->bonusy * SNAKE_BLOCK_SIZE + SNAKE_BLOCK_SIZE / 2 + 4) * FRACUNIT, FRACUNIT / 2, 0, - W_CachePatchName(snake_bonuspatches[snake->bonustype], PU_HUDGFX), + W_CachePatchLongName(snake_bonuspatches[snake->bonustype], PU_HUDGFX), NULL ); @@ -1625,7 +1625,7 @@ static void Snake_Draw(void) (SNAKE_TOP_Y + SNAKE_BORDER_SIZE + snake->snakey[i] * SNAKE_BLOCK_SIZE + SNAKE_BLOCK_SIZE / 2) * FRACUNIT, i == 0 && dir == 0 ? FRACUNIT / 5 : FRACUNIT / 2, snake->snakebonus == SNAKE_BONUS_GHOST ? V_TRANSLUCENT : 0, - W_CachePatchName(patchname, PU_HUDGFX), + W_CachePatchLongName(patchname, PU_HUDGFX), NULL ); } @@ -1642,7 +1642,7 @@ static void Snake_Draw(void) (SNAKE_TOP_Y + 24) * FRACUNIT, FRACUNIT / 2, 0, - W_CachePatchName(snake_bonuspatches[snake->snakebonus], PU_HUDGFX), + W_CachePatchLongName(snake_bonuspatches[snake->snakebonus], PU_HUDGFX), NULL ); } From e6ffedbce8a3620fa9aada0b892b01379ac6c440 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Mon, 1 Jun 2020 15:21:16 +0200 Subject: [PATCH 14/14] Fix food occasionally spawning inside the snake --- src/d_clisrv.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 1857df04f..646f77baa 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1268,7 +1268,7 @@ static UINT8 Snake_GetOppositeDir(UINT8 dir) return 12 + 5 - dir; } -static void Snake_FindFreeSlot(UINT8 *x, UINT8 *y) +static void Snake_FindFreeSlot(UINT8 *x, UINT8 *y, UINT8 headx, UINT8 heady) { UINT16 i; @@ -1280,7 +1280,7 @@ static void Snake_FindFreeSlot(UINT8 *x, UINT8 *y) for (i = 0; i < snake->snakelength; i++) if (*x == snake->snakex[i] && *y == snake->snakey[i]) break; - } while (i < snake->snakelength); + } while (i < snake->snakelength || (*x == headx && *y == heady)); } static void Snake_Handle(void) @@ -1420,7 +1420,7 @@ static void Snake_Handle(void) } // Spawn new apple - Snake_FindFreeSlot(&snake->applex, &snake->appley); + Snake_FindFreeSlot(&snake->applex, &snake->appley, x, y); // Spawn new bonus if (!(snake->snakelength % 5)) @@ -1431,7 +1431,7 @@ static void Snake_Handle(void) } while (snake->snakelength > SNAKE_NUM_BLOCKS_X * SNAKE_NUM_BLOCKS_Y * 3 / 4 && (snake->bonustype == SNAKE_BONUS_EGGMAN || snake->bonustype == SNAKE_BONUS_FAST || snake->bonustype == SNAKE_BONUS_REVERSE)); - Snake_FindFreeSlot(&snake->bonusx, &snake->bonusy); + Snake_FindFreeSlot(&snake->bonusx, &snake->bonusy, x, y); } S_StartSound(NULL, sfx_s3k6b);