From 9ac3fd202f35f217d5844f4626c97a5808afb1b3 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Tue, 16 Oct 2018 00:00:53 +0200 Subject: [PATCH 01/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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 165b6c2435b524c8f0194b742ef51e5877dc2f1d Mon Sep 17 00:00:00 2001 From: lachwright Date: Fri, 1 May 2020 08:26:23 +0800 Subject: [PATCH 13/36] Dashmode fixes: - Don't force the player's default normalspeed and jumpfactor while not in dashmode - Properly trim the fuse for followmobj ghosts spawned during dashmode - Add deliberate dashmode ghosts for Metal's jet fume --- src/g_game.c | 5 +++++ src/p_mobj.c | 8 ++++++++ src/p_user.c | 19 +++++++++++++++++-- 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 92d71fbae..1fb817bf8 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2377,6 +2377,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) fixed_t height; fixed_t spinheight; INT32 exiting; + tic_t dashmode; INT16 numboxes; INT16 totalring; UINT8 laps; @@ -2411,6 +2412,8 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) if (!(netgame || multiplayer)) pflags |= (players[player].pflags & (PF_GODMODE|PF_NOCLIP|PF_INVIS)); + dashmode = players[player].dashmode; + numboxes = players[player].numboxes; laps = players[player].laps; totalring = players[player].totalring; @@ -2509,6 +2512,8 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) p->spinheight = spinheight; p->exiting = exiting; + p->dashmode = dashmode; + p->numboxes = numboxes; p->laps = laps; p->totalring = totalring; diff --git a/src/p_mobj.c b/src/p_mobj.c index 29fe1a57c..45a6ffe5b 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11393,6 +11393,14 @@ void P_SpawnPlayer(INT32 playernum) p->realtime = leveltime; p->followitem = skins[p->skin].followitem; + // Make sure player's stats are reset if they were in dashmode! + if (p->dashmode) + { + p->dashmode = 0; + p->normalspeed = skins[p->skin].normalspeed; + p->jumpfactor = skins[p->skin].jumpfactor; + } + //awayview stuff p->awayviewmobj = NULL; p->awayviewtics = 0; diff --git a/src/p_user.c b/src/p_user.c index b2f40fe70..c7f772fb0 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -11485,6 +11485,13 @@ static void P_DoMetalJetFume(player_t *player, mobj_t *fume) fume->y = mo->y + P_ReturnThrustY(fume, angle, dist); fume->z = mo->z + ((mo->height - fume->height) >> 1); P_SetThingPosition(fume); + + // If dashmode is high enough, spawn a trail + if (!(fume->flags2 & MF2_DONTDRAW) && player->normalspeed >= skins[player->skin].normalspeed*2) + { + mobj_t *ghost = P_SpawnGhostMobj(fume); + ghost->tics = 4; + } } // @@ -12279,6 +12286,7 @@ void P_PlayerThink(player_t *player) // Dash mode - thanks be to VelocitOni if ((player->charflags & SF_DASHMODE) && !player->gotflag && !player->powers[pw_carry] && !player->exiting && !(maptol & TOL_NIGHTS) && !metalrecording) // woo, dashmode! no nights tho. { + tic_t prevdashmode = dashmode; boolean totallyradical = player->speed >= FixedMul(player->runspeed, player->mo->scale); boolean floating = (player->secondjump == 1); @@ -12303,8 +12311,11 @@ void P_PlayerThink(player_t *player) if (dashmode < DASHMODE_THRESHOLD) // Exits Dash Mode if you drop below speed/dash counter tics. Not in the above block so it doesn't keep disabling in midair. { - player->normalspeed = skins[player->skin].normalspeed; // Reset to default if not capable of entering dash mode. - player->jumpfactor = skins[player->skin].jumpfactor; + if (prevdashmode >= DASHMODE_THRESHOLD) + { + player->normalspeed = skins[player->skin].normalspeed; // Reset to default if not capable of entering dash mode. + player->jumpfactor = skins[player->skin].jumpfactor; + } } else if (P_IsObjectOnGround(player->mo)) // Activate dash mode if we're on the ground. { @@ -12319,6 +12330,10 @@ void P_PlayerThink(player_t *player) { mobj_t *ghost = P_SpawnGhostMobj(player->mo); // Spawns afterimages ghost->fuse = 2; // Makes the images fade quickly + if (ghost->tracer) + { + ghost->tracer->fuse = ghost->fuse; + } } } else if (dashmode) From dc55ab9ae212aaea6e3eea87c9fa5edd4f9f594b Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Sun, 10 May 2020 11:02:45 +0200 Subject: [PATCH 14/36] 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 8b801921a464eebfba97fb7dd9d3421d17f446fe Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Mon, 18 May 2020 11:29:56 -0500 Subject: [PATCH 15/36] Deprecate FixedRem. It's about time! --- src/lua_mathlib.c | 3 ++- src/m_fixed.h | 12 ------------ src/tables.c | 2 +- 3 files changed, 3 insertions(+), 14 deletions(-) diff --git a/src/lua_mathlib.c b/src/lua_mathlib.c index 215903278..794f90f1f 100644 --- a/src/lua_mathlib.c +++ b/src/lua_mathlib.c @@ -113,7 +113,8 @@ static int lib_fixeddiv(lua_State *L) static int lib_fixedrem(lua_State *L) { - lua_pushfixed(L, FixedRem(luaL_checkfixed(L, 1), luaL_checkfixed(L, 2))); + LUA_Deprecated(L, "FixedRem(a, b)", "a % b"); + lua_pushfixed(L, luaL_checkfixed(L, 1) % luaL_checkfixed(L, 2)); return 1; } diff --git a/src/m_fixed.h b/src/m_fixed.h index cc54c1aea..289ca442a 100644 --- a/src/m_fixed.h +++ b/src/m_fixed.h @@ -204,18 +204,6 @@ FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FixedDiv(fixed_t a, fixed_t b) return FixedDiv2(a, b); } -/** \brief The FixedRem function - - \param x fixed_t number - \param y fixed_t number - - \return remainder of dividing x by y -*/ -FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FixedRem(fixed_t x, fixed_t y) -{ - return x % y; -} - /** \brief The FixedSqrt function \param x fixed_t number diff --git a/src/tables.c b/src/tables.c index 00424db22..70a1ecd0a 100644 --- a/src/tables.c +++ b/src/tables.c @@ -72,7 +72,7 @@ static FUNCMATH angle_t AngleAdj(const fixed_t fa, const fixed_t wf, const angle_t adj = 0x77; const boolean fan = fa < 0; const fixed_t sl = FixedDiv(fa, wf*2); - const fixed_t lb = FixedRem(fa, wf*2); + const fixed_t lb = fa % (wf*2); const fixed_t lo = (wf*2)-lb; if (ra == 0) From 67eef5a37f96fd68a25493f72b02195f8cb8f53f Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Thu, 28 May 2020 11:03:35 +0200 Subject: [PATCH 16/36] Fix potential desynch when a player spawns --- src/d_clisrv.c | 49 +++------------ src/d_clisrv.h | 4 +- src/d_player.h | 3 + src/g_demo.c | 2 +- src/g_game.c | 53 ++++++++++++---- src/g_game.h | 1 + src/lua_mobjlib.c | 5 +- src/m_cheat.c | 11 +++- src/p_inter.c | 10 +--- src/p_local.h | 4 ++ src/p_map.c | 21 +------ src/p_mobj.c | 6 +- src/p_polyobj.c | 5 +- src/p_saveg.c | 9 ++- src/p_spec.c | 31 +++------- src/p_telept.c | 10 +--- src/p_tick.c | 4 +- src/p_user.c | 150 ++++++++++++++++++++-------------------------- 18 files changed, 158 insertions(+), 220 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index ed0b8e528..c01ca35db 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -522,6 +522,9 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i) rsp->pflags = (UINT32)LONG(players[i].pflags); //pflags_t rsp->panim = (UINT8)players[i].panim; //panim_t + rsp->angleturn = (INT16)SHORT(players[i].angleturn); + rsp->oldrelangleturn = (INT16)SHORT(players[i].oldrelangleturn); + rsp->aiming = (angle_t)LONG(players[i].aiming); rsp->currentweapon = LONG(players[i].currentweapon); rsp->ringweapons = LONG(players[i].ringweapons); @@ -663,6 +666,9 @@ static void resynch_read_player(resynch_pak *rsp) players[i].pflags = (UINT32)LONG(rsp->pflags); //pflags_t players[i].panim = (UINT8)rsp->panim; //panim_t + players[i].angleturn = (INT16)SHORT(rsp->angleturn); + players[i].oldrelangleturn = (INT16)SHORT(rsp->oldrelangleturn); + players[i].aiming = (angle_t)LONG(rsp->aiming); players[i].currentweapon = LONG(rsp->currentweapon); players[i].ringweapons = LONG(rsp->ringweapons); @@ -3346,6 +3352,7 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum) displayplayer = newplayernum; secondarydisplayplayer = newplayernum; DEBFILE("spawning me\n"); + ticcmd_oldangleturn[0] = newplayer->oldrelangleturn; } else { @@ -3353,7 +3360,9 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum) DEBFILE("spawning my brother\n"); if (botingame) newplayer->bot = 1; + ticcmd_oldangleturn[1] = newplayer->oldrelangleturn; } + P_ForceLocalAngle(newplayer, (angle_t)(newplayer->angleturn << 16)); D_SendPlayerConfig(); addedtogame = true; @@ -3361,11 +3370,6 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum) { if (newplayer->mo) { - if (!splitscreenplayer) - localangle = newplayer->mo->angle; - else - localangle2 = newplayer->mo->angle; - newplayer->viewheight = 41*newplayer->height/48; if (newplayer->mo->eflags & MFE_VERTICALFLIP) @@ -4721,41 +4725,6 @@ static void Local_Maketic(INT32 realtics) localcmds2.angleturn |= TICCMD_RECEIVED; } -// This function is utter bullshit and is responsible for -// the random desynch that happens when a player spawns. -// This is because ticcmds are resent to clients if a packet -// was dropped, and thus modifying them can lead to several -// clients having their ticcmds set to different values. -void SV_SpawnPlayer(INT32 playernum, INT32 x, INT32 y, angle_t angle) -{ - tic_t tic; - UINT8 numadjust = 0; - - (void)x; - (void)y; - - // Revisionist history: adjust the angles in the ticcmds received - // for this player, because they actually preceded the player - // spawning, but will be applied afterwards. - - for (tic = server ? maketic : (neededtic - 1); tic >= gametic; tic--) - { - if (numadjust++ == BACKUPTICS) - { - DEBFILE(va("SV_SpawnPlayer: All netcmds for player %d adjusted!\n", playernum)); - // We already adjusted them all, waste of time doing the same thing over and over - // This shouldn't happen normally though, either gametic was 0 (which is handled now anyway) - // or maketic >= gametic + BACKUPTICS - // -- Monster Iestyn 16/01/18 - break; - } - netcmds[tic%BACKUPTICS][playernum].angleturn = (INT16)((angle>>16) | TICCMD_RECEIVED); - - if (!tic) // failsafe for gametic == 0 -- Monster Iestyn 16/01/18 - break; - } -} - // create missed tic static void SV_Maketic(void) { diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 463240a2a..25274e97c 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -171,6 +171,9 @@ typedef struct UINT32 pflags; // pflags_t UINT8 panim; // panim_t + INT16 angleturn; + INT16 oldrelangleturn; + angle_t aiming; INT32 currentweapon; INT32 ringweapons; @@ -534,7 +537,6 @@ void NetUpdate(void); void SV_StartSinglePlayerServer(void); boolean SV_SpawnServer(void); -void SV_SpawnPlayer(INT32 playernum, INT32 x, INT32 y, angle_t angle); void SV_StopServer(void); void SV_ResetServer(void); void CL_AddSplitscreenPlayer(void); diff --git a/src/d_player.h b/src/d_player.h index e5c7e7298..745f7b42f 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -332,6 +332,9 @@ typedef struct player_s angle_t viewrollangle; + INT16 angleturn; + INT16 oldrelangleturn; + // Mouse aiming, where the guy is looking at! // It is updated with cmd->aiming. angle_t aiming; diff --git a/src/g_demo.c b/src/g_demo.c index a901e8dea..b070cbd51 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -165,7 +165,6 @@ void G_LoadMetal(UINT8 **buffer) void G_ReadDemoTiccmd(ticcmd_t *cmd, INT32 playernum) { UINT8 ziptic; - (void)playernum; if (!demo_p || !demo_start) return; @@ -183,6 +182,7 @@ void G_ReadDemoTiccmd(ticcmd_t *cmd, INT32 playernum) oldcmd.aiming = READINT16(demo_p); G_CopyTiccmd(cmd, &oldcmd, 1); + players[playernum].angleturn = cmd->angleturn; if (!(demoflags & DF_GHOST) && *demo_p == DEMOMARKER) { diff --git a/src/g_game.c b/src/g_game.c index 5bcf9f580..2560c2b32 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1065,6 +1065,7 @@ static fixed_t forwardmove[2] = {25<>16, 50<>16}; static fixed_t sidemove[2] = {25<>16, 50<>16}; // faster! static fixed_t angleturn[3] = {640, 1280, 320}; // + slow turn +INT16 ticcmd_oldangleturn[2]; boolean ticcmd_centerviewdown[2]; // For simple controls, lock the camera behind the player mobj_t *ticcmd_ztargetfocus[2]; // Locking onto an object? void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) @@ -1140,7 +1141,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) if (paused || P_AutoPause() || (gamestate == GS_LEVEL && (player->playerstate == PST_REBORN || ((gametyperules & GTR_TAG) && (leveltime < hidetime * TICRATE) && (player->pflags & PF_TAGIT))))) {//@TODO splitscreen player - cmd->angleturn = (INT16)(*myangle >> 16); + cmd->angleturn = ticcmd_oldangleturn[forplayer]; cmd->aiming = G_ClipAimingPitch(myaiming); return; } @@ -1361,7 +1362,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) if (controlstyle == CS_SIMPLE && !ticcmd_centerviewdown[forplayer] && !G_RingSlingerGametype()) { CV_SetValue(&cv_directionchar[forplayer], 2); - *myangle = player->mo->angle; + cmd->angleturn = (INT16)((player->mo->angle - *myangle) >> 16); *myaiming = 0; if (cv_cam_lockonboss[forplayer].value) @@ -1430,7 +1431,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) else if (anglediff < -maxturn) anglediff = -maxturn; - *myangle += anglediff; + cmd->angleturn = (INT16)(cmd->angleturn + (anglediff >> 16)); } } } @@ -1567,19 +1568,23 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) B_HandleFlightIndicator(player); } else if (player->bot == 2) - *myangle = localangle; // Fix offset angle for P2-controlled Tailsbot when P2's controls are set to non-Legacy + // Fix offset angle for P2-controlled Tailsbot when P2's controls are set to non-Legacy + cmd->angleturn = (INT16)((localangle - *myangle) >> 16); + + *myangle += (cmd->angleturn<<16); if (controlstyle == CS_LMAOGALOG) { + angle_t angle; + if (player->awayviewtics) - cmd->angleturn = (INT16)(player->awayviewmobj->angle >> 16); + angle = player->awayviewmobj->angle; else - cmd->angleturn = (INT16)(thiscam->angle >> 16); + angle = thiscam->angle; + + cmd->angleturn = (INT16)((angle - (ticcmd_oldangleturn[forplayer] << 16)) >> 16); } else { - *myangle += (cmd->angleturn<<16); - cmd->angleturn = (INT16)(*myangle >> 16); - // Adjust camera angle by player input if (controlstyle == CS_SIMPLE && !forcestrafe && thiscam->chase && !turnheld[forplayer] && !ticcmd_centerviewdown[forplayer] && !player->climbing && player->powers[pw_carry] != CR_MINECART) { @@ -1589,13 +1594,17 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) { fixed_t sine = FINESINE((R_PointToAngle2(0, 0, player->rmomx, player->rmomy) - localangle)>>ANGLETOFINESHIFT); fixed_t factor; + INT16 camadjust; if ((sine > 0) == (cmd->sidemove > 0)) sine = 0; // Prevent jerking right when braking from going left, or vice versa factor = min(40, FixedMul(player->speed, abs(sine))*2 / FRACUNIT); - *myangle -= cmd->sidemove * factor * camadjustfactor; + camadjust = (cmd->sidemove * factor * camadjustfactor) >> 16; + + *myangle -= camadjust << 16; + cmd->angleturn = (INT16)(cmd->angleturn - camadjust); } if (ticcmd_centerviewdown[forplayer] && (cv_cam_lockedinput[forplayer].value || (player->pflags & PF_STARTDASH))) @@ -1632,9 +1641,10 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) { angle_t controlangle; INT32 anglediff; + INT16 camadjust; if ((cmd->forwardmove || cmd->sidemove) && !(player->pflags & PF_SPINNING)) - controlangle = (cmd->angleturn<<16) + R_PointToAngle2(0, 0, cmd->forwardmove << FRACBITS, -cmd->sidemove << FRACBITS); + controlangle = *myangle + R_PointToAngle2(0, 0, cmd->forwardmove << FRACBITS, -cmd->sidemove << FRACBITS); else controlangle = player->drawangle + drawangleoffset; @@ -1651,7 +1661,10 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) anglediff = FixedMul(anglediff, sine); } - *myangle += FixedMul(anglediff, camadjustfactor); + camadjust = FixedMul(anglediff, camadjustfactor) >> 16; + + *myangle += camadjust << 16; + cmd->angleturn = (INT16)(cmd->angleturn + camadjust); } } } @@ -1665,6 +1678,9 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) LUAh_ViewpointSwitch(player, &players[consoleplayer], true); displayplayer = consoleplayer; } + + cmd->angleturn = (INT16)(cmd->angleturn + ticcmd_oldangleturn[forplayer]); + ticcmd_oldangleturn[forplayer] = cmd->angleturn; } ticcmd_t *G_CopyTiccmd(ticcmd_t* dest, const ticcmd_t* src, const size_t n) @@ -2205,11 +2221,16 @@ void G_Ticker(boolean run) buf = gametic % BACKUPTICS; - // read/write demo and check turbo cheat for (i = 0; i < MAXPLAYERS; i++) { if (playeringame[i]) + { G_CopyTiccmd(&players[i].cmd, &netcmds[buf][i], 1); + + players[i].angleturn += players[i].cmd.angleturn - players[i].oldrelangleturn; + players[i].oldrelangleturn = players[i].cmd.angleturn; + players[i].cmd.angleturn = players[i].angleturn; + } } // do main actions @@ -2392,6 +2413,8 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) SINT8 pity; INT16 rings; INT16 spheres; + INT16 playerangleturn; + INT16 oldrelangleturn; score = players[player].score; lives = players[player].lives; @@ -2403,6 +2426,8 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) spectator = players[player].spectator; outofcoop = players[player].outofcoop; pflags = (players[player].pflags & (PF_FLIPCAM|PF_ANALOGMODE|PF_DIRECTIONCHAR|PF_AUTOBRAKE|PF_TAGIT|PF_GAMETYPEOVER)); + playerangleturn = players[player].angleturn; + oldrelangleturn = players[player].oldrelangleturn; if (!betweenmaps) pflags |= (players[player].pflags & PF_FINISHED); @@ -2474,6 +2499,8 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) p->quittime = quittime; p->spectator = spectator; p->outofcoop = outofcoop; + p->angleturn = playerangleturn; + p->oldrelangleturn = oldrelangleturn; // save player config truth reborn p->skincolor = skincolor; diff --git a/src/g_game.h b/src/g_game.h index df0c9392e..21fa682b7 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -93,6 +93,7 @@ typedef enum // build an internal map name MAPxx from map number const char *G_BuildMapName(INT32 map); +extern INT16 ticcmd_oldangleturn[2]; extern boolean ticcmd_centerviewdown[2]; // For simple controls, lock the camera behind the player extern mobj_t *ticcmd_ztargetfocus[2]; // Locking onto an object? void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer); diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index 81729b788..62b5d736f 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -449,10 +449,7 @@ static int mobj_set(lua_State *L) return UNIMPLEMENTED; case mobj_angle: mo->angle = luaL_checkangle(L, 3); - if (mo->player == &players[consoleplayer]) - localangle = mo->angle; - else if (mo->player == &players[secondarydisplayplayer]) - localangle2 = mo->angle; + P_SetPlayerAngle(mo->player, mo->angle); break; case mobj_rollangle: mo->rollangle = luaL_checkangle(L, 3); diff --git a/src/m_cheat.c b/src/m_cheat.c index 156c5db16..98e309a55 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -555,7 +555,8 @@ void Command_Teleport_f(void) p->mo->flags2 &= ~MF2_OBJECTFLIP; } - localangle = p->mo->angle = p->drawangle = FixedAngle(mt->angle<mo->angle = p->drawangle = FixedAngle(mt->angle<mo->angle); } else // scan the thinkers to find starposts... { @@ -619,7 +620,8 @@ void Command_Teleport_f(void) p->mo->flags2 &= ~MF2_OBJECTFLIP; } - localangle = p->mo->angle = p->drawangle = mo2->angle; + p->mo->angle = p->drawangle = mo2->angle; + P_SetPlayerAngle(p, p->mo->angle); } CONS_Printf(M_GetText("Teleporting to checkpoint %d, %d...\n"), starpostnum, starpostpath); @@ -673,7 +675,10 @@ void Command_Teleport_f(void) i = COM_CheckParm("-ang"); if (i) - localangle = p->drawangle = p->mo->angle = FixedAngle(atoi(COM_Argv(i + 1))<drawangle = p->mo->angle = FixedAngle(atoi(COM_Argv(i + 1))<mo->angle); + } i = COM_CheckParm("-aim"); if (i) diff --git a/src/p_inter.c b/src/p_inter.c index 3d2c5e45e..052ecc0da 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1143,10 +1143,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) toucher->angle = special->angle; - if (player == &players[consoleplayer]) - localangle = toucher->angle; - else if (player == &players[secondarydisplayplayer]) - localangle2 = toucher->angle; + P_SetPlayerAngle(player, toucher->angle); P_ResetPlayer(player); @@ -1564,10 +1561,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) #if 0 // camera redirection - deemed unnecessary toucher->angle = special->angle; - if (player == &players[consoleplayer]) - localangle = toucher->angle; - else if (player == &players[secondarydisplayplayer]) - localangle2 = toucher->angle; + P_SetPlayerAngle(player, toucher->angle); #endif S_StartSound(toucher, special->info->attacksound); // home run diff --git a/src/p_local.h b/src/p_local.h index becb045f7..e89343ca8 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -138,6 +138,10 @@ void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor); void P_ResetPlayer(player_t *player); boolean P_PlayerCanDamage(player_t *player, mobj_t *thing); boolean P_IsLocalPlayer(player_t *player); +void P_SetPlayerAngle(player_t *player, angle_t angle); +angle_t P_GetLocalAngle(player_t *player); +void P_SetLocalAngle(player_t *player, angle_t angle); +void P_ForceLocalAngle(player_t *player, angle_t angle); boolean P_IsObjectInGoop(mobj_t *mo); boolean P_IsObjectOnGround(mobj_t *mo); diff --git a/src/p_map.c b/src/p_map.c index 6e4992473..e3038e87f 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -372,12 +372,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) object->angle = object->player->drawangle = spring->angle; if (!demoplayback || P_ControlStyle(object->player) == CS_LMAOGALOG) - { - if (object->player == &players[consoleplayer]) - localangle = spring->angle; - else if (object->player == &players[secondarydisplayplayer]) - localangle2 = spring->angle; - } + P_SetPlayerAngle(object->player, spring->angle); } if (object->player->pflags & PF_GLIDING) @@ -1310,12 +1305,7 @@ static boolean PIT_CheckThing(mobj_t *thing) thing->angle = tmthing->angle; if (!demoplayback || P_ControlStyle(thing->player) == CS_LMAOGALOG) - { - if (thing->player == &players[consoleplayer]) - localangle = thing->angle; - else if (thing->player == &players[secondarydisplayplayer]) - localangle2 = thing->angle; - } + P_SetPlayerAngle(thing->player, thing->angle); return true; } @@ -3409,12 +3399,7 @@ isblocking: { slidemo->angle = climbangle; /*if (!demoplayback || P_ControlStyle(slidemo->player) == CS_LMAOGALOG) - { - if (slidemo->player == &players[consoleplayer]) - localangle = slidemo->angle; - else if (slidemo->player == &players[secondarydisplayplayer]) - localangle2 = slidemo->angle; - }*/ + P_SetPlayerAngle(slidemo->player, slidemo->angle);*/ if (!slidemo->player->climbing) { diff --git a/src/p_mobj.c b/src/p_mobj.c index 4124c47a9..3d50b0439 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11388,10 +11388,7 @@ void P_AfterPlayerSpawn(INT32 playernum) player_t *p = &players[playernum]; mobj_t *mobj = p->mo; - if (playernum == consoleplayer) - localangle = mobj->angle; - else if (playernum == secondarydisplayplayer) - localangle2 = mobj->angle; + P_SetPlayerAngle(p, mobj->angle); p->viewheight = 41*p->height/48; @@ -11408,7 +11405,6 @@ void P_AfterPlayerSpawn(INT32 playernum) HU_Start(); } - SV_SpawnPlayer(playernum, mobj->x, mobj->y, mobj->angle); p->drawangle = mobj->angle; if (camera.chase) diff --git a/src/p_polyobj.c b/src/p_polyobj.c index 3b6195285..ca21a36cc 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -1156,10 +1156,7 @@ static void Polyobj_rotateThings(polyobj_t *po, vertex_t origin, angle_t delta, if (turnthings == 2 || (turnthings == 1 && !mo->player)) { mo->angle += delta; - if (mo->player == &players[consoleplayer]) - localangle += delta; - else if (mo->player == &players[secondarydisplayplayer]) - localangle2 += delta; + P_SetPlayerAngle(mo->player, (angle_t)(mo->player->angleturn << 16) + delta); } } } diff --git a/src/p_saveg.c b/src/p_saveg.c index bec64ed35..a4cdd5148 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -103,6 +103,8 @@ static void P_NetArchivePlayers(void) // no longer send ticcmds, player name, skin, or color + WRITEINT16(save_p, players[i].angleturn); + WRITEINT16(save_p, players[i].oldrelangleturn); WRITEANGLE(save_p, players[i].aiming); WRITEANGLE(save_p, players[i].drawangle); WRITEANGLE(save_p, players[i].viewrollangle); @@ -311,6 +313,8 @@ static void P_NetUnArchivePlayers(void) // sending player names, skin and color should not be necessary at all! // (that data is handled in the server config now) + players[i].angleturn = READINT16(save_p); + players[i].oldrelangleturn = READINT16(save_p); players[i].aiming = READANGLE(save_p); players[i].drawangle = READANGLE(save_p); players[i].viewrollangle = READANGLE(save_p); @@ -2547,11 +2551,6 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) i = READUINT8(save_p); mobj->player = &players[i]; mobj->player->mo = mobj; - // added for angle prediction - if (consoleplayer == i) - localangle = mobj->angle; - if (secondarydisplayplayer == i) - localangle2 = mobj->angle; } if (diff & MD_MOVEDIR) mobj->movedir = READANGLE(save_p); diff --git a/src/p_spec.c b/src/p_spec.c index d45a33c47..85546a97a 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4602,12 +4602,7 @@ DoneSection2: player->mo->angle = player->drawangle = lineangle; if (!demoplayback || P_ControlStyle(player) == CS_LMAOGALOG) - { - if (player == &players[consoleplayer]) - localangle = player->mo->angle; - else if (player == &players[secondarydisplayplayer]) - localangle2 = player->mo->angle; - } + P_SetPlayerAngle(player, player->mo->angle); if (!(lines[i].flags & ML_EFFECT4)) { @@ -8865,24 +8860,12 @@ void T_Pusher(pusher_t *p) if (!demoplayback || P_ControlStyle(thing->player) == CS_LMAOGALOG) { - if (thing->player == &players[consoleplayer]) - { - if (thing->angle - localangle > ANGLE_180) - localangle -= (localangle - thing->angle) / 8; - else - localangle += (thing->angle - localangle) / 8; - } - else if (thing->player == &players[secondarydisplayplayer]) - { - if (thing->angle - localangle2 > ANGLE_180) - localangle2 -= (localangle2 - thing->angle) / 8; - else - localangle2 += (thing->angle - localangle2) / 8; - } - /*if (thing->player == &players[consoleplayer]) - localangle = thing->angle; - else if (thing->player == &players[secondarydisplayplayer]) - localangle2 = thing->angle;*/ + angle_t angle = thing->player->angleturn << 16; + if (thing->angle - angle > ANGLE_180) + P_SetPlayerAngle(thing->player, angle - (angle - thing->angle) / 8); + else + P_SetPlayerAngle(thing->player, angle + (thing->angle - angle) / 8); + //P_SetPlayerAngle(thing->player, thing->angle); } } diff --git a/src/p_telept.c b/src/p_telept.c index 600d40c88..f6feddf4b 100644 --- a/src/p_telept.c +++ b/src/p_telept.c @@ -63,10 +63,7 @@ void P_MixUp(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, thing->reactiontime = TICRATE/2; // don't move for about half a second // absolute angle position - if (thing == players[consoleplayer].mo) - localangle = angle; - if (thing == players[secondarydisplayplayer].mo) - localangle2 = angle; + P_SetPlayerAngle(thing->player, angle); // move chasecam at new player location if (splitscreen && camera2.chase @@ -165,10 +162,7 @@ boolean P_Teleport(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle thing->player->drawangle += (angle - thing->angle); // absolute angle position - if (thing->player == &players[consoleplayer]) - localangle = angle; - if (thing->player == &players[secondarydisplayplayer]) - localangle2 = angle; + P_SetPlayerAngle(thing->player, angle); // move chasecam at new player location if (splitscreen && camera2.chase && thing->player == &players[secondarydisplayplayer]) diff --git a/src/p_tick.c b/src/p_tick.c index 7ea6edb2d..55b545856 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -770,7 +770,9 @@ void P_PreTicker(INT32 frames) memcpy(&temptic, &players[i].cmd, sizeof(ticcmd_t)); memset(&players[i].cmd, 0, sizeof(ticcmd_t)); // correct angle on spawn... - players[i].cmd.angleturn = temptic.angleturn; + players[i].angleturn += temptic.angleturn - players[i].oldrelangleturn; + players[i].oldrelangleturn = temptic.angleturn; + players[i].cmd.angleturn = players[i].angleturn; P_PlayerThink(&players[i]); diff --git a/src/p_user.c b/src/p_user.c index ca1001f57..c22e29397 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -3557,22 +3557,11 @@ static void P_DoClimbing(player_t *player) #define CLIMBCONEMAX FixedAngle(90*FRACUNIT) if (!demoplayback || P_ControlStyle(player) == CS_LMAOGALOG) { - if (player == &players[consoleplayer]) - { - angle_t angdiff = localangle - player->mo->angle; - if (angdiff < ANGLE_180 && angdiff > CLIMBCONEMAX) - localangle = player->mo->angle + CLIMBCONEMAX; - else if (angdiff > ANGLE_180 && angdiff < InvAngle(CLIMBCONEMAX)) - localangle = player->mo->angle - CLIMBCONEMAX; - } - else if (player == &players[secondarydisplayplayer]) - { - angle_t angdiff = localangle2 - player->mo->angle; - if (angdiff < ANGLE_180 && angdiff > CLIMBCONEMAX) - localangle2 = player->mo->angle + CLIMBCONEMAX; - else if (angdiff > ANGLE_180 && angdiff < InvAngle(CLIMBCONEMAX)) - localangle2 = player->mo->angle - CLIMBCONEMAX; - } + angle_t angdiff = P_GetLocalAngle(player) - player->mo->angle; + if (angdiff < ANGLE_180 && angdiff > CLIMBCONEMAX) + P_SetLocalAngle(player, player->mo->angle + CLIMBCONEMAX); + else if (angdiff > ANGLE_180 && angdiff < InvAngle(CLIMBCONEMAX)) + P_SetLocalAngle(player, player->mo->angle - CLIMBCONEMAX); } if (player->climbing == 0) @@ -4358,12 +4347,7 @@ void P_DoJump(player_t *player, boolean soundandstate) player->drawangle = player->mo->angle = player->mo->angle - ANGLE_180; // Turn around from the wall you were climbing. if (!demoplayback || P_ControlStyle(player) == CS_LMAOGALOG) - { - if (player == &players[consoleplayer]) - localangle = player->mo->angle; // Adjust the local control angle. - else if (player == &players[secondarydisplayplayer]) - localangle2 = player->mo->angle; - } + P_SetPlayerAngle(player, player->mo->angle); player->climbing = 0; // Stop climbing, duh! P_InstaThrust(player->mo, player->mo->angle, FixedMul(6*FRACUNIT, player->mo->scale)); // Jump off the wall. @@ -4686,12 +4670,7 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) player->mo->angle = R_PointToAngle2(player->mo->x, player->mo->y, lockon->x, lockon->y); bullet = P_SpawnPointMissile(player->mo, lockon->x, lockon->y, zpos(lockon), player->revitem, player->mo->x, player->mo->y, zpos(player->mo)); if (!demoplayback || P_ControlStyle(player) == CS_LMAOGALOG) - { - if (player == &players[consoleplayer]) - localangle = player->mo->angle; - else if (player == &players[secondarydisplayplayer]) - localangle2 = player->mo->angle; - } + P_SetPlayerAngle(player, player->mo->angle); } else { @@ -5311,9 +5290,9 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) /*if (!demoplayback) { if (player == &players[consoleplayer] && cv_cam_turnfacingability[0].value > 0 && !(PLAYER1INPUTDOWN(gc_turnleft) || PLAYER1INPUTDOWN(gc_turnright))) - localangle = player->mo->angle; + P_SetPlayerAngle(player, player->mo->angle);; else if (player == &players[secondarydisplayplayer] && cv_cam_turnfacingability[1].value > 0 && !(PLAYER2INPUTDOWN(gc_turnleft) || PLAYER2INPUTDOWN(gc_turnright))) - localangle2 = player->mo->angle; + P_SetPlayerAngle(player, player->mo->angle); }*/ } break; @@ -5718,10 +5697,7 @@ static void P_2dMovement(player_t *player) player->mo->angle = ANGLE_180; } - if (player == &players[consoleplayer]) - localangle = player->mo->angle; - else if (player == &players[secondarydisplayplayer]) - localangle2 = player->mo->angle; + P_SetPlayerAngle(player, player->mo->angle); if (player->pflags & PF_GLIDING) movepushangle = player->mo->angle; @@ -7558,10 +7534,7 @@ static void P_NiGHTSMovement(player_t *player) else player->mo->rollangle = rollangle; - if (player == &players[consoleplayer]) - localangle = player->mo->angle; - else if (player == &players[secondarydisplayplayer]) - localangle2 = player->mo->angle; + P_SetPlayerAngle(player, player->mo->angle); // Check for crushing in our new location if ((player->mo->ceilingz - player->mo->floorz < player->mo->height) @@ -8510,10 +8483,7 @@ static void P_MovePlayer(player_t *player) player->mo->angle = R_PointToAngle2(0, 0, player->rmomx, player->rmomy); // Update the local angle control. - if (player == &players[consoleplayer]) - localangle = player->mo->angle; - else if (player == &players[secondarydisplayplayer]) - localangle2 = player->mo->angle; + P_SetPlayerAngle(player, player->mo->angle); } if (player->climbing == 1) @@ -8789,11 +8759,7 @@ static void P_DoZoomTube(player_t *player) if (player->mo->tracer) { player->mo->angle = R_PointToAngle2(player->mo->x, player->mo->y, player->mo->tracer->x, player->mo->tracer->y); - - if (player == &players[consoleplayer]) - localangle = player->mo->angle; - else if (player == &players[secondarydisplayplayer]) - localangle2 = player->mo->angle; + P_SetPlayerAngle(player, player->mo->angle); } } @@ -9250,12 +9216,7 @@ boolean P_HomingAttack(mobj_t *source, mobj_t *enemy) // Home in on your target { source->player->drawangle = source->angle; if (!demoplayback || P_ControlStyle(source->player) == CS_LMAOGALOG) - { - if (source->player == &players[consoleplayer]) - localangle = source->angle; - else if (source->player == &players[secondarydisplayplayer]) - localangle2 = source->angle; - } + P_SetPlayerAngle(source->player, source->angle); } // change slope @@ -9696,7 +9657,7 @@ void P_ResetCamera(player_t *player, camera_t *thiscam) if ((thiscam == &camera && G_ControlStyle(1) == CS_SIMPLE) || (thiscam == &camera2 && G_ControlStyle(2) == CS_SIMPLE)) { - thiscam->angle = (thiscam == &camera) ? localangle : localangle2; + thiscam->angle = P_GetLocalAngle(player); thiscam->aiming = (thiscam == &camera) ? localaiming : localaiming2; } else if (!(thiscam == &camera && (cv_cam_still.value || cv_analog[0].value)) @@ -9897,9 +9858,9 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall if (player == &players[consoleplayer]) { if (focusangle >= localangle) - localangle += abs((signed)(focusangle - localangle))>>5; + P_ForceLocalAngle(player, localangle + (abs((signed)(focusangle - localangle))>>5)); else - localangle -= abs((signed)(focusangle - localangle))>>5; + P_ForceLocalAngle(player, localangle - (abs((signed)(focusangle - localangle))>>5)); } } else @@ -10873,21 +10834,13 @@ static void P_MinecartThink(player_t *player) if (angdiff + minecart->angle != player->mo->angle && (!demoplayback || P_ControlStyle(player) == CS_LMAOGALOG)) { - angle_t *ang = NULL; + angdiff = P_GetLocalAngle(player) - minecart->angle; + if (angdiff < ANGLE_180 && angdiff > MINECARTCONEMAX) + P_SetLocalAngle(player, minecart->angle + MINECARTCONEMAX); + else if (angdiff > ANGLE_180 && angdiff < InvAngle(MINECARTCONEMAX)) + P_SetLocalAngle(player, minecart->angle - MINECARTCONEMAX); - if (player == &players[consoleplayer]) - ang = &localangle; - else if (player == &players[secondarydisplayplayer]) - ang = &localangle2; - if (ang) - { - angdiff = *ang - minecart->angle; - if (angdiff < ANGLE_180 && angdiff > MINECARTCONEMAX) - *ang = minecart->angle + MINECARTCONEMAX; - else if (angdiff > ANGLE_180 && angdiff < InvAngle(MINECARTCONEMAX)) - *ang = minecart->angle - MINECARTCONEMAX; - } } } @@ -10964,10 +10917,7 @@ static void P_MinecartThink(player_t *player) if (angdiff && (!demoplayback || P_ControlStyle(player) == CS_LMAOGALOG)) // maintain relative angle on turns { player->mo->angle += angdiff; - if (player == &players[consoleplayer]) - localangle += angdiff; - else if (player == &players[secondarydisplayplayer]) - localangle2 += angdiff; + P_SetPlayerAngle(player, (angle_t)(player->angleturn << 16) + angdiff); } // Sideways detection @@ -12520,12 +12470,7 @@ void P_PlayerAfterThink(player_t *player) player->mo->angle = tails->angle; if (!demoplayback || P_ControlStyle(player) == CS_LMAOGALOG) - { - if (player == &players[consoleplayer]) - localangle = player->mo->angle; - else if (player == &players[secondarydisplayplayer]) - localangle2 = player->mo->angle; - } + P_SetPlayerAngle(player, player->mo->angle); } if (P_AproxDistance(player->mo->x - tails->x, player->mo->y - tails->y) > player->mo->radius) @@ -12609,12 +12554,7 @@ void P_PlayerAfterThink(player_t *player) player->mo->angle += cmd->sidemove< ANGLE_MAX if (!demoplayback || P_ControlStyle(player) == CS_LMAOGALOG) - { - if (player == &players[consoleplayer]) - localangle = player->mo->angle; // Adjust the local control angle. - else if (player == &players[secondarydisplayplayer]) - localangle2 = player->mo->angle; - } + P_SetPlayerAngle(player, player->mo->angle); } } break; @@ -12826,3 +12766,43 @@ void P_PlayerAfterThink(player_t *player) } } } + +void P_SetPlayerAngle(player_t *player, angle_t angle) +{ + INT16 delta = (INT16)(angle >> 16) - player->angleturn; + + P_ForceLocalAngle(player, P_GetLocalAngle(player) + (delta << 16)); + player->angleturn += delta; +} + +void P_SetLocalAngle(player_t *player, angle_t angle) +{ + INT16 delta = (INT16)((angle - P_GetLocalAngle(player)) >> 16); + + P_ForceLocalAngle(player, P_GetLocalAngle(player) + (angle_t)(delta << 16)); + + if (player == &players[consoleplayer]) + ticcmd_oldangleturn[0] += delta; + else if (player == &players[secondarydisplayplayer]) + ticcmd_oldangleturn[1] += delta; +} + +angle_t P_GetLocalAngle(player_t *player) +{ + if (player == &players[consoleplayer]) + return localangle; + else if (player == &players[secondarydisplayplayer]) + return localangle2; + else + return 0; +} + +void P_ForceLocalAngle(player_t *player, angle_t angle) +{ + angle = angle >> 16 << 16; + + if (player == &players[consoleplayer]) + localangle = angle; + else if (player == &players[secondarydisplayplayer]) + localangle2 = angle; +} From c6e13d0e3001122bdd9d57b95691a5dabf024b67 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Thu, 28 May 2020 18:34:56 +0200 Subject: [PATCH 17/36] Fix crash when setting a mobj's angle from a Lua script --- src/lua_mobjlib.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index 62b5d736f..c828fdb9c 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -449,7 +449,8 @@ static int mobj_set(lua_State *L) return UNIMPLEMENTED; case mobj_angle: mo->angle = luaL_checkangle(L, 3); - P_SetPlayerAngle(mo->player, mo->angle); + if (mo->player) + P_SetPlayerAngle(mo->player, mo->angle); break; case mobj_rollangle: mo->rollangle = luaL_checkangle(L, 3); From 51b640ad5a678080cc37e2b81facafd469090466 Mon Sep 17 00:00:00 2001 From: lachwright Date: Sat, 30 May 2020 18:21:39 +0800 Subject: [PATCH 18/36] Feedback so far indicates the old booster effect is preferred --- src/p_user.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 5381c7bbb..96a16284f 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -11392,11 +11392,8 @@ static void P_DoMetalJetFume(player_t *player, mobj_t *fume) P_SetThingPosition(fume); // If dashmode is high enough, spawn a trail - if (!(fume->flags2 & MF2_DONTDRAW) && player->normalspeed >= skins[player->skin].normalspeed*2) - { - mobj_t *ghost = P_SpawnGhostMobj(fume); - ghost->tics = 4; - } + if (player->normalspeed >= skins[player->skin].normalspeed*2) + P_SpawnGhostMobj(fume); } // From b874da52298d94034f7a19d352b6ce25c6194139 Mon Sep 17 00:00:00 2001 From: lachwright Date: Sat, 30 May 2020 18:26:11 +0800 Subject: [PATCH 19/36] Ensure followmobj ghost exists before applying fuse --- src/p_user.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 96a16284f..5972bb1a0 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -12231,10 +12231,8 @@ void P_PlayerThink(player_t *player) { mobj_t *ghost = P_SpawnGhostMobj(player->mo); // Spawns afterimages ghost->fuse = 2; // Makes the images fade quickly - if (ghost->tracer) - { + if (ghost->tracer && !P_MobjWasRemoved(ghost->tracer)) ghost->tracer->fuse = ghost->fuse; - } } } else if (dashmode) From 5136a4d41d6ba21acf434a550ee2e99acc5223cf Mon Sep 17 00:00:00 2001 From: lachwright Date: Sat, 30 May 2020 19:07:16 +0800 Subject: [PATCH 20/36] Don't cut momentum if landing in a roll --- src/p_mobj.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index fd13c8f05..a22545f05 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -2948,6 +2948,8 @@ static void P_PlayerZMovement(mobj_t *mo) } } + clipmomz = P_PlayerHitFloor(mo->player, true); + if (!stopmovecut) // Cut momentum in half when you hit the ground and // aren't pressing any controls. @@ -2958,8 +2960,6 @@ static void P_PlayerZMovement(mobj_t *mo) } } - clipmomz = P_PlayerHitFloor(mo->player, true); - if (!(mo->player->pflags & PF_SPINNING) && mo->player->powers[pw_carry] != CR_NIGHTSMODE) mo->player->pflags &= ~PF_STARTDASH; From e6ffedbce8a3620fa9aada0b892b01379ac6c440 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Mon, 1 Jun 2020 15:21:16 +0200 Subject: [PATCH 21/36] 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); From 9be188ff02111f07da371d35834e3e907854192e Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Tue, 2 Jun 2020 10:31:56 +0200 Subject: [PATCH 22/36] Minor edit --- src/p_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index 5708461d9..a7c24232d 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -12814,7 +12814,7 @@ angle_t P_GetLocalAngle(player_t *player) void P_ForceLocalAngle(player_t *player, angle_t angle) { - angle = angle >> 16 << 16; + angle = angle & ~UINT16_MAX; if (player == &players[consoleplayer]) localangle = angle; From 33ed36cf4b42f4a4f207cdf18ca34846c8f442ea Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Wed, 3 Jun 2020 19:41:47 +0200 Subject: [PATCH 23/36] Effect 6 flag allows cutting of cyan pixels on FOF and PolyObject planes (even if they're translucent) --- extras/conf/SRB2-22.cfg | 19 +++++++++++++++++++ src/p_polyobj.c | 3 +++ src/p_polyobj.h | 3 ++- src/r_plane.c | 14 +++++++------- 4 files changed, 31 insertions(+), 8 deletions(-) diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg index 5ed05d4d6..a0d40cdf0 100644 --- a/extras/conf/SRB2-22.cfg +++ b/extras/conf/SRB2-22.cfg @@ -760,6 +760,7 @@ linedeftypes flags128text = "[7] Intangible"; flags256text = "[8] Stopped by pushables"; flags512text = "[9] Render flats"; + flags8192text = "[13] Cut cyan flat pixels"; } 30 @@ -914,6 +915,7 @@ linedeftypes flags32text = "[5] Only block player"; flags64text = "[6] Render insides"; flags128text = "[7] Only block non-players"; + flags8192text = "[13] Cut cyan flat pixels"; 3dfloor = true; 3dfloorflags = "195F"; flags643dfloorflagsadd = "7C80"; @@ -973,6 +975,7 @@ linedeftypes flags32text = "[5] Only block player"; flags64text = "[6] Don't cast shadow"; flags128text = "[7] Render insides/block non-plr"; + flags8192text = "[13] Cut cyan flat pixels"; 3dfloor = true; 3dfloorflags = "200191F"; flags1283dfloorflagsadd = "7C80"; @@ -986,6 +989,7 @@ linedeftypes flags32text = "[5] Only block player"; flags64text = "[6] Don't cast shadow"; flags128text = "[7] Render insides/block non-plr"; + flags8192text = "[13] Cut cyan flat pixels"; 3dfloor = true; 3dfloorflags = "2001917"; flags1283dfloorflagsadd = "7C80"; @@ -1013,6 +1017,7 @@ linedeftypes flags32text = "[5] Only block player"; flags64text = "[6] Don't cast shadow"; flags128text = "[7] Render insides/block non-plr"; + flags8192text = "[13] Cut cyan flat pixels"; 3dfloor = true; 3dfloorflags = "400191F"; flags1283dfloorflagsadd = "7C80"; @@ -1026,6 +1031,7 @@ linedeftypes flags32text = "[5] Only block player"; flags64text = "[6] Don't cast shadow"; flags128text = "[7] Render insides/block non-plr"; + flags8192text = "[13] Cut cyan flat pixels"; 3dfloor = true; 3dfloorflags = "4001917"; flags1283dfloorflagsadd = "7C80"; @@ -1071,6 +1077,7 @@ linedeftypes flags64text = "[6] Use two light levels"; flags512text = "[9] Use target light level"; flags1024text = "[10] Ripple effect"; + flags8192text = "[13] Cut cyan flat pixels"; 3dfloor = true; 3dfloorflags = "9F39"; flags643dfloorflagsadd = "20000"; @@ -1099,6 +1106,7 @@ linedeftypes flags64text = "[6] Use two light levels"; flags512text = "[9] Use target light level"; flags1024text = "[10] Ripple effect"; + flags8192text = "[13] Cut cyan flat pixels"; 3dfloor = true; 3dfloorflags = "1F31"; flags643dfloorflagsadd = "20000"; @@ -1114,6 +1122,7 @@ linedeftypes flags64text = "[6] Use two light levels"; flags512text = "[9] Use target light level"; flags1024text = "[10] Ripple effect"; + flags8192text = "[13] Cut cyan flat pixels"; 3dfloor = true; 3dfloorflags = "209F39"; flags643dfloorflagsadd = "20000"; @@ -1128,6 +1137,7 @@ linedeftypes flags64text = "[6] Use two light levels"; flags512text = "[9] Use target light level"; flags1024text = "[10] Ripple effect"; + flags8192text = "[13] Cut cyan flat pixels"; 3dfloor = true; 3dfloorflags = "201F31"; flags643dfloorflagsadd = "20000"; @@ -1150,6 +1160,7 @@ linedeftypes prefix = "(221)"; flags8text = "[3] Slope skew sides"; flags64text = "[6] Cast shadow"; + flags8192text = "[13] Cut cyan flat pixels"; 3dfloor = true; 3dfloorflags = "1B59"; flags643dfloorflagsremove = "40"; @@ -1273,6 +1284,7 @@ linedeftypes flags32text = "[5] Only block player"; flags64text = "[6] Spindash to move"; flags128text = "[7] Only block non-players"; + flags8192text = "[13] Cut cyan flat pixels"; 3dfloor = true; 3dfloorflags = "195F"; } @@ -1312,6 +1324,7 @@ linedeftypes flags32text = "[5] Only block player"; flags64text = "[6] Spindash, no shadow"; flags128text = "[7] Only block non-players"; + flags8192text = "[13] Cut cyan flat pixels"; 3dfloor = true; 3dfloorflags = "2009D1F"; flags643dfloorflagsadd = "40"; @@ -1378,6 +1391,7 @@ linedeftypes flags32text = "[5] Only block player"; flags64text = "[6] Don't cast shadow"; flags128text = "[7] Only block non-players"; + flags8192text = "[13] Cut cyan flat pixels"; 3dfloor = true; 3dfloorflags = "210959F"; flags643dfloorflagsadd = "40"; @@ -1391,6 +1405,7 @@ linedeftypes flags32text = "[5] Only block player"; flags64text = "[6] Don't cast shadow"; flags128text = "[7] Only block non-players"; + flags8192text = "[13] Cut cyan flat pixels"; 3dfloor = true; 3dfloorflags = "218959F"; flags643dfloorflagsadd = "40"; @@ -1529,6 +1544,7 @@ linedeftypes flags8text = "[3] Slope skew sides"; flags512text = "[9] Shattered by pushables"; flags1024text = "[10] Trigger linedef executor"; + flags8192text = "[13] Cut cyan flat pixels"; 3dfloor = true; 3dfloorflags = "880101D"; } @@ -1570,6 +1586,7 @@ linedeftypes flags128text = "[7] Only block non-players"; flags512text = "[9] Shattered by pushables"; flags1024text = "[10] Trigger linedef executor"; + flags8192text = "[13] Cut cyan flat pixels"; 3dfloor = true; 3dfloorflags = "1080101F"; } @@ -1591,6 +1608,7 @@ linedeftypes prefix = "(258)"; flags8text = "[3] Slope skew sides"; flags32text = "[5] Don't damage bosses"; + flags8192text = "[13] Cut cyan flat pixels"; 3dfloor = true; 3dfloorflags = "959"; } @@ -1604,6 +1622,7 @@ linedeftypes flags128text = "[7] Only block non-players"; flags512text = "[9] Shattered by pushables"; flags1024text = "[10] Trigger linedef executor"; + flags8192text = "[13] Cut cyan flat pixels"; 3dfloor = true; 3dfloorcustom = true; } diff --git a/src/p_polyobj.c b/src/p_polyobj.c index 3b6195285..d94f363c3 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -240,6 +240,9 @@ static void Polyobj_GetInfo(polyobj_t *po) /*if (lines[i].flags & ML_EFFECT5) po->flags &= ~POF_CLIPPLANES;*/ + if (lines[i].flags & ML_EFFECT6) + po->flags |= POF_SPLAT; + if (lines[i].flags & ML_NOCLIMB) // Has a linedef executor po->flags |= POF_LDEXEC; } diff --git a/src/p_polyobj.h b/src/p_polyobj.h index 8037c545f..c6ae716f4 100644 --- a/src/p_polyobj.h +++ b/src/p_polyobj.h @@ -38,7 +38,7 @@ typedef enum POF_SOLID = 0x3, ///< Clips things. POF_TESTHEIGHT = 0x4, ///< Test line collision with heights POF_RENDERSIDES = 0x8, ///< Renders the sides. - POF_RENDERTOP = 0x10, ///< Renders the top.. + POF_RENDERTOP = 0x10, ///< Renders the top. POF_RENDERBOTTOM = 0x20, ///< Renders the bottom. POF_RENDERPLANES = 0x30, ///< Renders top and bottom. POF_RENDERALL = 0x38, ///< Renders everything. @@ -49,6 +49,7 @@ typedef enum POF_LDEXEC = 0x400, ///< This PO triggers a linedef executor. POF_ONESIDE = 0x800, ///< Only use the first side of the linedef. POF_NOSPECIALS = 0x1000, ///< Don't apply sector specials. + POF_SPLAT = 0x2000, ///< Use splat flat renderer (treat cyan pixels as invisible). } polyobjflags_e; // diff --git a/src/r_plane.c b/src/r_plane.c index 6857b6dca..92795d0fb 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -943,23 +943,23 @@ void R_DrawSinglePlane(visplane_t *pl) #endif spanfunc = spanfuncs[BASEDRAWFUNC]; - if (pl->polyobj && pl->polyobj->translucency != 0) + if (pl->polyobj) { - spanfunctype = SPANDRAWFUNC_TRANS; - // Hacked up support for alpha value in software mode Tails 09-24-2002 (sidenote: ported to polys 10-15-2014, there was no time travel involved -Red) if (pl->polyobj->translucency >= 10) return; // Don't even draw it else if (pl->polyobj->translucency > 0) + { + spanfunctype = (pl->polyobj->flags & POF_SPLAT) ? SPANDRAWFUNC_TRANSSPLAT : SPANDRAWFUNC_TRANS; ds_transmap = transtables + ((pl->polyobj->translucency-1)<polyobj->flags & POF_SPLAT) // Opaque, but allow transparent flat pixels spanfunctype = SPANDRAWFUNC_SPLAT; - if ((spanfunctype == SPANDRAWFUNC_SPLAT) || (pl->extra_colormap && (pl->extra_colormap->flags & CMF_FOG))) + if (pl->polyobj->translucency == 0 || (pl->extra_colormap && (pl->extra_colormap->flags & CMF_FOG))) light = (pl->lightlevel >> LIGHTSEGSHIFT); else light = LIGHTLEVELS-1; - } else { @@ -984,7 +984,7 @@ void R_DrawSinglePlane(visplane_t *pl) if (pl->ffloor->flags & FF_TRANSLUCENT) { - spanfunctype = SPANDRAWFUNC_TRANS; + spanfunctype = (pl->ffloor->master->flags & ML_EFFECT6) ? SPANDRAWFUNC_TRANSSPLAT : SPANDRAWFUNC_TRANS; // Hacked up support for alpha value in software mode Tails 09-24-2002 if (pl->ffloor->alpha < 12) From 879a2bd20afd8cd07089a5fb0909dd17cf6f1109 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 28 May 2020 16:39:31 +0100 Subject: [PATCH 24/36] G_GhostTicker/G_ReadMetalTic: type should default to MT_NULL, not -1 This way, if for some reason the ghost has no skin, nothing should spawn at all --- src/g_demo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/g_demo.c b/src/g_demo.c index 30bc8ca48..63ab4c74f 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -764,7 +764,7 @@ void G_GhostTicker(void) if (xziptic & EZT_THOKMASK) { // Let's only spawn ONE of these per frame, thanks. mobj_t *mobj; - INT32 type = -1; + UINT32 type = MT_NULL; if (g->mo->skin) { skin_t *skin = (skin_t *)g->mo->skin; @@ -1051,7 +1051,7 @@ void G_ReadMetalTic(mobj_t *metal) if (xziptic & EZT_THOKMASK) { // Let's only spawn ONE of these per frame, thanks. mobj_t *mobj; - INT32 type = -1; + UINT32 type = MT_NULL; if (metal->skin) { skin_t *skin = (skin_t *)metal->skin; From d11ba67288ebc27cbb94265c8e1dbcdb5f3fd159 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 28 May 2020 16:49:12 +0100 Subject: [PATCH 25/36] G_ReadMetalTic: Make sure all three values for GZT_XYZ are read in the right order --- src/g_demo.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/g_demo.c b/src/g_demo.c index 63ab4c74f..c03e2c53f 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -996,7 +996,11 @@ void G_ReadMetalTic(mobj_t *metal) // Read changes from the tic if (ziptic & GZT_XYZ) { - P_TeleportMove(metal, READFIXED(metal_p), READFIXED(metal_p), READFIXED(metal_p)); + // make sure the values are read in the right order + oldmetal.x = READFIXED(metal_p); + oldmetal.y = READFIXED(metal_p); + oldmetal.z = READFIXED(metal_p); + P_TeleportMove(metal, oldmetal.x, oldmetal.y, oldmetal.z); oldmetal.x = metal->x; oldmetal.y = metal->y; oldmetal.z = metal->z; From adb11eec1b3dfe658e55ce93d97f3133a2b04b95 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 28 May 2020 17:10:20 +0100 Subject: [PATCH 26/36] dehacked.c: use actual size of descriptions buffers rather than MAXLINELEN, which is way too large --- src/dehacked.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index a6c73e0b4..8450c16e6 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -392,7 +392,7 @@ static void readPlayer(MYFILE *f, INT32 num) // It works down here, though. { INT32 numline = 0; - for (i = 0; i < MAXLINELEN-1; i++) + for (i = 0; (size_t)i < sizeof(description[num].notes)-1; i++) { if (numline < 20 && description[num].notes[i] == '\n') numline++; @@ -1174,7 +1174,7 @@ static void readgametype(MYFILE *f, char *gtname) // It works down here, though. { INT32 numline = 0; - for (i = 0; i < MAXLINELEN-1; i++) + for (i = 0; (size_t)i < sizeof(gtdescription)-1; i++) { if (numline < 20 && gtdescription[i] == '\n') numline++; From 7340442839aa329d870c0e85a91ce2957ba6f0f4 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 28 May 2020 17:35:14 +0100 Subject: [PATCH 27/36] P_XYMovement: initialise slopemom to all zeros --- src/p_mobj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 78e0ccd41..98e21544f 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1772,7 +1772,7 @@ void P_XYMovement(mobj_t *mo) fixed_t oldx, oldy; // reducing bobbing/momentum on ice when up against walls boolean moved; pslope_t *oldslope = NULL; - vector3_t slopemom; + vector3_t slopemom = {0,0,0}; fixed_t predictedz = 0; I_Assert(mo != NULL); From 8092d30376b8aaa38a4f93736442bece07f26b8d Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 28 May 2020 17:55:25 +0100 Subject: [PATCH 28/36] Polyobj_rotate and related: change "origin" to vector2_t since all it needs is x/y and not any of the new stuff for vertex_t --- src/p_polyobj.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/p_polyobj.c b/src/p_polyobj.c index cd63f4509..9d293a575 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -1039,7 +1039,7 @@ static boolean Polyobj_moveXY(polyobj_t *po, fixed_t x, fixed_t y, boolean check // The formula for this can be found here: // http://www.inversereality.org/tutorials/graphics%20programming/2dtransformations.html // It is, of course, just a vector-matrix multiplication. -static inline void Polyobj_rotatePoint(vertex_t *v, const vertex_t *c, angle_t ang) +static inline void Polyobj_rotatePoint(vertex_t *v, const vector2_t *c, angle_t ang) { vertex_t tmp = *v; @@ -1092,7 +1092,7 @@ static void Polyobj_rotateLine(line_t *ld) } // Causes objects resting on top of the rotating polyobject to 'ride' with its movement. -static void Polyobj_rotateThings(polyobj_t *po, vertex_t origin, angle_t delta, UINT8 turnthings) +static void Polyobj_rotateThings(polyobj_t *po, vector2_t origin, angle_t delta, UINT8 turnthings) { static INT32 pomovecount = 10000; INT32 x, y; @@ -1172,7 +1172,7 @@ static boolean Polyobj_rotate(polyobj_t *po, angle_t delta, UINT8 turnthings, bo { size_t i; angle_t angle; - vertex_t origin; + vector2_t origin; INT32 hitflags = 0; // don't move bad polyobjects From bb1a2dbba773c5a7da16ff86dc4a156b8c0b3d9b Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 28 May 2020 18:03:57 +0100 Subject: [PATCH 29/36] sdl/i_main.c: fix wrong placement of #endif for LOGMESSAGES code --- src/sdl/i_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sdl/i_main.c b/src/sdl/i_main.c index 3eded734f..24841d173 100644 --- a/src/sdl/i_main.c +++ b/src/sdl/i_main.c @@ -191,7 +191,6 @@ int main(int argc, char **argv) left = snprintf(logfilename, sizeof logfilename, "."PATHSEP"%s"PATHSEP, reldir); } -#endif/*LOGMESSAGES*/ strftime(&logfilename[left], sizeof logfilename - left, format, timeinfo); @@ -218,6 +217,7 @@ int main(int argc, char **argv) logstream = fopen("latest-log.txt", "wt+"); #endif/*defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON)*/ } +#endif/*LOGMESSAGES*/ //I_OutputMsg("I_StartupSystem() ...\n"); I_StartupSystem(); From 5349a0bf627085db884be51a67442d5d2827ccaa Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 28 May 2020 18:07:12 +0100 Subject: [PATCH 30/36] V_Init: count to NUMSCREENS, not NUMSCREENS+1 (though I can't help thinking this one might have been deliberate somehow?) --- src/v_video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/v_video.c b/src/v_video.c index 3ce0e79f5..11381ccea 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -3696,7 +3696,7 @@ void V_Init(void) #ifdef DEBUG CONS_Debug(DBG_RENDER, "V_Init done:\n"); - for (i = 0; i < NUMSCREENS+1; i++) + for (i = 0; i < NUMSCREENS; i++) CONS_Debug(DBG_RENDER, " screens[%d] = %x\n", i, screens[i]); #endif } From b11d58aef5c1946a18a8549925cc9a2adfe7e3e0 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 28 May 2020 18:49:15 +0100 Subject: [PATCH 31/36] clean up BUGTRAP code in win32/win_main.c to avoid unmatched } (though that said we don't officially care about the win32 folder files anymore) --- src/win32/win_main.c | 41 ++++++++++++++++------------------------- 1 file changed, 16 insertions(+), 25 deletions(-) diff --git a/src/win32/win_main.c b/src/win32/win_main.c index 8a29f7e18..e1d90881b 100644 --- a/src/win32/win_main.c +++ b/src/win32/win_main.c @@ -643,37 +643,28 @@ int WINAPI WinMain (HINSTANCE hInstance, int nCmdShow) { int Result = -1; - -#if 0 - // Win95 and NT <4 don't have this, so link at runtime. - p_IsDebuggerPresent pfnIsDebuggerPresent = (p_IsDebuggerPresent)GetProcAddress(GetModuleHandleA("kernel32.dll"),"IsDebuggerPresent"); -#endif - UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); UNREFERENCED_PARAMETER(nCmdShow); -#if 0 -#ifdef BUGTRAP - // Try BugTrap first. - if((!pfnIsDebuggerPresent || !pfnIsDebuggerPresent()) && InitBugTrap()) - Result = HandledWinMain(hInstance); - else { -#endif - // Try Dr MinGW's exception handler. - if (!pfnIsDebuggerPresent || !pfnIsDebuggerPresent()) -#endif - LoadLibraryA("exchndl.dll"); - -#ifndef __MINGW32__ - prevExceptionFilter = SetUnhandledExceptionFilter(RecordExceptionInfo); -#endif - - Result = HandledWinMain(hInstance); +#if 0 + p_IsDebuggerPresent pfnIsDebuggerPresent = (p_IsDebuggerPresent)GetProcAddress(GetModuleHandleA("kernel32.dll"),"IsDebuggerPresent"); + if((!pfnIsDebuggerPresent || !pfnIsDebuggerPresent()) +#ifdef BUGTRAP + && !InitBugTrap() +#endif + ) +#endif + { + LoadLibraryA("exchndl.dll"); + } + } +#ifndef __MINGW32__ + prevExceptionFilter = SetUnhandledExceptionFilter(RecordExceptionInfo); +#endif + Result = HandledWinMain(hInstance); #ifdef BUGTRAP - } // BT failure clause. - // This is safe even if BT didn't start. ShutdownBugTrap(); #endif From cb7423b97e4cb720e147458d764d1b29f5604ebe Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 28 May 2020 19:08:53 +0100 Subject: [PATCH 32/36] sdl/i_main.c: while we're here, split all the logging initialisation code into a separate function, to make main function more clean --- src/sdl/i_main.c | 171 ++++++++++++++++++++++++----------------------- 1 file changed, 88 insertions(+), 83 deletions(-) diff --git a/src/sdl/i_main.c b/src/sdl/i_main.c index 24841d173..26efd3275 100644 --- a/src/sdl/i_main.c +++ b/src/sdl/i_main.c @@ -103,6 +103,93 @@ static inline VOID MakeCodeWritable(VOID) } #endif +#ifdef LOGMESSAGES +static VOID InitLogging(VOID) +{ + const char *logdir = NULL; + time_t my_time; + struct tm * timeinfo; + const char *format; + const char *reldir; + int left; + boolean fileabs; +#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) + const char *link; +#endif + + logdir = D_Home(); + + my_time = time(NULL); + timeinfo = localtime(&my_time); + + if (M_CheckParm("-logfile") && M_IsNextParm()) + { + format = M_GetNextParm(); + fileabs = M_IsPathAbsolute(format); + } + else + { + format = "log-%Y-%m-%d_%H-%M-%S.txt"; + fileabs = false; + } + + if (fileabs) + { + strftime(logfilename, sizeof logfilename, format, timeinfo); + } + else + { + if (M_CheckParm("-logdir") && M_IsNextParm()) + reldir = M_GetNextParm(); + else + reldir = "logs"; + + if (M_IsPathAbsolute(reldir)) + { + left = snprintf(logfilename, sizeof logfilename, + "%s"PATHSEP, reldir); + } + else +#ifdef DEFAULTDIR + if (logdir) + { + left = snprintf(logfilename, sizeof logfilename, + "%s"PATHSEP DEFAULTDIR PATHSEP"%s"PATHSEP, logdir, reldir); + } + else +#endif/*DEFAULTDIR*/ + { + left = snprintf(logfilename, sizeof logfilename, + "."PATHSEP"%s"PATHSEP, reldir); + } + + strftime(&logfilename[left], sizeof logfilename - left, + format, timeinfo); + } + + M_MkdirEachUntil(logfilename, + M_PathParts(logdir) - 1, + M_PathParts(logfilename) - 1, 0755); + +#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) + logstream = fopen(logfilename, "w"); +#ifdef DEFAULTDIR + if (logdir) + link = va("%s/"DEFAULTDIR"/latest-log.txt", logdir); + else +#endif/*DEFAULTDIR*/ + link = "latest-log.txt"; + unlink(link); + if (symlink(logfilename, link) == -1) + { + I_OutputMsg("Error symlinking latest-log.txt: %s\n", strerror(errno)); + } +#else/*defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON)*/ + logstream = fopen("latest-log.txt", "wt+"); +#endif/*defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON)*/ +} +#endif + /** \brief The main function @@ -121,7 +208,6 @@ int SDL_main(int argc, char **argv) int main(int argc, char **argv) #endif { - const char *logdir = NULL; myargc = argc; myargv = argv; /// \todo pull out path to exe from this string @@ -135,88 +221,7 @@ int main(int argc, char **argv) #ifdef LOGMESSAGES if (!M_CheckParm("-nolog")) - { - time_t my_time; - struct tm * timeinfo; - const char *format; - const char *reldir; - int left; - boolean fileabs; -#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) - const char *link; -#endif - - logdir = D_Home(); - - my_time = time(NULL); - timeinfo = localtime(&my_time); - - if (M_CheckParm("-logfile") && M_IsNextParm()) - { - format = M_GetNextParm(); - fileabs = M_IsPathAbsolute(format); - } - else - { - format = "log-%Y-%m-%d_%H-%M-%S.txt"; - fileabs = false; - } - - if (fileabs) - { - strftime(logfilename, sizeof logfilename, format, timeinfo); - } - else - { - if (M_CheckParm("-logdir") && M_IsNextParm()) - reldir = M_GetNextParm(); - else - reldir = "logs"; - - if (M_IsPathAbsolute(reldir)) - { - left = snprintf(logfilename, sizeof logfilename, - "%s"PATHSEP, reldir); - } - else -#ifdef DEFAULTDIR - if (logdir) - { - left = snprintf(logfilename, sizeof logfilename, - "%s"PATHSEP DEFAULTDIR PATHSEP"%s"PATHSEP, logdir, reldir); - } - else -#endif/*DEFAULTDIR*/ - { - left = snprintf(logfilename, sizeof logfilename, - "."PATHSEP"%s"PATHSEP, reldir); - } - - strftime(&logfilename[left], sizeof logfilename - left, - format, timeinfo); - } - - M_MkdirEachUntil(logfilename, - M_PathParts(logdir) - 1, - M_PathParts(logfilename) - 1, 0755); - -#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) - logstream = fopen(logfilename, "w"); -#ifdef DEFAULTDIR - if (logdir) - link = va("%s/"DEFAULTDIR"/latest-log.txt", logdir); - else -#endif/*DEFAULTDIR*/ - link = "latest-log.txt"; - unlink(link); - if (symlink(logfilename, link) == -1) - { - I_OutputMsg("Error symlinking latest-log.txt: %s\n", strerror(errno)); - } -#else/*defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON)*/ - logstream = fopen("latest-log.txt", "wt+"); -#endif/*defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON)*/ - } + InitLogging(); #endif/*LOGMESSAGES*/ //I_OutputMsg("I_StartupSystem() ...\n"); From 9e4ed738b77fed9b3bc72c91e7a76572325bdd4b Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 4 Jun 2020 21:31:26 +0100 Subject: [PATCH 33/36] Sync turnobjs for polyrotate_t thinkers in netgames --- src/p_saveg.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/p_saveg.c b/src/p_saveg.c index 6f80949ea..eafc285a3 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -2023,6 +2023,7 @@ static inline void SavePolyrotatetThinker(const thinker_t *th, const UINT8 type) WRITEINT32(save_p, ht->polyObjNum); WRITEINT32(save_p, ht->speed); WRITEINT32(save_p, ht->distance); + WRITEUINT8(save_p, ht->turnobjs); } static void SavePolymoveThinker(const thinker_t *th, const UINT8 type) @@ -3155,6 +3156,7 @@ static inline thinker_t* LoadPolyrotatetThinker(actionf_p1 thinker) ht->polyObjNum = READINT32(save_p); ht->speed = READINT32(save_p); ht->distance = READINT32(save_p); + ht->turnobjs = READUINT8(save_p); return &ht->thinker; } From 56b8ea3587d10ae258af31d5440a8fa8fc95cf79 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 6 Jun 2020 17:38:35 +0100 Subject: [PATCH 34/36] added liolib.c to the VC10 project files, since it was missing from them --- src/sdl/Srb2SDL-vc10.vcxproj | 1 + src/sdl/Srb2SDL-vc10.vcxproj.filters | 3 +++ 2 files changed, 4 insertions(+) diff --git a/src/sdl/Srb2SDL-vc10.vcxproj b/src/sdl/Srb2SDL-vc10.vcxproj index 6335b3028..6a55ac2d6 100644 --- a/src/sdl/Srb2SDL-vc10.vcxproj +++ b/src/sdl/Srb2SDL-vc10.vcxproj @@ -338,6 +338,7 @@ + diff --git a/src/sdl/Srb2SDL-vc10.vcxproj.filters b/src/sdl/Srb2SDL-vc10.vcxproj.filters index a226e8397..89ba1b588 100644 --- a/src/sdl/Srb2SDL-vc10.vcxproj.filters +++ b/src/sdl/Srb2SDL-vc10.vcxproj.filters @@ -534,6 +534,9 @@ BLUA + + BLUA + BLUA From d2fefb6b9a2080943d0c360134b942bab0d8a66f Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 6 Jun 2020 20:49:12 +0100 Subject: [PATCH 35/36] use void rather than VOID, because the logging init code isn't exclusively Win32, whoops --- src/sdl/i_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sdl/i_main.c b/src/sdl/i_main.c index 26efd3275..1dee379c0 100644 --- a/src/sdl/i_main.c +++ b/src/sdl/i_main.c @@ -104,7 +104,7 @@ static inline VOID MakeCodeWritable(VOID) #endif #ifdef LOGMESSAGES -static VOID InitLogging(VOID) +static void InitLogging(void) { const char *logdir = NULL; time_t my_time; From 82200d80a97621bfc061a8dbf3c042b9fe020093 Mon Sep 17 00:00:00 2001 From: sphere Date: Sun, 7 Jun 2020 00:40:33 +0200 Subject: [PATCH 36/36] Fix mouse being grabbed in the continue screen. --- src/sdl/i_video.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 0abc9280c..87445497a 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -373,7 +373,8 @@ static boolean IgnoreMouse(void) return !M_MouseNeeded(); if (paused || con_destlines || chat_on) return true; - if (gamestate != GS_LEVEL && gamestate != GS_INTERMISSION && gamestate != GS_CUTSCENE) + if (gamestate != GS_LEVEL && gamestate != GS_INTERMISSION && + gamestate != GS_CONTINUING && gamestate != GS_CUTSCENE) return true; return false; }