// SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. // Copyright (C) 1999-2023 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. // See the 'LICENSE' file for more details. //----------------------------------------------------------------------------- /// \file hu_stuff.c /// \brief Heads up display #include "doomdef.h" #include "byteptr.h" #include "hu_stuff.h" #include "m_menu.h" // gametype_cons_t #include "m_cond.h" // emblems #include "m_misc.h" // word jumping #include "netcode/d_clisrv.h" #include "netcode/net_command.h" #include "netcode/gamestate.h" #include "g_game.h" #include "g_input.h" #include "i_video.h" #include "i_system.h" #include "st_stuff.h" // ST_HEIGHT #include "r_local.h" #include "keys.h" #include "v_video.h" #include "w_wad.h" #include "z_zone.h" #include "console.h" #include "am_map.h" #include "d_main.h" #include "p_local.h" // camera, camera2 #include "p_tick.h" #ifdef HWRENDER #include "hardware/hw_main.h" #endif #include "lua_hud.h" #include "lua_hudlib_drawlist.h" #include "lua_hook.h" // coords are scaled #define HU_INPUTX 0 #define HU_INPUTY 0 #define HU_SERVER_SAY 1 // Server message (dedicated). #define HU_CSAY 2 // Server CECHOes to everyone. //------------------------------------------- // heads up font //------------------------------------------- patch_t *hu_font[HU_FONTSIZE]; patch_t *tny_font[HU_FONTSIZE]; patch_t *tallnum[10]; // 0-9 patch_t *nightsnum[10]; // 0-9 // Level title and credits fonts patch_t *lt_font[LT_FONTSIZE]; patch_t *cred_font[CRED_FONTSIZE]; patch_t *ttlnum[10]; // act numbers (0-9) // Name tag fonts patch_t *ntb_font[NT_FONTSIZE]; patch_t *nto_font[NT_FONTSIZE]; static player_t *plr; boolean chat_on; // entering a chat message? boolean chat_on_first_event; // blocker for first chat input event static char w_chat[HU_MAXMSGLEN + 1]; static size_t c_input = 0; // let's try to make the chat input less shitty. static boolean headsupactive = false; boolean hu_showscores; // draw rankings static char hu_tick; patch_t *rflagico; patch_t *bflagico; patch_t *rmatcico; patch_t *bmatcico; patch_t *tagico; patch_t *tallminus; patch_t *tallinfin; //------------------------------------------- // coop hud //------------------------------------------- patch_t *emeraldpics[3][8]; // 0 = normal, 1 = tiny, 2 = coinbox static patch_t *emblemicon; patch_t *tokenicon; static patch_t *exiticon; static patch_t *nopingicon; //------------------------------------------- // misc vars //------------------------------------------- // crosshair 0 = off, 1 = cross, 2 = angle, 3 = point, see m_menu.c static patch_t *crosshair[HU_CROSSHAIRS]; // 3 precached crosshair graphics // ------- // protos. // ------- static void HU_DrawRankings(void); static void HU_DrawCoopOverlay(void); static void HU_DrawNetplayCoopOverlay(void); //====================================================================== // KEYBOARD LAYOUTS FOR ENTERING TEXT //====================================================================== char *shiftxform; char english_shiftxform[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, ' ', '!', '"', '#', '$', '%', '&', '"', // shift-' '(', ')', '*', '+', '<', // shift-, '_', // shift-- '>', // shift-. '?', // shift-/ ')', // shift-0 '!', // shift-1 '@', // shift-2 '#', // shift-3 '$', // shift-4 '%', // shift-5 '^', // shift-6 '&', // shift-7 '*', // shift-8 '(', // shift-9 ':', ':', // shift-; '<', '+', // shift-= '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '{', // shift-[ '|', // shift-backslash - OH MY GOD DOES WATCOM SUCK '}', // shift-] '"', '_', '~', // shift-` 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '{', '|', '}', '~', 127 }; static char cechotext[1024]; static tic_t cechotimer = 0; static tic_t cechoduration = 5*TICRATE; static INT32 cechoflags = 0; static huddrawlist_h luahuddrawlist_scores; //====================================================================== // HEADS UP INIT //====================================================================== static tic_t resynch_ticker = 0; // just after static void Command_Say_f(void); static void Command_Sayto_f(void); static void Command_Sayteam_f(void); static void Command_CSay_f(void); static void Got_Saycmd(UINT8 **p, INT32 playernum); void HU_LoadGraphics(void) { char buffer[9]; INT32 i, j; if (dedicated) return; j = HU_FONTSTART; for (i = 0; i < HU_FONTSIZE; i++, j++) { // cache the heads-up font for entire game execution sprintf(buffer, "STCFN%.3d", j); if (W_CheckNumForName(buffer) == LUMPERROR) hu_font[i] = NULL; else hu_font[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX); // tiny version of the heads-up font sprintf(buffer, "TNYFN%.3d", j); if (W_CheckNumForName(buffer) == LUMPERROR) tny_font[i] = NULL; else tny_font[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX); } j = LT_FONTSTART; for (i = 0; i < LT_FONTSIZE; i++) { sprintf(buffer, "LTFNT%.3d", j); j++; if (W_CheckNumForName(buffer) == LUMPERROR) lt_font[i] = NULL; else lt_font[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX); } // cache the credits font for entire game execution (why not?) j = CRED_FONTSTART; for (i = 0; i < CRED_FONTSIZE; i++) { sprintf(buffer, "CRFNT%.3d", j); j++; if (W_CheckNumForName(buffer) == LUMPERROR) cred_font[i] = NULL; else cred_font[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX); } //cache numbers too! for (i = 0; i < 10; i++) { sprintf(buffer, "STTNUM%d", i); tallnum[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX); sprintf(buffer, "NGTNUM%d", i); nightsnum[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); } // minus for negative tallnums tallminus = (patch_t *)W_CachePatchName("STTMINUS", PU_HUDGFX); tallinfin = (patch_t *)W_CachePatchName("STTINFIN", PU_HUDGFX); // cache act numbers for level titles for (i = 0; i < 10; i++) { sprintf(buffer, "TTL%.2d", i); ttlnum[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX); } // cache the base name tag font for entire game execution j = NT_FONTSTART; for (i = 0; i < NT_FONTSIZE; i++) { sprintf(buffer, "NTFNT%.3d", j); j++; if (W_CheckNumForName(buffer) == LUMPERROR) ntb_font[i] = NULL; else ntb_font[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX); } // cache the outline name tag font for entire game execution j = NT_FONTSTART; for (i = 0; i < NT_FONTSIZE; i++) { sprintf(buffer, "NTFNO%.3d", j); j++; if (W_CheckNumForName(buffer) == LUMPERROR) nto_font[i] = NULL; else nto_font[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX); } // cache the crosshairs, don't bother to know which one is being used, // just cache all 3, they're so small anyway. for (i = 0; i < HU_CROSSHAIRS; i++) { sprintf(buffer, "CROSHAI%c", '1'+i); crosshair[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX); } emblemicon = W_CachePatchName("EMBLICON", PU_HUDGFX); tokenicon = W_CachePatchName("TOKNICON", PU_HUDGFX); exiticon = W_CachePatchName("EXITICON", PU_HUDGFX); nopingicon = W_CachePatchName("NOPINGICON", PU_HUDGFX); emeraldpics[0][0] = W_CachePatchName("CHAOS1", PU_HUDGFX); emeraldpics[0][1] = W_CachePatchName("CHAOS2", PU_HUDGFX); emeraldpics[0][2] = W_CachePatchName("CHAOS3", PU_HUDGFX); emeraldpics[0][3] = W_CachePatchName("CHAOS4", PU_HUDGFX); emeraldpics[0][4] = W_CachePatchName("CHAOS5", PU_HUDGFX); emeraldpics[0][5] = W_CachePatchName("CHAOS6", PU_HUDGFX); emeraldpics[0][6] = W_CachePatchName("CHAOS7", PU_HUDGFX); emeraldpics[0][7] = W_CachePatchName("CHAOS8", PU_HUDGFX); emeraldpics[1][0] = W_CachePatchName("TEMER1", PU_HUDGFX); emeraldpics[1][1] = W_CachePatchName("TEMER2", PU_HUDGFX); emeraldpics[1][2] = W_CachePatchName("TEMER3", PU_HUDGFX); emeraldpics[1][3] = W_CachePatchName("TEMER4", PU_HUDGFX); emeraldpics[1][4] = W_CachePatchName("TEMER5", PU_HUDGFX); emeraldpics[1][5] = W_CachePatchName("TEMER6", PU_HUDGFX); emeraldpics[1][6] = W_CachePatchName("TEMER7", PU_HUDGFX); //emeraldpics[1][7] = W_CachePatchName("TEMER8", PU_HUDGFX); -- unused emeraldpics[2][0] = W_CachePatchName("EMBOX1", PU_HUDGFX); emeraldpics[2][1] = W_CachePatchName("EMBOX2", PU_HUDGFX); emeraldpics[2][2] = W_CachePatchName("EMBOX3", PU_HUDGFX); emeraldpics[2][3] = W_CachePatchName("EMBOX4", PU_HUDGFX); emeraldpics[2][4] = W_CachePatchName("EMBOX5", PU_HUDGFX); emeraldpics[2][5] = W_CachePatchName("EMBOX6", PU_HUDGFX); emeraldpics[2][6] = W_CachePatchName("EMBOX7", PU_HUDGFX); //emeraldpics[2][7] = W_CachePatchName("EMBOX8", PU_HUDGFX); -- unused } // Initialise Heads up // once at game startup. // void HU_Init(void) { COM_AddCommand("say", Command_Say_f, COM_LUA); COM_AddCommand("sayto", Command_Sayto_f, COM_LUA); COM_AddCommand("sayteam", Command_Sayteam_f, COM_LUA); COM_AddCommand("csay", Command_CSay_f, COM_LUA); RegisterNetXCmd(XD_SAY, Got_Saycmd); // set shift translation table shiftxform = english_shiftxform; luahuddrawlist_scores = LUA_HUD_CreateDrawList(); } static inline void HU_Stop(void) { headsupactive = false; } // // Reset Heads up when consoleplayer spawns // void HU_Start(void) { if (headsupactive) HU_Stop(); plr = &players[consoleplayer]; headsupactive = true; } //====================================================================== // EXECUTION //====================================================================== // EVERY CHANGE IN THIS SCRIPT IS LOL XD! BY VINCYTM static UINT32 chat_nummsg_log = 0; static UINT32 chat_nummsg_min = 0; static UINT32 chat_scroll = 0; static tic_t chat_scrolltime = 0; static UINT32 chat_maxscroll = 0; // how far can we scroll? //static chatmsg_t chat_mini[CHAT_BUFSIZE]; // Display the last few messages sent. //static chatmsg_t chat_log[CHAT_BUFSIZE]; // Keep every message sent to us in memory so we can scroll n shit, it's cool. static char chat_log[CHAT_BUFSIZE][255]; // hold the last 48 or so messages in that log. static char chat_mini[8][255]; // display up to 8 messages that will fade away / get overwritten static tic_t chat_timers[8]; static boolean chat_scrollmedown = false; // force instant scroll down on the chat log. Happens when you open it / send a message. // remove text from minichat table static INT16 addy = 0; // use this to make the messages scroll smoothly when one fades away static void HU_removeChatText_Mini(void) { // MPC: Don't create new arrays, just iterate through an existing one size_t i; for(i=0;i