Compare commits
53
Commits
softwarecrap
...
emotes
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2800685cfc | ||
|
|
c479d9d706 | ||
|
|
338fbfbeaf | ||
|
|
5ca12bb421 | ||
|
|
6c94e0c9bf | ||
|
|
83d0f6bb50 | ||
|
|
7e06fc986f | ||
|
|
3f5328371a | ||
|
|
148fcc8dab | ||
|
|
72a67d306f | ||
|
|
0dcdcc3da1 | ||
|
|
729c60c9b0 | ||
|
|
1b418caf6b | ||
|
|
d275db9bb4 | ||
|
|
21cfd7c361 | ||
|
|
5d8bb3223f | ||
|
|
5e1f943a38 | ||
|
|
612431c1f1 | ||
|
|
fca7b4a837 | ||
|
|
d2bab80b29 | ||
|
|
78ab90c1a6 | ||
|
|
102e944fd5 | ||
|
|
04385d9700 | ||
|
|
7ef2da5922 | ||
|
|
5638709670 | ||
|
|
9bd4a933cf | ||
|
|
e233635783 | ||
|
|
da24ba20c7 | ||
|
|
74bdabc636 | ||
|
|
4b129314d3 | ||
|
|
3a55972997 | ||
|
|
6e04e4171e | ||
|
|
db67176eca | ||
|
|
0b7a4ff4e0 | ||
|
|
02feb3ad5c | ||
|
|
49f13d2a59 | ||
|
|
8fb1775606 | ||
|
|
fab7635373 | ||
|
|
b29ca13916 | ||
|
|
e13ba89f1a | ||
|
|
68ae880979 | ||
|
|
d8b2134aef | ||
|
|
c168832f8e | ||
|
|
448a603a56 | ||
|
|
2a95201c6d | ||
|
|
a73de55f96 | ||
|
|
e4a4496be6 | ||
|
|
a8f3a8dfb0 | ||
|
|
e19b9d1c60 | ||
|
|
e28ec4e7cb | ||
|
|
d0f09b467b | ||
|
|
359befd857 | ||
|
|
279dfcafc4 |
No files matched your search
+31
@@ -161,6 +161,37 @@ Duration is in milliseconds and is optional to set, default value is 84ms.
|
||||
Exactly same as P_CheckSight but uses cheaper algorithm, useful for things like nametags. Doesn't work exactly
|
||||
like P_CheckSight so don't use it for anything gameplay-related.
|
||||
|
||||
## musicdef_t
|
||||
|
||||
Userdata structure representing a musicdef. Fields:
|
||||
|
||||
`musicdef.name` - song identifier ("kmap01" for example).
|
||||
|
||||
`musicdef.usage`, `musicdef.source` - fields from vanilla MUSICDEFS lump.
|
||||
|
||||
`musicdef.filename` - unused for now.
|
||||
|
||||
`musicdef.title`, `musicdef.alttitle`, `musicdef.authors` - fields from MUSCINFO lump.
|
||||
|
||||
`#musicdef` - returns integer id for musicdef (which can be used as index in `musicdefs`).
|
||||
|
||||
All fields are read-only.
|
||||
|
||||
## S_FindMusicCredit(name)
|
||||
|
||||
Returns musicdef corresponding to music with given identifier. For example, `S_FindMusicCredit("kmap01")` will return
|
||||
musicdef for green hills music.
|
||||
|
||||
## musicdefs
|
||||
|
||||
Global table for all musicdefs, similar to mobjinfo, states, etc. Can take either integer indices,
|
||||
from `0` to `#musicdefs-1`, or string indices (which is equal to calling `S_FindMusicCredit`).
|
||||
|
||||
## addHook("MusicCredit", function(musicdef))
|
||||
|
||||
Hook is called whenever `S_ShowMusicCredit` (either from game or mod) is called. Takes musicdef as only argument, returning true
|
||||
will overwrite vanilla behavior (not show music credit), can be used to implement custom music credit pop-ups.
|
||||
|
||||
# Other changes
|
||||
|
||||
## P_PlayRinglossSound(source, damager)
|
||||
|
||||
@@ -13,6 +13,7 @@ f_finale.c
|
||||
f_wipe.c
|
||||
filesrch.c
|
||||
g_game.c
|
||||
g_demo.c
|
||||
g_input.c
|
||||
hu_stuff.c
|
||||
i_tcp.c
|
||||
@@ -28,6 +29,7 @@ m_cond.c
|
||||
m_fixed.c
|
||||
m_menu.c
|
||||
m_textinput.c
|
||||
m_emotes.cpp
|
||||
m_misc.c
|
||||
m_perfstats.c
|
||||
m_queue.c
|
||||
@@ -78,6 +80,7 @@ p_tick.c
|
||||
p_user.c
|
||||
k_director.c
|
||||
k_kart.c
|
||||
k_hud.c
|
||||
k_stats.c
|
||||
lua_baselib.c
|
||||
lua_blockmaplib.c
|
||||
|
||||
+26
-22
@@ -40,6 +40,7 @@
|
||||
#include "g_game.h"
|
||||
#include "g_input.h"
|
||||
#include "hu_stuff.h"
|
||||
#include "m_emotes.h"
|
||||
#include "i_sound.h"
|
||||
#include "i_system.h"
|
||||
#include "i_time.h"
|
||||
@@ -72,6 +73,7 @@
|
||||
#include "d_protocol.h"
|
||||
#include "m_perfstats.h"
|
||||
#include "k_kart.h"
|
||||
#include "k_hud.h"
|
||||
|
||||
#include "core/memory.h"
|
||||
|
||||
@@ -1242,32 +1244,32 @@ static boolean AddIWAD(void)
|
||||
}
|
||||
|
||||
// extra graphic patches for saturn specific thingies
|
||||
boolean found_extra_kart = false;
|
||||
boolean found_extra_kart = false;
|
||||
boolean found_extra2_kart = false;
|
||||
boolean found_extra3_kart = false;
|
||||
|
||||
boolean xtra_speedo = false; // extra speedometer check
|
||||
boolean xtra_speedo_clr = false; // extra speedometer colour check
|
||||
boolean xtra_speedo3 = false; // 80x 11 extra speedometer check
|
||||
boolean xtra_speedo_clr3 = false; // 80x 11 extra speedometer colour check
|
||||
boolean achi_speedo = false; // achiiro speedometer check
|
||||
boolean achi_speedo_clr = false; // extra speedometer colour check
|
||||
boolean dial_speedo = false; // dial speedometer check
|
||||
boolean dial_speedo_clr = false; // dial speedometer colour check
|
||||
boolean kartz_speedo = false; // kartZ speedo
|
||||
boolean xtra_speedo = false; // extra speedometer check
|
||||
boolean xtra_speedo_clr = false; // extra speedometer colour check
|
||||
boolean xtra_speedo3 = false; // 80x 11 extra speedometer check
|
||||
boolean xtra_speedo_clr3 = false; // 80x 11 extra speedometer colour check
|
||||
boolean achi_speedo = false; // achiiro speedometer check
|
||||
boolean achi_speedo_clr = false; // extra speedometer colour check
|
||||
boolean dial_speedo = false; // dial speedometer check
|
||||
boolean dial_speedo_clr = false; // dial speedometer colour check
|
||||
boolean kartz_speedo = false; // kartZ speedo
|
||||
boolean kartz_speedo_smol = false; // kartZ speedo but smol
|
||||
|
||||
boolean clr_hud = false; // colour hud check
|
||||
boolean clr_hud = false; // colour hud check
|
||||
boolean driftgaugegfx_clr = false; // driftgauge colour check
|
||||
boolean big_lap = false; // bigger lap counter
|
||||
boolean big_lap_color = false; // bigger lap counter but colour
|
||||
boolean statdp = false; // stat display for extended player setup
|
||||
boolean nametaggfx = false; // Nametag stuffs
|
||||
boolean driftgaugegfx = false; // Driftgauge stuffs
|
||||
boolean multiitem_icon = false; // Extra icons for Sneakers, Banana and Jawz
|
||||
boolean joystickicon = false; // Extra icons for the joystick input display
|
||||
boolean minidoticon = false; // Dot graphic for minimap player angle display
|
||||
boolean minilighticon = false; // mkwii-style minimap headlight
|
||||
boolean big_lap = false; // bigger lap counter
|
||||
boolean big_lap_color = false; // bigger lap counter but colour
|
||||
boolean statdp = false; // stat display for extended player setup
|
||||
boolean nametaggfx = false; // Nametag stuffs
|
||||
boolean driftgaugegfx = false; // Driftgauge stuffs
|
||||
boolean multiitem_icon = false; // Extra icons for Sneakers, Banana and Jawz
|
||||
boolean joystickicon = false; // Extra icons for the joystick input display
|
||||
boolean minidoticon = false; // Dot graphic for minimap player angle display
|
||||
boolean minilighticon = false; // mkwii-style minimap headlight
|
||||
//
|
||||
|
||||
static void IdentifyVersion(void)
|
||||
@@ -1840,7 +1842,7 @@ void D_SRB2Main(void)
|
||||
{
|
||||
name = lumpinfo->name;
|
||||
|
||||
if (name[0] == 'M' && name[1] == 'A' && name[2] == 'P') // Ignore the headers
|
||||
if (memcmp(name, "MAP", 3) == 0) // Ignore the headers
|
||||
{
|
||||
INT16 num;
|
||||
if (name[5] != '\0')
|
||||
@@ -1870,7 +1872,7 @@ void D_SRB2Main(void)
|
||||
{
|
||||
name = lumpinfo->name;
|
||||
|
||||
if (name[0] == 'M' && name[1] == 'A' && name[2] == 'P') // Ignore the headers
|
||||
if (memcmp(name, "MAP", 3) == 0) // Ignore the headers
|
||||
{
|
||||
INT16 num;
|
||||
if (name[5] != '\0')
|
||||
@@ -2023,6 +2025,8 @@ void D_SRB2Main(void)
|
||||
|
||||
S_InitMusicDefs();
|
||||
|
||||
M_InitEmotes();
|
||||
|
||||
CONS_Printf("ST_Init(): Init status bar.\n");
|
||||
ST_Init();
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "i_system.h"
|
||||
#include "g_game.h"
|
||||
#include "hu_stuff.h"
|
||||
#include "m_emotes.h"
|
||||
#include "g_input.h"
|
||||
#include "m_menu.h"
|
||||
#include "r_local.h"
|
||||
@@ -912,6 +913,8 @@ void D_RegisterClientCommands(void)
|
||||
|
||||
CV_RegisterVar(&cv_keyboardlayout);
|
||||
|
||||
CV_RegisterVar(&cv_emotes);
|
||||
|
||||
// time attack ghost options are also saved to config
|
||||
CV_RegisterVar(&cv_ghost_besttime);
|
||||
CV_RegisterVar(&cv_ghost_bestlap);
|
||||
@@ -1048,7 +1051,9 @@ void D_RegisterClientCommands(void)
|
||||
CV_RegisterVar(&cv_verticallook[i]);
|
||||
}
|
||||
|
||||
CV_RegisterVar(&cv_resyncdemo);
|
||||
CV_RegisterVar(&cv_demodateformat);
|
||||
|
||||
CV_RegisterVar(&cv_showspecstuff);
|
||||
|
||||
// ingame object placing
|
||||
|
||||
+4070
File diff suppressed because it is too large.
Load diff
+191
@@ -0,0 +1,191 @@
|
||||
// SONIC ROBO BLAST 2 KART
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2020 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 g_demo.h
|
||||
/// \brief Demo recording and playback
|
||||
|
||||
#ifndef __G_DEMO__
|
||||
#define __G_DEMO__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "doomdef.h"
|
||||
#include "doomstat.h"
|
||||
#include "d_event.h"
|
||||
#include "p_saveg.h"
|
||||
#include "m_textinput.h"
|
||||
|
||||
extern savebuffer_t demobuf;
|
||||
|
||||
// demoplaying back and demo recording
|
||||
extern consvar_t cv_recordmultiplayerdemos, cv_netdemosyncquality, cv_maxdemosize, cv_demochangemap;
|
||||
extern consvar_t cv_demodateformat;
|
||||
extern consvar_t cv_resyncdemo;
|
||||
|
||||
// Publicly-accessible demo vars
|
||||
struct demovars_s {
|
||||
char titlename[65];
|
||||
textinput_t titlenameinput;
|
||||
boolean recording, playback, timing;
|
||||
UINT16 version; // Current file format of the demo being played
|
||||
boolean title; // Title Screen demo can be cancelled by any key
|
||||
boolean rewinding; // Rewind in progress
|
||||
|
||||
boolean loadfiles, ignorefiles; // Demo file loading options
|
||||
boolean fromtitle; // SRB2Kart: Don't stop the music
|
||||
boolean inreplayhut; // Go back to replayhut after demos
|
||||
boolean quitafterplaying; // quit after playing a demo from cmdline
|
||||
boolean deferstart; // don't start playing demo right away
|
||||
|
||||
tic_t savebutton; // Used to determine when the local player can choose to save the replay while the race is still going
|
||||
enum {
|
||||
DSM_NOTSAVING,
|
||||
DSM_WILLAUTOSAVE,
|
||||
DSM_TITLEENTRY,
|
||||
DSM_WILLSAVE,
|
||||
DSM_SAVED
|
||||
} savemode;
|
||||
};
|
||||
|
||||
extern struct demovars_s demo;
|
||||
|
||||
typedef enum {
|
||||
MD_NOTLOADED,
|
||||
MD_LOADED,
|
||||
MD_SUBDIR,
|
||||
MD_OUTDATED,
|
||||
MD_INVALID
|
||||
} menudemotype_e;
|
||||
|
||||
typedef struct menudemo_s {
|
||||
char filepath[256];
|
||||
menudemotype_e type;
|
||||
|
||||
char title[65]; // Null-terminated for string prints
|
||||
char date[11]; // date when replay was recorded
|
||||
char version[12]; // combined version and subversion
|
||||
UINT16 map;
|
||||
UINT8 addonstatus; // What do we need to do addon-wise to play this demo?
|
||||
UINT8 gametype;
|
||||
UINT8 kartspeed; // Add OR DF_ENCORE for encore mode, idk
|
||||
UINT8 numlaps;
|
||||
|
||||
struct {
|
||||
UINT8 ranking;
|
||||
char name[17];
|
||||
UINT8 skin, color;
|
||||
UINT32 timeorscore;
|
||||
} standings[MAXPLAYERS];
|
||||
} menudemo_t;
|
||||
|
||||
extern mobj_t *metalplayback;
|
||||
|
||||
// Only called by startup code.
|
||||
void G_RecordDemo(const char *name);
|
||||
void G_RecordMetal(void);
|
||||
void G_BeginRecording(void);
|
||||
void G_BeginMetal(void);
|
||||
|
||||
// Only called by shutdown code.
|
||||
void G_WriteStanding(UINT8 ranking, char *name, INT32 skinnum, UINT8 color, UINT32 val);
|
||||
void G_SetDemoTime(UINT32 ptime, UINT32 plap);
|
||||
UINT8 G_CmpDemoTime(char *oldname, char *newname);
|
||||
|
||||
void G_LoadDemoInfo(menudemo_t *pdemo);
|
||||
void G_LoadDemoTitle(menudemo_t *pdemo); // For use in replay search feature
|
||||
void G_DeferedPlayDemo(const char *demo);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GHC_NORMAL = 0,
|
||||
GHC_SUPER,
|
||||
GHC_FIREFLOWER,
|
||||
GHC_INVINCIBLE
|
||||
} ghostcolor_t;
|
||||
|
||||
extern UINT8 demo_extradata[MAXPLAYERS];
|
||||
extern UINT8 demo_writerng;
|
||||
#define DXD_RESPAWN 0x01 // "respawn" command in console
|
||||
#define DXD_SKIN 0x02 // skin changed
|
||||
#define DXD_NAME 0x04 // name changed
|
||||
#define DXD_COLOR 0x08 // color changed
|
||||
#define DXD_PLAYSTATE 0x10 // state changed between playing, spectating, or not in-game
|
||||
|
||||
#define DXD_PST_PLAYING 0x01
|
||||
#define DXD_PST_SPECTATING 0x02
|
||||
#define DXD_PST_LEFT 0x03
|
||||
|
||||
// Record/playback tics
|
||||
void G_ReadDemoExtraData(void);
|
||||
void G_WriteDemoExtraData(void);
|
||||
void G_ReadDemoTiccmd(ticcmd_t *cmd, INT32 playernum);
|
||||
void G_WriteDemoTiccmd(ticcmd_t *cmd, INT32 playernum);
|
||||
void G_GhostAddThok(INT32 playernum);
|
||||
void G_GhostAddSpin(INT32 playernum);
|
||||
void G_GhostAddRev(INT32 playernum);
|
||||
void G_GhostAddColor(INT32 playernum, ghostcolor_t color);
|
||||
void G_GhostAddFlip(INT32 playernum);
|
||||
void G_GhostAddScale(INT32 playernum, fixed_t scale);
|
||||
void G_GhostAddHit(INT32 playernum, mobj_t *victim);
|
||||
void G_WriteAllGhostTics(void);
|
||||
void G_WriteGhostTic(mobj_t *ghost, INT32 playernum);
|
||||
void G_ConsAllGhostTics(void);
|
||||
void G_ConsGhostTic(INT32 playernum);
|
||||
void G_GhostTicker(void);
|
||||
|
||||
void G_InitDemoRewind(void);
|
||||
void G_StoreRewindInfo(void);
|
||||
void G_PreviewRewind(tic_t previewtime);
|
||||
void G_ConfirmRewind(tic_t rewindtime);
|
||||
|
||||
void G_ReadMetalTic(mobj_t *metal);
|
||||
void G_WriteMetalTic(mobj_t *metal);
|
||||
void G_SaveMetal(UINT8 **buffer);
|
||||
void G_LoadMetal(UINT8 **buffer);
|
||||
|
||||
// Your naming conventions are stupid and useless.
|
||||
// There is no conflict here.
|
||||
typedef struct demoghost {
|
||||
UINT8 checksum[16];
|
||||
UINT8 *buffer, *p, color;
|
||||
UINT16 version;
|
||||
mobj_t oldmo, *mo;
|
||||
struct demoghost *next;
|
||||
} demoghost;
|
||||
extern demoghost *ghosts;
|
||||
|
||||
// G_CheckDemoExtraFiles: checks if our loaded WAD list matches the demo's.
|
||||
#define DFILE_ERROR_NOTLOADED 0x01 // Files are not loaded, but can be without a restart.
|
||||
#define DFILE_ERROR_OUTOFORDER 0x02 // Files are loaded, but out of order.
|
||||
#define DFILE_ERROR_INCOMPLETEOUTOFORDER 0x03 // Some files are loaded out of order, but others are not.
|
||||
#define DFILE_ERROR_CANNOTLOAD 0x04 // Files are missing and cannot be loaded.
|
||||
#define DFILE_ERROR_EXTRAFILES 0x05 // Extra files outside of the replay's file list are loaded.
|
||||
|
||||
void G_ResetDemoRecording(void);
|
||||
void G_DoPlayDemo(char *defdemoname);
|
||||
void G_TimeDemo(const char *name);
|
||||
void G_AddGhost(char *defdemoname);
|
||||
void G_UpdateStaffGhostName(lumpnum_t l);
|
||||
void G_DoPlayMetal(void);
|
||||
void G_DoneLevelLoad(void);
|
||||
void G_StopMetalDemo(void);
|
||||
ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(void);
|
||||
void G_StopDemo(void);
|
||||
boolean G_CheckDemoStatus(void);
|
||||
void G_SaveDemo(void);
|
||||
boolean G_DemoTitleResponder(event_t *ev);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // __G_DEMO__
|
||||
-4008
File diff suppressed because it is too large.
Load diff
+1
-164
@@ -21,6 +21,7 @@ extern "C" {
|
||||
#include "doomdef.h"
|
||||
#include "doomstat.h"
|
||||
#include "d_event.h"
|
||||
#include "g_demo.h"
|
||||
#include "p_saveg.h"
|
||||
#include "m_textinput.h"
|
||||
|
||||
@@ -38,75 +39,6 @@ extern INT32 player_name_changes[MAXPLAYERS];
|
||||
extern player_t players[MAXPLAYERS];
|
||||
extern boolean playeringame[MAXPLAYERS];
|
||||
|
||||
extern savebuffer_t demobuf;
|
||||
|
||||
// ======================================
|
||||
// DEMO playback/recording related stuff.
|
||||
// ======================================
|
||||
|
||||
// demoplaying back and demo recording
|
||||
extern consvar_t cv_recordmultiplayerdemos, cv_netdemosyncquality, cv_maxdemosize, cv_demochangemap;
|
||||
extern consvar_t cv_demodateformat;
|
||||
|
||||
// Publicly-accessible demo vars
|
||||
struct demovars_s {
|
||||
char titlename[65];
|
||||
textinput_t titlenameinput;
|
||||
boolean recording, playback, timing;
|
||||
UINT16 version; // Current file format of the demo being played
|
||||
boolean title; // Title Screen demo can be cancelled by any key
|
||||
boolean rewinding; // Rewind in progress
|
||||
|
||||
boolean loadfiles, ignorefiles; // Demo file loading options
|
||||
boolean fromtitle; // SRB2Kart: Don't stop the music
|
||||
boolean inreplayhut; // Go back to replayhut after demos
|
||||
boolean quitafterplaying; // quit after playing a demo from cmdline
|
||||
boolean deferstart; // don't start playing demo right away
|
||||
|
||||
tic_t savebutton; // Used to determine when the local player can choose to save the replay while the race is still going
|
||||
enum {
|
||||
DSM_NOTSAVING,
|
||||
DSM_WILLAUTOSAVE,
|
||||
DSM_TITLEENTRY,
|
||||
DSM_WILLSAVE,
|
||||
DSM_SAVED
|
||||
} savemode;
|
||||
};
|
||||
|
||||
extern struct demovars_s demo;
|
||||
|
||||
typedef enum {
|
||||
MD_NOTLOADED,
|
||||
MD_LOADED,
|
||||
MD_SUBDIR,
|
||||
MD_OUTDATED,
|
||||
MD_INVALID
|
||||
} menudemotype_e;
|
||||
|
||||
typedef struct menudemo_s {
|
||||
char filepath[256];
|
||||
menudemotype_e type;
|
||||
|
||||
char title[65]; // Null-terminated for string prints
|
||||
char date[11]; // date when replay was recorded
|
||||
char version[12]; // combined version and subversion
|
||||
UINT16 map;
|
||||
UINT8 addonstatus; // What do we need to do addon-wise to play this demo?
|
||||
UINT8 gametype;
|
||||
UINT8 kartspeed; // Add OR DF_ENCORE for encore mode, idk
|
||||
UINT8 numlaps;
|
||||
|
||||
struct {
|
||||
UINT8 ranking;
|
||||
char name[17];
|
||||
UINT8 skin, color;
|
||||
UINT32 timeorscore;
|
||||
} standings[MAXPLAYERS];
|
||||
} menudemo_t;
|
||||
|
||||
|
||||
extern mobj_t *metalplayback;
|
||||
|
||||
// gametic at level start
|
||||
extern tic_t levelstarttic;
|
||||
|
||||
@@ -290,10 +222,6 @@ void G_SpawnPlayer(INT32 playernum, boolean starpost);
|
||||
void G_DeferedInitNew(boolean pencoremode, const char *mapname, INT32 pickedchar,
|
||||
UINT8 ssplayers, boolean FLS);
|
||||
|
||||
void G_LoadDemoInfo(menudemo_t *pdemo);
|
||||
void G_LoadDemoTitle(menudemo_t *pdemo); // For use in replay search feature
|
||||
void G_DeferedPlayDemo(const char *demo);
|
||||
|
||||
// Can be called by the startup code or M_Responder, calls P_SetupLevel.
|
||||
void G_LoadGame(UINT32 slot, INT16 mapoverride);
|
||||
|
||||
@@ -301,97 +229,6 @@ void G_SaveGameData(boolean force);
|
||||
|
||||
void G_SaveGame(UINT32 slot);
|
||||
|
||||
// Only called by startup code.
|
||||
void G_RecordDemo(const char *name);
|
||||
void G_RecordMetal(void);
|
||||
void G_BeginRecording(void);
|
||||
void G_BeginMetal(void);
|
||||
|
||||
// Only called by shutdown code.
|
||||
void G_WriteStanding(UINT8 ranking, char *name, INT32 skinnum, UINT8 color, UINT32 val);
|
||||
void G_SetDemoTime(UINT32 ptime, UINT32 plap);
|
||||
UINT8 G_CmpDemoTime(char *oldname, char *newname);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GHC_NORMAL = 0,
|
||||
GHC_SUPER,
|
||||
GHC_FIREFLOWER,
|
||||
GHC_INVINCIBLE
|
||||
} ghostcolor_t;
|
||||
|
||||
extern UINT8 demo_extradata[MAXPLAYERS];
|
||||
extern UINT8 demo_writerng;
|
||||
#define DXD_RESPAWN 0x01 // "respawn" command in console
|
||||
#define DXD_SKIN 0x02 // skin changed
|
||||
#define DXD_NAME 0x04 // name changed
|
||||
#define DXD_COLOR 0x08 // color changed
|
||||
#define DXD_PLAYSTATE 0x10 // state changed between playing, spectating, or not in-game
|
||||
|
||||
#define DXD_PST_PLAYING 0x01
|
||||
#define DXD_PST_SPECTATING 0x02
|
||||
#define DXD_PST_LEFT 0x03
|
||||
|
||||
// Record/playback tics
|
||||
void G_ReadDemoExtraData(void);
|
||||
void G_WriteDemoExtraData(void);
|
||||
void G_ReadDemoTiccmd(ticcmd_t *cmd, INT32 playernum);
|
||||
void G_WriteDemoTiccmd(ticcmd_t *cmd, INT32 playernum);
|
||||
void G_GhostAddThok(INT32 playernum);
|
||||
void G_GhostAddSpin(INT32 playernum);
|
||||
void G_GhostAddRev(INT32 playernum);
|
||||
void G_GhostAddColor(INT32 playernum, ghostcolor_t color);
|
||||
void G_GhostAddFlip(INT32 playernum);
|
||||
void G_GhostAddScale(INT32 playernum, fixed_t scale);
|
||||
void G_GhostAddHit(INT32 playernum, mobj_t *victim);
|
||||
void G_WriteAllGhostTics(void);
|
||||
void G_WriteGhostTic(mobj_t *ghost, INT32 playernum);
|
||||
void G_ConsAllGhostTics(void);
|
||||
void G_ConsGhostTic(INT32 playernum);
|
||||
void G_GhostTicker(void);
|
||||
|
||||
void G_InitDemoRewind(void);
|
||||
void G_StoreRewindInfo(void);
|
||||
void G_PreviewRewind(tic_t previewtime);
|
||||
void G_ConfirmRewind(tic_t rewindtime);
|
||||
|
||||
void G_ReadMetalTic(mobj_t *metal);
|
||||
void G_WriteMetalTic(mobj_t *metal);
|
||||
void G_SaveMetal(UINT8 **buffer);
|
||||
void G_LoadMetal(UINT8 **buffer);
|
||||
|
||||
// Your naming conventions are stupid and useless.
|
||||
// There is no conflict here.
|
||||
typedef struct demoghost {
|
||||
UINT8 checksum[16];
|
||||
UINT8 *buffer, *p, color;
|
||||
UINT16 version;
|
||||
mobj_t oldmo, *mo;
|
||||
struct demoghost *next;
|
||||
} demoghost;
|
||||
extern demoghost *ghosts;
|
||||
|
||||
// G_CheckDemoExtraFiles: checks if our loaded WAD list matches the demo's.
|
||||
#define DFILE_ERROR_NOTLOADED 0x01 // Files are not loaded, but can be without a restart.
|
||||
#define DFILE_ERROR_OUTOFORDER 0x02 // Files are loaded, but out of order.
|
||||
#define DFILE_ERROR_INCOMPLETEOUTOFORDER 0x03 // Some files are loaded out of order, but others are not.
|
||||
#define DFILE_ERROR_CANNOTLOAD 0x04 // Files are missing and cannot be loaded.
|
||||
#define DFILE_ERROR_EXTRAFILES 0x05 // Extra files outside of the replay's file list are loaded.
|
||||
|
||||
void G_ResetDemoRecording(void);
|
||||
void G_DoPlayDemo(char *defdemoname);
|
||||
void G_TimeDemo(const char *name);
|
||||
void G_AddGhost(char *defdemoname);
|
||||
void G_UpdateStaffGhostName(lumpnum_t l);
|
||||
void G_DoPlayMetal(void);
|
||||
void G_DoneLevelLoad(void);
|
||||
void G_StopMetalDemo(void);
|
||||
ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(void);
|
||||
void G_StopDemo(void);
|
||||
boolean G_CheckDemoStatus(void);
|
||||
void G_SaveDemo(void);
|
||||
boolean G_DemoTitleResponder(event_t *ev);
|
||||
|
||||
#define G_GametypeHasTeams() (G_IsGameType(GT_TEAMMATCH) || G_IsGameType(GT_CTF))
|
||||
#define G_BattleGametype() (G_IsGameType(GT_MATCH))
|
||||
#define G_RaceGametype() (G_IsGameType(GT_RACE))
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
hw_bsp.c
|
||||
hw_draw.c
|
||||
hw_main.c
|
||||
hw_main.cpp
|
||||
hw_clip.c
|
||||
hw_md2.c
|
||||
hw_cache.c
|
||||
|
||||
+52
-51
@@ -25,22 +25,23 @@ GLMipmap_t *current_texture = NULL;
|
||||
|
||||
boolean currently_batching = false;
|
||||
|
||||
FOutVector* finalVertexArray = NULL;// contains subset of sorted vertices and texture coordinates to be sent to gpu
|
||||
FOutVector* finalVertexArray = NULL;// contains subset of sorted vertices and texture coordinates to be sent to gpu
|
||||
UINT32* finalVertexIndexArray = NULL;// contains indexes for glDrawElements, taking into account fan->triangles conversion
|
||||
// NOTE have this alloced as 3x finalVertexArray size
|
||||
int finalVertexArrayAllocSize = 65536;
|
||||
|
||||
//GLubyte* colorArray = NULL;// contains color data to be sent to gpu, if needed
|
||||
//int colorArrayAllocSize = 65536;
|
||||
// not gonna use this for now, just sort by color and change state when it changes
|
||||
// later maybe when using vertex attributes if it's needed
|
||||
|
||||
PolygonArrayEntry* polygonArray = NULL;// contains the polygon data from DrawPolygon, waiting to be processed
|
||||
int polygonArraySize = 0;
|
||||
PolygonArrayEntry **polygonArraySorted = NULL;// contains sorted pointers to polygonArray
|
||||
PolygonArrayEntry* polygonArray = NULL ;// contains the polygon data from DrawPolygon, waiting to be processed
|
||||
PolygonArrayEntry **polygonArraySorted = NULL; // contains sorted pointers to polygonArray
|
||||
int polygonArraySize = 0;
|
||||
int polygonArrayAllocSize = 65536;
|
||||
|
||||
FOutVector* unsortedVertexArray = NULL;// contains unsorted vertices and texture coordinates from DrawPolygon
|
||||
int unsortedVertexArraySize = 0;
|
||||
FOutVector* unsortedVertexArray = NULL; // contains unsorted vertices and texture coordinates from DrawPolygon
|
||||
int unsortedVertexArraySize = 0;
|
||||
int unsortedVertexArrayAllocSize = 65536;
|
||||
|
||||
// Enables batching mode. HWR_ProcessPolygon will collect polygons instead of passing them directly to the rendering backend.
|
||||
@@ -55,11 +56,11 @@ void HWR_StartBatching(void)
|
||||
// init arrays if that has not been done yet
|
||||
if (!finalVertexArray)
|
||||
{
|
||||
finalVertexArray = malloc(finalVertexArrayAllocSize * sizeof(FOutVector));
|
||||
finalVertexArray = malloc(finalVertexArrayAllocSize * sizeof(FOutVector));
|
||||
finalVertexIndexArray = malloc(finalVertexArrayAllocSize * 3 * sizeof(UINT32));
|
||||
polygonArray = malloc(polygonArrayAllocSize * sizeof(PolygonArrayEntry));
|
||||
polygonArraySorted = malloc(polygonArrayAllocSize * sizeof(PolygonArrayEntry *));
|
||||
unsortedVertexArray = malloc(unsortedVertexArrayAllocSize * sizeof(FOutVector));
|
||||
polygonArray = malloc(polygonArrayAllocSize * sizeof(PolygonArrayEntry));
|
||||
polygonArraySorted = malloc(polygonArrayAllocSize * sizeof(PolygonArrayEntry *));
|
||||
unsortedVertexArray = malloc(unsortedVertexArrayAllocSize * sizeof(FOutVector));
|
||||
}
|
||||
|
||||
currently_batching = true;
|
||||
@@ -131,13 +132,13 @@ void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPt
|
||||
|
||||
static int comparePolygons(const void *p1, const void *p2)
|
||||
{
|
||||
const PolygonArrayEntry *poly1 = *(PolygonArrayEntry *const *)p1;
|
||||
const PolygonArrayEntry *poly2 = *(PolygonArrayEntry *const *)p2;
|
||||
int diff;
|
||||
INT64 diff64;
|
||||
const PolygonArrayEntry *poly1 = *(PolygonArrayEntry *const *)p1;
|
||||
const PolygonArrayEntry *poly2 = *(PolygonArrayEntry *const *)p2;
|
||||
|
||||
int shader1 = (poly1->polyFlags & PF_NoTexture || poly1->horizonSpecial) ? -1 : poly1->shader;
|
||||
int shader2 = (poly2->polyFlags & PF_NoTexture || poly2->horizonSpecial) ? -1 : poly2->shader;
|
||||
const int shader1 = (poly1->polyFlags & PF_NoTexture || poly1->horizonSpecial) ? -1 : poly1->shader;
|
||||
const int shader2 = (poly2->polyFlags & PF_NoTexture || poly2->horizonSpecial) ? -1 : poly2->shader;
|
||||
|
||||
// skywalls and horizon lines must retain their order for horizon lines to work
|
||||
if (shader1 == -1 && shader2 == -1)
|
||||
@@ -173,13 +174,13 @@ static int comparePolygons(const void *p1, const void *p2)
|
||||
|
||||
static int comparePolygonsNoShaders(const void *p1, const void *p2)
|
||||
{
|
||||
PolygonArrayEntry *poly1 = *(PolygonArrayEntry *const *)p1;
|
||||
PolygonArrayEntry *poly2 = *(PolygonArrayEntry *const *)p2;
|
||||
int diff;
|
||||
INT64 diff64;
|
||||
const PolygonArrayEntry *poly1 = *(PolygonArrayEntry *const *)p1;
|
||||
const PolygonArrayEntry *poly2 = *(PolygonArrayEntry *const *)p2;
|
||||
|
||||
GLMipmap_t *texture1 = (poly1->polyFlags & PF_NoTexture || poly1->horizonSpecial) ? NULL : poly1->texture;
|
||||
GLMipmap_t *texture2 = (poly2->polyFlags & PF_NoTexture || poly2->horizonSpecial) ? NULL : poly2->texture;
|
||||
const GLMipmap_t *texture1 = (poly1->polyFlags & PF_NoTexture || poly1->horizonSpecial) ? NULL : poly1->texture;
|
||||
const GLMipmap_t *texture2 = (poly2->polyFlags & PF_NoTexture || poly2->horizonSpecial) ? NULL : poly2->texture;
|
||||
|
||||
// skywalls and horizon lines must retain their order for horizon lines to work
|
||||
if (!texture1 && !texture2)
|
||||
@@ -203,17 +204,16 @@ static int comparePolygonsNoShaders(const void *p1, const void *p2)
|
||||
// the rendering backend to draw them.
|
||||
void HWR_RenderBatches(void)
|
||||
{
|
||||
int finalVertexWritePos = 0;// position in finalVertexArray
|
||||
int finalIndexWritePos = 0;// position in finalVertexIndexArray
|
||||
|
||||
int polygonReadPos = 0;// position in polygonArraySorted
|
||||
int finalVertexWritePos = 0; // position in finalVertexArray
|
||||
int finalIndexWritePos = 0; // position in finalVertexIndexArray
|
||||
int polygonReadPos = 0; // position in polygonArraySorted
|
||||
|
||||
int currentShader;
|
||||
int nextShader = 0;
|
||||
GLMipmap_t *currentTexture = NULL;
|
||||
GLMipmap_t *nextTexture = NULL;
|
||||
FBITFIELD currentPolyFlags = 0;
|
||||
FBITFIELD nextPolyFlags = 0;
|
||||
GLMipmap_t *currentTexture = NULL;
|
||||
GLMipmap_t *nextTexture = NULL;
|
||||
FBITFIELD currentPolyFlags = 0;
|
||||
FBITFIELD nextPolyFlags = 0;
|
||||
FSurfaceInfo currentSurfaceInfo;
|
||||
FSurfaceInfo nextSurfaceInfo;
|
||||
|
||||
@@ -224,8 +224,8 @@ void HWR_RenderBatches(void)
|
||||
I_Error("HWR_RenderBatches called without starting batching");
|
||||
}
|
||||
|
||||
nextSurfaceInfo.LightInfo.fade_end = 0;
|
||||
nextSurfaceInfo.LightInfo.fade_start = 0;
|
||||
nextSurfaceInfo.LightInfo.fade_end = 0;
|
||||
nextSurfaceInfo.LightInfo.fade_start = 0;
|
||||
nextSurfaceInfo.LightInfo.light_level = 0;
|
||||
nextSurfaceInfo.LightInfo.directional = false;
|
||||
|
||||
@@ -243,7 +243,7 @@ void HWR_RenderBatches(void)
|
||||
ps_hw_numpolys.value.i = polygonArraySize;
|
||||
ps_hw_numcalls.value.i = ps_hw_numverts.value.i = 0;
|
||||
ps_hw_numshaders.value.i = ps_hw_numtextures.value.i
|
||||
= ps_hw_numpolyflags.value.i = ps_hw_numcolors.value.i = 1;
|
||||
= ps_hw_numpolyflags.value.i = ps_hw_numcolors.value.i = 1;
|
||||
|
||||
// init polygonArraySorted
|
||||
for (i = 0; i < polygonArraySize; i++)
|
||||
@@ -253,10 +253,7 @@ void HWR_RenderBatches(void)
|
||||
|
||||
// sort polygons
|
||||
PS_START_TIMING(ps_hw_batchsorttime);
|
||||
if (cv_glshaders.value && gl_shadersavailable)
|
||||
qs22j(polygonArraySorted, polygonArraySize, sizeof(PolygonArrayEntry *), comparePolygons);
|
||||
else
|
||||
qs22j(polygonArraySorted, polygonArraySize, sizeof(PolygonArrayEntry *), comparePolygonsNoShaders);
|
||||
qs22j(polygonArraySorted, polygonArraySize, sizeof(PolygonArrayEntry *), (HWR_UseShader() ? comparePolygons : comparePolygonsNoShaders));
|
||||
PS_STOP_TIMING(ps_hw_batchsorttime);
|
||||
|
||||
// sort order
|
||||
@@ -268,16 +265,16 @@ void HWR_RenderBatches(void)
|
||||
|
||||
PS_START_TIMING(ps_hw_batchdrawtime);
|
||||
|
||||
currentShader = polygonArraySorted[0]->shader;
|
||||
currentTexture = polygonArraySorted[0]->texture;
|
||||
currentPolyFlags = polygonArraySorted[0]->polyFlags;
|
||||
currentShader = polygonArraySorted[0]->shader;
|
||||
currentTexture = polygonArraySorted[0]->texture;
|
||||
currentPolyFlags = polygonArraySorted[0]->polyFlags;
|
||||
currentSurfaceInfo = polygonArraySorted[0]->surf;
|
||||
// For now, will sort and track the colors. Vertex attributes could be used instead of uniforms
|
||||
// and a color array could replace the color calls.
|
||||
|
||||
// set state for first batch
|
||||
|
||||
if (cv_glshaders.value && gl_shadersavailable)
|
||||
if (HWR_UseShader())
|
||||
{
|
||||
GL_SetShader(currentShader);
|
||||
}
|
||||
@@ -302,16 +299,17 @@ void HWR_RenderBatches(void)
|
||||
// steps:
|
||||
// write vertices
|
||||
// check for changes or end, otherwise go back to writing
|
||||
// changes will affect the next vars and the change bools
|
||||
// end could set flag for stopping
|
||||
// changes will affect the next vars and the change bools
|
||||
// end could set flag for stopping
|
||||
// execute draw call
|
||||
// could check ending flag here
|
||||
// change states according to next vars and change bools, updating the current vars and reseting the bools
|
||||
// reset write pos
|
||||
// repeat loop
|
||||
|
||||
PolygonArrayEntry *entry = polygonArraySorted[polygonReadPos++];
|
||||
int numVerts = entry->numVerts;
|
||||
const PolygonArrayEntry *entry = polygonArraySorted[polygonReadPos++];
|
||||
const int numVerts = entry->numVerts;
|
||||
|
||||
// before writing, check if there is enough room
|
||||
// using 'while' instead of 'if' here makes sure that there will *always* be enough room.
|
||||
// probably never will this loop run more than once though
|
||||
@@ -323,13 +321,15 @@ void HWR_RenderBatches(void)
|
||||
// going from fans to triangles increases vertex count to 3x
|
||||
finalVertexIndexArray = realloc(finalVertexIndexArray, finalVertexArrayAllocSize * 3 * sizeof(UINT32));
|
||||
}
|
||||
|
||||
// write the vertices of the polygon
|
||||
memcpy(&finalVertexArray[finalVertexWritePos], &unsortedVertexArray[entry->vertsIndex],
|
||||
numVerts * sizeof(FOutVector));
|
||||
memcpy(&finalVertexArray[finalVertexWritePos], &unsortedVertexArray[entry->vertsIndex], numVerts * sizeof(FOutVector));
|
||||
|
||||
// write the indexes, pointing to the fan vertexes but in triangles format
|
||||
firstIndex = finalVertexWritePos;
|
||||
lastIndex = finalVertexWritePos + numVerts;
|
||||
finalVertexWritePos += 2;
|
||||
|
||||
while (finalVertexWritePos < lastIndex)
|
||||
{
|
||||
finalVertexIndexArray[finalIndexWritePos++] = firstIndex;
|
||||
@@ -344,16 +344,16 @@ void HWR_RenderBatches(void)
|
||||
else
|
||||
{
|
||||
// check if a state change is required, set the change bools and next vars
|
||||
PolygonArrayEntry *nextEntry = polygonArraySorted[polygonReadPos];
|
||||
nextShader = nextEntry->shader;
|
||||
nextTexture = nextEntry->texture;
|
||||
nextPolyFlags = nextEntry->polyFlags;
|
||||
const PolygonArrayEntry *nextEntry = polygonArraySorted[polygonReadPos];
|
||||
nextShader = nextEntry->shader;
|
||||
nextTexture = nextEntry->texture;
|
||||
nextPolyFlags = nextEntry->polyFlags;
|
||||
nextSurfaceInfo = nextEntry->surf;
|
||||
|
||||
if (nextPolyFlags & PF_NoTexture)
|
||||
nextTexture = 0;
|
||||
|
||||
if (currentShader != nextShader && cv_glshaders.value && gl_shadersavailable)
|
||||
if (currentShader != nextShader && HWR_UseShader())
|
||||
{
|
||||
changeState = true;
|
||||
changeShader = true;
|
||||
@@ -371,7 +371,7 @@ void HWR_RenderBatches(void)
|
||||
changePolyFlags = true;
|
||||
}
|
||||
|
||||
if (cv_glshaders.value && gl_shadersavailable)
|
||||
if (HWR_UseShader())
|
||||
{
|
||||
if (currentSurfaceInfo.PolyColor.rgba != nextSurfaceInfo.PolyColor.rgba ||
|
||||
currentSurfaceInfo.TintColor.rgba != nextSurfaceInfo.TintColor.rgba ||
|
||||
@@ -404,7 +404,7 @@ void HWR_RenderBatches(void)
|
||||
ps_hw_numverts.value.i += finalIndexWritePos;
|
||||
// reset write positions
|
||||
finalVertexWritePos = 0;
|
||||
finalIndexWritePos = 0;
|
||||
finalIndexWritePos = 0;
|
||||
}
|
||||
else
|
||||
continue;
|
||||
@@ -450,9 +450,10 @@ void HWR_RenderBatches(void)
|
||||
|
||||
ps_hw_numcolors.value.i++;
|
||||
}
|
||||
// and that should be it?
|
||||
}
|
||||
// and that should be it?
|
||||
}
|
||||
|
||||
// reset the arrays (set sizes to 0)
|
||||
polygonArraySize = 0;
|
||||
unsortedVertexArraySize = 0;
|
||||
|
||||
@@ -13,6 +13,10 @@
|
||||
#ifndef __HWR_BATCHING_H__
|
||||
#define __HWR_BATCHING_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "hw_defs.h"
|
||||
#include "hw_data.h"
|
||||
#include "hw_gl.h"
|
||||
@@ -36,4 +40,8 @@ void HWR_SetCurrentTexture(GLMipmap_t *texture);
|
||||
void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags, int shader, boolean horizonSpecial);
|
||||
void HWR_RenderBatches(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -371,12 +371,13 @@ static poly_t *CutOutSubsecPoly(seg_t *lseg, INT32 count, poly_t *poly)
|
||||
line_t *line = lseg->linedef;
|
||||
|
||||
// portal check
|
||||
if (!gl_maphasportals && line->special == 40 && lseg->side == 0)
|
||||
if (!gl_maphasportals && line->special == PORTALSPECIAL && lseg->side == 0)
|
||||
{
|
||||
// Find the other side!
|
||||
INT32 line2 = P_FindSpecialLineFromTag(40, line->tag, -1);
|
||||
INT32 line2 = P_FindSpecialLineFromTag(PORTALSPECIAL, line->tag, -1);
|
||||
|
||||
if (line == &lines[line2])
|
||||
line2 = P_FindSpecialLineFromTag(40, line->tag, line2);
|
||||
line2 = P_FindSpecialLineFromTag(PORTALSPECIAL, line->tag, line2);
|
||||
if (line2 >= 0) // found it!
|
||||
gl_maphasportals = 1;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,10 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// OpenGL BSP clipping
|
||||
#include "../doomdef.h"
|
||||
#include "../tables.h"
|
||||
@@ -22,3 +26,7 @@ angle_t gld_FrustumAngle(angle_t tiltangle);
|
||||
void gld_FrustumSetup(void);
|
||||
boolean gld_SphereInFrustum(float x, float y, float z, float radius);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
@@ -13,6 +13,10 @@
|
||||
#ifndef __HWR_GL_H__
|
||||
#define __HWR_GL_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "../screen.h"
|
||||
|
||||
#include "hw_data.h"
|
||||
@@ -76,4 +80,8 @@ UINT32 GL_CreateLightTable(RGBA_t *hw_lighttable);
|
||||
void GL_ClearLightTables(void);
|
||||
void GL_SetScreenPalette(RGBA_t *palette);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // __HWR_GL_H__
|
||||
@@ -14,6 +14,10 @@
|
||||
#ifndef _HWR_GLOB_H_
|
||||
#define _HWR_GLOB_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "hw_defs.h"
|
||||
#include "../m_misc.h"
|
||||
#include "../r_defs.h"
|
||||
@@ -109,4 +113,8 @@ const char *HWR_GetShaderName(INT32 shader);
|
||||
|
||||
extern customshaderxlat_t shaderxlat[];
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif //_HW_GLOB_
|
||||
File diff suppressed because it is too large.
Load diff
@@ -20,6 +20,10 @@
|
||||
#ifndef __HWR_MAIN_H__
|
||||
#define __HWR_MAIN_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "hw_gl.h"
|
||||
#include "hw_glob.h"
|
||||
#include "hw_data.h"
|
||||
@@ -34,10 +38,6 @@
|
||||
|
||||
#define GLENCORE
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Startup & Shutdown the hardware mode renderer
|
||||
void HWR_Startup(void);
|
||||
void HWR_Shutdown(void);
|
||||
@@ -110,6 +110,7 @@ void HWR_AddCommands(void);
|
||||
|
||||
void HWR_RenderPlayerView(void);
|
||||
void HWR_RenderViewpoint(gl_portal_t *rootportal, const float fpov, player_t *player, int stencil_level, boolean allow_portals);
|
||||
void HWR_RenderPortalViewpoint(gl_portal_t *rootportal, const float fpov, player_t *player, int stencil_level, boolean allow_portals);
|
||||
|
||||
void HWR_ClearSkyDome(void);
|
||||
void HWR_BuildSkyDome(void);
|
||||
|
||||
@@ -1187,7 +1187,7 @@ void HWR_DrawMD2(gl_vissprite_t *spr)
|
||||
spriteinfo_t *sprinfo;
|
||||
interpmobjstate_t interp;
|
||||
|
||||
if (R_UsingFrameInterpolation() && !paused && (!cv_maxinterpdist.value || R_QuickCamDist(spr->mobj->x, spr->mobj->y) < cv_maxinterpdist.value))
|
||||
if (R_UsingFrameInterpolation() && !paused && R_CheckInterpDist(spr->mobj))
|
||||
{
|
||||
R_InterpolateMobjState(spr->mobj, rendertimefrac, &interp);
|
||||
}
|
||||
|
||||
@@ -169,7 +169,7 @@ void HWR_RenderPortal(gl_portal_t* portal, gl_portal_t* rootportal, const float
|
||||
// go to portal frame lmao
|
||||
HWR_PortalFrame(portal);
|
||||
// call HWR_RenderViewpoint
|
||||
HWR_RenderViewpoint(portal, fpov, player, stencil_level + 1, true);
|
||||
HWR_RenderPortalViewpoint(portal, fpov, player, stencil_level + 1, true);
|
||||
// return to current frame
|
||||
if (rootportal)
|
||||
HWR_PortalFrame(rootportal);
|
||||
|
||||
@@ -14,6 +14,10 @@
|
||||
#ifndef __HW_PORTAL__
|
||||
#define __HW_PORTAL__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef HWRENDER
|
||||
|
||||
#include "../doomstat.h"
|
||||
@@ -77,5 +81,9 @@ void HWR_FreePortalList(gl_portallist_t portallist);
|
||||
boolean HWR_PortalCheckPointSide(fixed_t x, fixed_t y);
|
||||
boolean HWR_PortalCheckBBox(const fixed_t *bspcoord);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}// extern "C"
|
||||
#endif
|
||||
#endif
|
||||
@@ -20,6 +20,10 @@
|
||||
#ifndef _R_OPENGL_H_
|
||||
#define _R_OPENGL_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SDL
|
||||
#define _MATH_DEFINES_DEFINED
|
||||
|
||||
@@ -143,4 +147,8 @@ typedef enum
|
||||
GLF_NOTEXENV = 0x02,
|
||||
} oglflags_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+101
-18
@@ -17,6 +17,7 @@
|
||||
|
||||
#include "m_menu.h" // gametype_cons_t
|
||||
#include "m_cond.h" // emblems
|
||||
#include "m_emotes.h"
|
||||
|
||||
#include "d_clisrv.h"
|
||||
|
||||
@@ -49,6 +50,7 @@
|
||||
|
||||
#include "s_sound.h" // song credits
|
||||
#include "k_kart.h"
|
||||
#include "k_hud.h"
|
||||
|
||||
#include "m_textinput.h"
|
||||
|
||||
@@ -93,6 +95,9 @@ static textinput_t w_chat;
|
||||
static boolean headsupactive = false;
|
||||
boolean hu_showscores; // draw rankings
|
||||
static char hu_tick;
|
||||
static tic_t hu_emoteanim = 0;
|
||||
#define MAXEMOTESUGGESTIONS 8
|
||||
static emote_t *emote_suggestions[MAXEMOTESUGGESTIONS] = {0};
|
||||
|
||||
static huddrawlist_h luahuddrawlist_scores;
|
||||
|
||||
@@ -259,8 +264,6 @@ INT32 HU_FallBackFrSpecialLetter(INT32 key)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static char cechotext[1024];
|
||||
static tic_t cechotimer = 0;
|
||||
static tic_t cechoduration = 5*TICRATE;
|
||||
@@ -1104,6 +1107,7 @@ void HU_Ticker(void)
|
||||
return;
|
||||
|
||||
hu_tick++;
|
||||
hu_emoteanim++;
|
||||
hu_tick &= 7; // currently only to blink chat input cursor
|
||||
|
||||
if (PLAYER1INPUTDOWN(gc_scores))
|
||||
@@ -1368,7 +1372,7 @@ boolean HU_Responder(event_t *ev)
|
||||
&& ev->data1 != gamecontrol[0][gc_talkkey][1]))
|
||||
return false;
|
||||
|
||||
M_TextInputHandle(&w_chat, c);
|
||||
M_TextInputHandleEmotes(&w_chat, c, emote_suggestions, MAXEMOTESUGGESTIONS);
|
||||
|
||||
if (c == KEY_ENTER)
|
||||
{
|
||||
@@ -1408,6 +1412,8 @@ boolean HU_Responder(event_t *ev)
|
||||
|
||||
#ifndef NONET
|
||||
|
||||
#define HU_DrawEmote(x, y, emote, flags) M_DrawEmote((x), (y), (emote), hu_emoteanim, (flags))
|
||||
|
||||
// Precompile a wordwrapped string to any given width.
|
||||
// This is a muuuch better method than V_WORDWRAP.
|
||||
// again stolen and modified a bit from video.c, don't mind me, will need to rearrange this one day.
|
||||
@@ -1419,6 +1425,8 @@ static char *CHAT_WordWrap(INT32 x, INT32 w, INT32 option, const char *string)
|
||||
size_t slen;
|
||||
char *newstring = Z_StrDup(string);
|
||||
INT32 spacewidth = (vid.width < 640) ? 8 : 4, charwidth = (vid.width < 640) ? 8 : 4;
|
||||
emote_t *emote = NULL;
|
||||
int emotelen = 0;
|
||||
|
||||
slen = strlen(string);
|
||||
x = 0;
|
||||
@@ -1440,7 +1448,12 @@ static char *CHAT_WordWrap(INT32 x, INT32 w, INT32 option, const char *string)
|
||||
c = toupper(c);
|
||||
c -= HU_FONTSTART;
|
||||
|
||||
if (c < 0 || c >= HU_FONTSIZE || !hu_font[c])
|
||||
if ((emote = M_VerifyEmote(string+i, &emotelen)))
|
||||
{
|
||||
chw = EMOTEWIDTH;
|
||||
i += emotelen-1; // Will be incremented on next loop iteration, hence -1
|
||||
}
|
||||
else if (c < 0 || c >= HU_FONTSIZE || !hu_font[c])
|
||||
{
|
||||
chw = spacewidth;
|
||||
lastusablespace = i;
|
||||
@@ -1462,7 +1475,6 @@ static char *CHAT_WordWrap(INT32 x, INT32 w, INT32 option, const char *string)
|
||||
return newstring;
|
||||
}
|
||||
|
||||
|
||||
// 30/7/18: chaty is now the distance at which the lowest point of the chat will be drawn if that makes any sense.
|
||||
|
||||
INT16 chatx = 13, chaty = 169; // let's use this as our coordinates, shh
|
||||
@@ -1495,6 +1507,8 @@ static void HU_drawMiniChat(void)
|
||||
char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i-1]);
|
||||
size_t j = 0;
|
||||
INT32 linescount = 0;
|
||||
emote_t *emote = NULL;
|
||||
int emotelen = 0;
|
||||
|
||||
while(msg[j]) // iterate through msg
|
||||
{
|
||||
@@ -1519,6 +1533,11 @@ static void HU_drawMiniChat(void)
|
||||
|
||||
++j;
|
||||
}
|
||||
else if ((emote = M_VerifyEmote(msg+j, &emotelen)))
|
||||
{
|
||||
dx += EMOTEWIDTH - charwidth;
|
||||
j += emotelen;
|
||||
}
|
||||
else
|
||||
{
|
||||
j++;
|
||||
@@ -1564,6 +1583,8 @@ static void HU_drawMiniChat(void)
|
||||
size_t j = 0;
|
||||
char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i]); // get the current message, and word wrap it.
|
||||
UINT8 *colormap = NULL;
|
||||
emote_t *emote = NULL;
|
||||
int emotelen = 0;
|
||||
|
||||
while(msg[j]) // iterate through msg
|
||||
{
|
||||
@@ -1590,6 +1611,16 @@ static void HU_drawMiniChat(void)
|
||||
|
||||
++j;
|
||||
}
|
||||
else if ((emote = M_VerifyEmote(msg+j, &emotelen)))
|
||||
{
|
||||
if (cv_chatbacktint.value) // on request of wolfy
|
||||
V_DrawFillConsoleMap(x + dx + 2, y+dy, EMOTEWIDTH, charheight, 239|V_SNAPTOBOTTOM|V_SNAPTOLEFT);
|
||||
|
||||
HU_DrawEmote(x+dx+2, y+dy, emote, V_SNAPTOBOTTOM|V_SNAPTOLEFT|transflag);
|
||||
dx += EMOTEWIDTH - charwidth;
|
||||
|
||||
j += emotelen;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cv_chatbacktint.value) // on request of wolfy
|
||||
@@ -1667,6 +1698,9 @@ static void HU_drawChatLog(INT32 offset)
|
||||
INT32 j = 0;
|
||||
char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_log[i]); // get the current message, and word wrap it.
|
||||
UINT8 *colormap = NULL;
|
||||
emote_t *emote = NULL;
|
||||
int emotelen = 0;
|
||||
|
||||
while(msg[j]) // iterate through msg
|
||||
{
|
||||
if (msg[j] < HU_FONTSTART) // don't draw
|
||||
@@ -1688,6 +1722,15 @@ static void HU_drawChatLog(INT32 offset)
|
||||
|
||||
++j;
|
||||
}
|
||||
else if ((emote = M_VerifyEmote(msg+j, &emotelen)))
|
||||
{
|
||||
if ((y+dy+2 >= chat_topy) && (y+dy < (chat_bottomy)))
|
||||
{
|
||||
HU_DrawEmote(x+dx+2, y+dy, emote, V_SNAPTOBOTTOM|V_SNAPTOLEFT);
|
||||
dx += EMOTEWIDTH - charwidth;
|
||||
}
|
||||
j += emotelen;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((y+dy+2 >= chat_topy) && (y+dy < (chat_bottomy)))
|
||||
@@ -1813,7 +1856,7 @@ static void HU_DrawChat(void)
|
||||
typelines = 1;
|
||||
|
||||
if ((w_chat.cursor == 0 || w_chat.length == 0) && hu_tick < 4)
|
||||
V_DrawChatCharacter(chatx+2+c+charwidth*w_chat.cursor, y+1, '_'|V_SNAPTOBOTTOM|V_SNAPTOLEFT|t, !cv_allcaps.value, NULL);
|
||||
V_DrawChatCharacter(chatx+2+c, y+1, '_'|V_SNAPTOBOTTOM|V_SNAPTOLEFT|t, !cv_allcaps.value, NULL);
|
||||
|
||||
if (w_chat.select != w_chat.cursor)
|
||||
{
|
||||
@@ -1824,30 +1867,40 @@ static void HU_DrawChat(void)
|
||||
while (w_chat_buf[i])
|
||||
{
|
||||
boolean skippedline = false;
|
||||
if (w_chat.cursor == (i+1))
|
||||
emote_t *emote = NULL;
|
||||
int emotelen = 0;
|
||||
int drawwidth = charwidth; // if we've drawn emote, selection needs to account for that
|
||||
|
||||
if ((emote = M_VerifyEmote(w_chat_buf+i, &emotelen)))
|
||||
{
|
||||
HU_DrawEmote(chatx + c + 2, y-1, emote, V_SNAPTOBOTTOM|V_SNAPTOLEFT|t);
|
||||
c += EMOTEWIDTH - charwidth;
|
||||
i += emotelen-1;
|
||||
drawwidth = EMOTEWIDTH;
|
||||
}
|
||||
else if (w_chat_buf[i] >= HU_FONTSTART) //Hurdler: isn't it better like that?
|
||||
V_DrawChatCharacter(chatx + c + 2, y, w_chat_buf[i] | V_SNAPTOBOTTOM|V_SNAPTOLEFT | t, !cv_allcaps.value, NULL);
|
||||
|
||||
// Draw selection
|
||||
if (i >= select_start && i < select_end)
|
||||
V_DrawFill(chatx + c + 2 - (drawwidth-charwidth), y-1, drawwidth, charheight, 103|V_TRANSLUCENT|V_SNAPTOBOTTOM|V_SNAPTOLEFT|t);
|
||||
|
||||
++i;
|
||||
|
||||
if (w_chat.cursor == i)
|
||||
{
|
||||
INT32 cursorx = (c+charwidth < boxw-charwidth) ? (chatx + 2 + c+charwidth) : (chatx+1); // we may have to go down.
|
||||
INT32 cursory = (cursorx != chatx+1) ? (y) : (y+charheight);
|
||||
if (hu_tick < 4)
|
||||
V_DrawChatCharacter(cursorx, cursory+1, '_' |V_SNAPTOBOTTOM|V_SNAPTOLEFT|t, !cv_allcaps.value, NULL);
|
||||
|
||||
if (cursorx == chatx+1 && saylen == i) // a weirdo hack
|
||||
if (cursorx == chatx+1 && saylen == i-1) // a weirdo hack
|
||||
{
|
||||
typelines += 1;
|
||||
skippedline = true;
|
||||
}
|
||||
}
|
||||
|
||||
//Hurdler: isn't it better like that?
|
||||
if (w_chat_buf[i] >= HU_FONTSTART)
|
||||
V_DrawChatCharacter(chatx + c + 2, y, w_chat_buf[i] | V_SNAPTOBOTTOM|V_SNAPTOLEFT | t, !cv_allcaps.value, NULL);
|
||||
|
||||
// Draw selection
|
||||
if (i >= select_start && i < select_end)
|
||||
V_DrawFill(chatx + c + 2, y-1, charwidth, charheight, 103|V_TRANSLUCENT|V_SNAPTOBOTTOM|V_SNAPTOLEFT|t);
|
||||
|
||||
++i;
|
||||
|
||||
c += charwidth;
|
||||
if (c > boxw-(charwidth*2) && !skippedline)
|
||||
{
|
||||
@@ -1857,6 +1910,36 @@ static void HU_DrawChat(void)
|
||||
}
|
||||
}
|
||||
|
||||
if (emote_suggestions[0])
|
||||
{
|
||||
// A bit of copy-paste from /pm code :p
|
||||
INT32 suggesty = chaty - charheight - 1;
|
||||
size_t longest_suggestion_length = 0;
|
||||
|
||||
for (i = 0; i < MAXEMOTESUGGESTIONS && emote_suggestions[i]; ++i)
|
||||
{
|
||||
longest_suggestion_length = max(longest_suggestion_length, strlen(emote_suggestions[i]->name));
|
||||
}
|
||||
|
||||
#ifdef NETSPLITSCREEN
|
||||
if (splitscreen)
|
||||
{
|
||||
suggesty -= BASEVIDHEIGHT/2;
|
||||
if (splitscreen > 1)
|
||||
suggesty += 16;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
suggesty -= (cv_kartspeedometer.value ? 16 : 0);
|
||||
|
||||
for (i = 0; i < MAXEMOTESUGGESTIONS && emote_suggestions[i]; ++i)
|
||||
{
|
||||
V_DrawFillConsoleMap(chatx + boxw + 2, suggesty - (7*i), (longest_suggestion_length+2)*4 + EMOTEWIDTH, 6, 239|V_SNAPTOBOTTOM|V_SNAPTOLEFT);
|
||||
V_DrawSmallString(chatx + boxw + 4 + EMOTEWIDTH, suggesty - (7*i), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, va(":%s:", emote_suggestions[i]->name));
|
||||
HU_DrawEmote(chatx + boxw + 2, suggesty - i*7, emote_suggestions[i], V_SNAPTOBOTTOM|V_SNAPTOLEFT);
|
||||
}
|
||||
}
|
||||
|
||||
// handle /pm list. It's messy, horrible and I don't care.
|
||||
if (strnicmp(w_chat_buf, "/pm", 3) == 0 && vid.width >= 400 && !teamtalk) // 320x200 unsupported kthxbai
|
||||
{
|
||||
|
||||
+4788
File diff suppressed because it is too large.
Load diff
+81
@@ -0,0 +1,81 @@
|
||||
// SONIC ROBO BLAST 2 KART
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2018-2020 by Kart Krew
|
||||
//
|
||||
// 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 k_hud.h
|
||||
/// \brief HUD drawing functions exclusive to Kart
|
||||
|
||||
#ifndef __K_HUD__
|
||||
#define __K_HUD__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "doomdef.h"
|
||||
#include "d_player.h" // Need for player_t
|
||||
#include "command.h"
|
||||
#include "r_defs.h"
|
||||
|
||||
UINT8 K_GetHudColor(void);
|
||||
boolean K_UseColorHud(void);
|
||||
boolean K_UseHighResPortraits(void);
|
||||
patch_t *K_GetFacePrefix(player_t *player, INT32 skinnum);
|
||||
|
||||
void K_RegisterKartHudStuff(void);
|
||||
|
||||
extern consvar_t cv_colorizedhud,
|
||||
cv_colorizeditembox,
|
||||
cv_colorizedhudcolor;
|
||||
|
||||
extern consvar_t cv_darkitembox;
|
||||
extern consvar_t cv_biglaps;
|
||||
extern consvar_t cv_highresportrait;
|
||||
extern consvar_t cv_stat_xoffset, cv_stat_yoffset;
|
||||
extern consvar_t cv_showstats;
|
||||
extern consvar_t cv_fancyroulette;
|
||||
extern consvar_t cv_showlaptimes;
|
||||
extern consvar_t cv_battlespeedo;
|
||||
extern consvar_t cv_multiitemicon;
|
||||
extern consvar_t cv_huditemamount;
|
||||
|
||||
#define NUMSPEEDOSTUFF 8
|
||||
extern CV_PossibleValue_t speedo_cons_t[NUMSPEEDOSTUFF];
|
||||
#define NUMDGAUGESTUFF 6
|
||||
extern CV_PossibleValue_t driftgaugestyle_cons_t[NUMDGAUGESTUFF];
|
||||
#define NUMINPUTDISPLAYSTUFF 5
|
||||
extern CV_PossibleValue_t inputdisplay_cons_t[NUMINPUTDISPLAYSTUFF];
|
||||
#define NUMMINIMAPDOTSTUFF 5
|
||||
extern CV_PossibleValue_t minimapdot_cons_t[NUMMINIMAPDOTSTUFF];
|
||||
|
||||
const char *K_GetItemPatch(UINT8 item, boolean tiny);
|
||||
INT32 K_calcSplitFlags(INT32 snapflags);
|
||||
void K_LoadKartHUDGraphics(void);
|
||||
void K_drawKartHUD(void);
|
||||
void K_drawKartFreePlay(UINT32 flashtime);
|
||||
void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, INT16 emblemmap, UINT8 mode);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
INT32 x;
|
||||
INT32 y;
|
||||
INT32 flags;
|
||||
} drawinfo_t;
|
||||
|
||||
patch_t *K_getItemBoxPatch(boolean small, boolean dark);
|
||||
patch_t *K_getItemMulPatch(boolean small);
|
||||
void K_getItemBoxDrawinfo(drawinfo_t *out);
|
||||
INT32 K_getMinimapTrans(void);
|
||||
void K_getLapsDrawinfo(drawinfo_t *out);
|
||||
void K_getMinimapDrawinfo(drawinfo_t *out);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
// =========================================================================
|
||||
#endif // __K_HUD__
|
||||
+33
-4758
File diff suppressed because it is too large.
Load diff
+2
-45
@@ -22,9 +22,6 @@ extern const UINT8 KartColor_Opposite[MAXSKINCOLORS*2];
|
||||
void K_RainbowColormap(UINT8 *dest_colormap, UINT8 skincolor);
|
||||
void K_GenerateKartColormap(UINT8 *dest_colormap, INT32 skinnum, UINT8 color, boolean local);
|
||||
UINT8 K_GetKartColorByName(const char *name);
|
||||
UINT8 K_GetHudColor(void);
|
||||
boolean K_UseColorHud(void);
|
||||
boolean K_UseHighResPortraits(void);
|
||||
|
||||
void K_RegisterServerKartStuff(void);
|
||||
void K_RegisterClientKartStuff(void);
|
||||
@@ -33,30 +30,11 @@ extern consvar_t cv_coloredspeedlines, cv_coloredsneakertrail;
|
||||
extern consvar_t cv_bananajitter;
|
||||
extern consvar_t cv_bananthrowroll;
|
||||
extern consvar_t cv_airsparks;
|
||||
extern consvar_t cv_colorizedhud, cv_colorizeditembox, cv_colorizedhudcolor;
|
||||
extern consvar_t cv_darkitembox;
|
||||
extern consvar_t cv_biglaps;
|
||||
extern consvar_t cv_highresportrait;
|
||||
extern consvar_t cv_stat_xoffset, cv_stat_yoffset;
|
||||
extern consvar_t cv_showstats;
|
||||
extern consvar_t cv_fancyroulette;
|
||||
extern consvar_t cv_showlaptimes;
|
||||
extern consvar_t cv_battlespeedo;
|
||||
extern consvar_t cv_multiitemicon;
|
||||
extern consvar_t cv_huditemamount;
|
||||
|
||||
#define NUMSPEEDOSTUFF 8
|
||||
extern CV_PossibleValue_t speedo_cons_t[NUMSPEEDOSTUFF];
|
||||
#define NUMDGAUGESTUFF 6
|
||||
extern CV_PossibleValue_t driftgaugestyle_cons_t[NUMDGAUGESTUFF];
|
||||
#define NUMINPUTDISPLAYSTUFF 5
|
||||
extern CV_PossibleValue_t inputdisplay_cons_t[NUMINPUTDISPLAYSTUFF];
|
||||
#define NUMMINIMAPDOTSTUFF 5
|
||||
extern CV_PossibleValue_t minimapdot_cons_t[NUMMINIMAPDOTSTUFF];
|
||||
|
||||
|
||||
boolean K_IsPlayerLosing(player_t *player);
|
||||
boolean K_IsPlayerWanted(player_t *player);
|
||||
INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean spbrush);
|
||||
INT32 K_FindUseodds(player_t *player, fixed_t mashed, INT32 pingame, INT32 bestbumper, boolean spbrush, boolean dontforcespb);
|
||||
void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid);
|
||||
void K_FlipFromObject(mobj_t *mo, mobj_t *master);
|
||||
void K_MatchGenericExtraFlags(mobj_t *mo, mobj_t *master);
|
||||
@@ -115,27 +93,6 @@ void K_PlayOvertakeSound(mobj_t *source);
|
||||
void K_PlayHitEmSound(mobj_t *source, mobj_t *victim);
|
||||
void K_PlayPowerGloatSound(mobj_t *source);
|
||||
|
||||
const char *K_GetItemPatch(UINT8 item, boolean tiny);
|
||||
INT32 K_calcSplitFlags(INT32 snapflags);
|
||||
void K_LoadKartHUDGraphics(void);
|
||||
void K_drawKartHUD(void);
|
||||
void K_drawKartFreePlay(UINT32 flashtime);
|
||||
void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, INT16 emblemmap, UINT8 mode);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
INT32 x;
|
||||
INT32 y;
|
||||
INT32 flags;
|
||||
} drawinfo_t;
|
||||
|
||||
patch_t *K_getItemBoxPatch(boolean small, boolean dark);
|
||||
patch_t *K_getItemMulPatch(boolean small);
|
||||
void K_getItemBoxDrawinfo(drawinfo_t *out);
|
||||
INT32 K_getMinimapTrans(void);
|
||||
void K_getLapsDrawinfo(drawinfo_t *out);
|
||||
void K_getMinimapDrawinfo(drawinfo_t *out);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "hu_stuff.h" // HU_AddChatText
|
||||
#include "console.h"
|
||||
#include "k_kart.h" // SRB2Kart
|
||||
#include "k_hud.h" // SRB2Kart
|
||||
#include "d_netcmd.h" // IsPlayerAdmin
|
||||
#include "d_main.h"
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
X (PlayerQuit),\
|
||||
X (PlayerThink),/* P_PlayerThink */\
|
||||
X (MusicChange),\
|
||||
X (MusicCredit),\
|
||||
X (ShouldSpin),/*SRB2KART*/\
|
||||
X (ShouldExplode),/*SRB2KART*/\
|
||||
X (ShouldSquish),/*SRB2KART*/\
|
||||
@@ -130,6 +131,7 @@ int LUA_HookPlayerCanDamage(player_t *, mobj_t *);
|
||||
void LUA_HookPlayerQuit(player_t *, int);
|
||||
int LUA_HookPlayerCmd(player_t *, ticcmd_t *);
|
||||
int LUA_HookMusicChange(const char *oldname, struct MusicChange *);
|
||||
int LUA_HookMusicCredit(musicdef_t *musicdef);
|
||||
|
||||
int LUA_HookShouldSpin(player_t *player, mobj_t *inflictor, mobj_t *source); // SRB2KART: Should player be spun out?
|
||||
int LUA_HookShouldExplode(player_t *player, mobj_t *inflictor, mobj_t *source); // SRB2KART: Should player be exploded?
|
||||
|
||||
@@ -1066,6 +1066,18 @@ int LUA_HookMusicChange(const char *oldname, struct MusicChange *param)
|
||||
return hook.status;
|
||||
}
|
||||
|
||||
int LUA_HookMusicCredit(musicdef_t *musicdef)
|
||||
{
|
||||
Hook_State hook;
|
||||
if (prepare_hook(&hook, 0, HOOK(MusicCredit)))
|
||||
{
|
||||
LUA_PushUserdata(gL, musicdef, META_MUSICDEF);
|
||||
call_hooks(&hook, 1, res_true);
|
||||
}
|
||||
|
||||
return hook.status;
|
||||
}
|
||||
|
||||
static int kartdamage_hook
|
||||
(
|
||||
player_t *player,
|
||||
|
||||
+5
-16
@@ -24,6 +24,7 @@
|
||||
#include "w_wad.h"
|
||||
#include "z_zone.h"
|
||||
#include "k_kart.h"
|
||||
#include "k_hud.h" // SRB2kart
|
||||
|
||||
#include "lua_script.h"
|
||||
#include "lua_libs.h"
|
||||
@@ -1260,15 +1261,10 @@ extern int lib_hudadd(lua_State *L);
|
||||
|
||||
static int lib_hudsetvotebackground(lua_State *L)
|
||||
{
|
||||
memset(VoteScreen.luaPrefix, 0, sizeof(VoteScreen.luaPrefix));
|
||||
|
||||
if (lua_isnoneornil(L, 1))
|
||||
{
|
||||
if (luaVoteScreen)
|
||||
{
|
||||
free(luaVoteScreen);
|
||||
}
|
||||
|
||||
luaVoteScreen = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1279,15 +1275,8 @@ static int lib_hudsetvotebackground(lua_State *L)
|
||||
return luaL_argerror(L, 1, "prefix should 4 characters wide");
|
||||
}
|
||||
|
||||
if (!luaVoteScreen)
|
||||
{
|
||||
luaVoteScreen = (char*)malloc(5);
|
||||
luaVoteScreen[4] = 0;
|
||||
}
|
||||
|
||||
strncpy(luaVoteScreen, prefix, 4);
|
||||
|
||||
strupr(luaVoteScreen);
|
||||
strncpy(VoteScreen.luaPrefix, prefix, 4);
|
||||
strupr(VoteScreen.luaPrefix);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "dehacked.h"
|
||||
#include "p_mobj.h"
|
||||
#include "p_local.h"
|
||||
#include "s_sound.h"
|
||||
#include "z_zone.h"
|
||||
|
||||
#include "lua_script.h"
|
||||
@@ -1072,6 +1073,109 @@ static int sfxinfo_num(lua_State *L)
|
||||
return 1;
|
||||
}
|
||||
|
||||
enum musicdef_e {
|
||||
musicdef_name = 0,
|
||||
musicdef_usage,
|
||||
musicdef_source,
|
||||
musicdef_filename,
|
||||
musicdef_title,
|
||||
musicdef_alttitle,
|
||||
musicdef_authors,
|
||||
};
|
||||
|
||||
const char *const musicdef_opt[] = {
|
||||
"name",
|
||||
"usage",
|
||||
"source",
|
||||
"filename",
|
||||
"title",
|
||||
"alttitle",
|
||||
"authors",
|
||||
NULL
|
||||
};
|
||||
|
||||
static int musicdef_fields_ref = LUA_NOREF;
|
||||
|
||||
static int lib_sFindMusicCredit(lua_State *L)
|
||||
{
|
||||
const char *name = luaL_checkstring(L, 1);
|
||||
LUA_PushUserdata(L, S_FindMusicCredit(name), META_MUSICDEF);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_getMusicDef(lua_State *L)
|
||||
{
|
||||
musicdef_t *def = NULL;
|
||||
|
||||
if (lua_isnumber(L, 2))
|
||||
def = S_GetMusicCredit(lua_tonumber(L, 2));
|
||||
else if (lua_isstring(L, 2))
|
||||
def = S_FindMusicCredit(lua_tostring(L, 2));
|
||||
else
|
||||
return luaL_error(L, "musicdefs index must be number or string (got %s)", luaL_typename(L, 2));
|
||||
|
||||
LUA_PushUserdata(L, def, META_MUSICDEF);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_setMusicDef(lua_State *L)
|
||||
{
|
||||
return luaL_error(L, "musicdefs is read only");
|
||||
}
|
||||
|
||||
static int lib_musicdefslen(lua_State *L)
|
||||
{
|
||||
lua_pushinteger(L, nummusicdefs);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int musicdef_get(lua_State *L)
|
||||
{
|
||||
musicdef_t *musicdef = *((musicdef_t **)luaL_checkudata(L, 1, META_MUSICDEF));
|
||||
enum musicdef_e field = Lua_optoption(L, 2, -1, musicdef_fields_ref);
|
||||
|
||||
I_Assert(musicdef != NULL);
|
||||
|
||||
switch (field)
|
||||
{
|
||||
case musicdef_name:
|
||||
lua_pushstring(L, musicdef->name);
|
||||
return 1;
|
||||
case musicdef_usage:
|
||||
lua_pushstring(L, musicdef->usage);
|
||||
return 1;
|
||||
case musicdef_source:
|
||||
lua_pushstring(L, musicdef->source);
|
||||
return 1;
|
||||
case musicdef_filename:
|
||||
lua_pushstring(L, musicdef->filename);
|
||||
return 1;
|
||||
case musicdef_title:
|
||||
lua_pushstring(L, musicdef->title);
|
||||
return 1;
|
||||
case musicdef_alttitle:
|
||||
lua_pushstring(L, musicdef->alttitle);
|
||||
return 1;
|
||||
case musicdef_authors:
|
||||
lua_pushstring(L, musicdef->authors);
|
||||
return 1;
|
||||
default:
|
||||
return luaL_error(L, LUA_QL("musicdef_t") " has no field named " LUA_QS, lua_tostring(L, 2));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int musicdef_num(lua_State *L)
|
||||
{
|
||||
musicdef_t *musicdef = *((musicdef_t **)luaL_checkudata(L, 1, META_MUSICDEF));
|
||||
|
||||
I_Assert(musicdef != NULL);
|
||||
|
||||
lua_pushinteger(L, musicdef->num);
|
||||
return 1;
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//
|
||||
// Now push all these functions into the Lua state!
|
||||
@@ -1126,6 +1230,18 @@ int LUA_InfoLib(lua_State *L)
|
||||
|
||||
sfxinfo_fields_ref = Lua_CreateFieldTable(L, sfxinfo_opt);
|
||||
|
||||
luaL_newmetatable(L, META_MUSICDEF);
|
||||
lua_pushcfunction(L, musicdef_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
lua_pushcfunction(L, musicdef_num);
|
||||
lua_setfield(L, -2, "__len");
|
||||
lua_pop(L, 1);
|
||||
|
||||
musicdef_fields_ref = Lua_CreateFieldTable(L, musicdef_opt);
|
||||
|
||||
lua_register(L, "S_FindMusicCredit", lib_sFindMusicCredit);
|
||||
|
||||
lua_newuserdata(L, 0);
|
||||
lua_createtable(L, 0, 2);
|
||||
lua_pushcfunction(L, lib_getSprname);
|
||||
@@ -1176,5 +1292,19 @@ int LUA_InfoLib(lua_State *L)
|
||||
lua_pushvalue(L, -1);
|
||||
lua_setglobal(L, "S_sfx");
|
||||
lua_setglobal(L, "sfxinfo");
|
||||
|
||||
lua_newuserdata(L, 0);
|
||||
lua_createtable(L, 0, 2);
|
||||
lua_pushcfunction(L, lib_getMusicDef);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
lua_pushcfunction(L, lib_setMusicDef);
|
||||
lua_setfield(L, -2, "__newindex");
|
||||
|
||||
lua_pushcfunction(L, lib_musicdefslen);
|
||||
lua_setfield(L, -2, "__len");
|
||||
lua_setmetatable(L, -2);
|
||||
lua_setglobal(L, "musicdefs");
|
||||
|
||||
return 0;
|
||||
}
|
||||
+5
-1
@@ -10,6 +10,9 @@
|
||||
/// \file lua_libs.h
|
||||
/// \brief libraries for Lua scripting
|
||||
|
||||
#include "doomtype.h"
|
||||
#include "blua/lua.h"
|
||||
|
||||
extern lua_State *gL;
|
||||
|
||||
#define LREG_VALID "VALID_USERDATA"
|
||||
@@ -20,6 +23,7 @@ extern lua_State *gL;
|
||||
#define META_STATE "STATE_T*"
|
||||
#define META_MOBJINFO "MOBJINFO_T*"
|
||||
#define META_SFXINFO "SFXINFO_T*"
|
||||
#define META_MUSICDEF "MUSICDEF_T*"
|
||||
|
||||
#define META_MOBJ "MOBJ_T*"
|
||||
#define META_MAPTHING "MAPTHING_T*"
|
||||
@@ -68,4 +72,4 @@ int LUA_SkinLib(lua_State *L);
|
||||
int LUA_ThinkerLib(lua_State *L);
|
||||
int LUA_MapLib(lua_State *L);
|
||||
int LUA_BlockmapLib(lua_State *L);
|
||||
int LUA_HudLib(lua_State *L);
|
||||
int LUA_HudLib(lua_State *L);
|
||||
@@ -0,0 +1,262 @@
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <cstring>
|
||||
|
||||
#include "m_emotes.h"
|
||||
|
||||
extern "C" {
|
||||
#include "w_wad.h"
|
||||
#include "z_zone.h"
|
||||
#include "hu_stuff.h"
|
||||
#include "v_video.h"
|
||||
}
|
||||
|
||||
consvar_t cv_emotes = {"emotes", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};;
|
||||
|
||||
static std::map<std::string, emote_t> emotes;
|
||||
|
||||
// TODO - Would be really nice to generalize soc-like file parsing and not reimplement it 100 times :)))))
|
||||
void M_LoadEmotes(UINT16 wadnum)
|
||||
{
|
||||
UINT16 lumpnum = W_CheckNumForNamePwad("EMOTES", wadnum, 0);
|
||||
|
||||
if (lumpnum == INT16_MAX)
|
||||
return;
|
||||
|
||||
char *lump = static_cast<char*>(W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE));
|
||||
size_t size = W_LumpLengthPwad(wadnum, lumpnum);
|
||||
|
||||
std::istringstream file(std::string(lump, size));
|
||||
std::string line;
|
||||
|
||||
emote_t *emote = nullptr;
|
||||
std::string emote_name;
|
||||
|
||||
// Just smol lambda to remove all the trailing chars we might not want
|
||||
auto trim = [](std::string &str) {
|
||||
str.erase(0, str.find_first_not_of(" \t\n\r\f\v"));
|
||||
str.erase(str.find_last_not_of(" \t\n\r\f\v")+1);
|
||||
};
|
||||
|
||||
int numemotes = 0;
|
||||
int linenum = 0;
|
||||
|
||||
while (std::getline(file, line))
|
||||
{
|
||||
++linenum;
|
||||
|
||||
trim(line);
|
||||
|
||||
if (line.empty())
|
||||
continue;
|
||||
|
||||
size_t split = line.find('=');
|
||||
|
||||
// Didn't find the =, means we're about to parse `Emote <name>`
|
||||
if (split == line.npos)
|
||||
{
|
||||
split = line.find(' ');
|
||||
|
||||
if (split == line.npos)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "EMOTES: Unrecognized line. (file %s, line %d)\n", wadfiles[wadnum]->filename, linenum);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strnicmp(line.c_str(), "emote", 5))
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "EMOTES: 'Emote' expected. (file %s, line %d)\n", wadfiles[wadnum]->filename, linenum);
|
||||
continue;
|
||||
}
|
||||
|
||||
emote_name = line.substr(split+1);
|
||||
|
||||
if (emote_name.find_first_of(" \t\n\r\f\v:") != emote_name.npos)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "EMOTES: Emote name cannot contain spaces or ':' symbols. (file %s, line %d)\n", wadfiles[wadnum]->filename, linenum);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (emote_name.size() > MAXEMOTENAME)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "EMOTES: Emote name is too long, truncating. (file %s, line %d)\n", wadfiles[wadnum]->filename, linenum);
|
||||
emote_name = emote_name.substr(0, MAXEMOTENAME);
|
||||
}
|
||||
|
||||
emote = &emotes[emote_name];
|
||||
strlcpy(emote->name, emote_name.c_str(), MAXEMOTENAME);
|
||||
|
||||
emote->timeperframe = 1;
|
||||
emote->numframes = 0;
|
||||
std::memset(emote->frames, 0, sizeof(emote->frames));
|
||||
|
||||
++numemotes;
|
||||
}
|
||||
else if (emote)
|
||||
{
|
||||
std::string field = line.substr(0, split);
|
||||
std::string value = line.substr(split+1);
|
||||
|
||||
trim(field);
|
||||
trim(value);
|
||||
|
||||
if (stricmp(field.c_str(), "frames") == 0)
|
||||
{
|
||||
UINT8 numframes = 0;
|
||||
|
||||
auto copy_frame = [&] {
|
||||
if (numframes == MAXEMOTEFRAMES)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "EMOTES: Too many frames. (file %s, line %d)", wadfiles[wadnum]->filename, linenum);
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t list_split = value.find(',');
|
||||
std::string framelumpname = value.substr(0, list_split);
|
||||
trim(framelumpname);
|
||||
|
||||
if (list_split == value.npos)
|
||||
value = "";
|
||||
else
|
||||
value = value.substr(list_split+1, value.npos);
|
||||
|
||||
// End of list of frames
|
||||
if (framelumpname.size() == 0)
|
||||
return false;
|
||||
|
||||
if (framelumpname.size() > 8)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "EMOTES: Frame %d name is too long. (file %s, line %d)", numframes, wadfiles[wadnum]->filename, linenum);
|
||||
framelumpname = framelumpname.substr(0, 8);
|
||||
}
|
||||
|
||||
std::strncpy(emote->frames[numframes], framelumpname.c_str(), framelumpname.size()+1);
|
||||
|
||||
++numframes;
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
while (copy_frame()) {}
|
||||
|
||||
if (numframes == 0)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "EMOTES: Expected list of frames. (file %s, line %d)", wadfiles[wadnum]->filename, linenum);
|
||||
}
|
||||
|
||||
emote->numframes = numframes;
|
||||
}
|
||||
else if (stricmp(field.c_str(), "timeperframe") == 0)
|
||||
{
|
||||
emote->timeperframe = std::stoi(value);
|
||||
|
||||
if (emote->timeperframe <= 0)
|
||||
{
|
||||
emote->timeperframe = 1;
|
||||
CONS_Alert(CONS_WARNING, "EMOTES: Bad value for 'timeperframe'. (file %s, line %d)", wadfiles[wadnum]->filename, linenum);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "EMOTES: Unrecognized field '%s'. (file %s, line %d)", field.c_str(), wadfiles[wadnum]->filename, linenum);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "EMOTES: Unrecognized line. (file %s, line %d)\n", wadfiles[wadnum]->filename, linenum);
|
||||
}
|
||||
}
|
||||
|
||||
CONS_Printf("Added %d emotes\n", numemotes);
|
||||
}
|
||||
|
||||
void M_InitEmotes(void)
|
||||
{
|
||||
UINT16 i;
|
||||
for (i = 0; i < numwadfiles; i++)
|
||||
M_LoadEmotes(i);
|
||||
}
|
||||
|
||||
emote_t *M_FindEmote(const char *name, int len, int skip)
|
||||
{
|
||||
if (!cv_emotes.value)
|
||||
return nullptr;
|
||||
|
||||
char query[MAXEMOTENAME+1] = {0};
|
||||
std::strncpy(query, name, std::min(len, MAXEMOTENAME));
|
||||
|
||||
for (auto &pair: emotes)
|
||||
{
|
||||
if (pair.first.rfind(query, 0, std::min(len, MAXEMOTENAME)) != 0)
|
||||
continue;
|
||||
|
||||
if (skip > 0)
|
||||
{
|
||||
--skip;
|
||||
continue;
|
||||
}
|
||||
|
||||
return &pair.second;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
emote_t *M_VerifyEmote(const char *name, int *emotelen)
|
||||
{
|
||||
if (*name != ':')
|
||||
return nullptr;
|
||||
|
||||
if (!cv_emotes.value)
|
||||
return nullptr;
|
||||
|
||||
const char *p = name+1; // skip ':'
|
||||
emote_t *match = nullptr;
|
||||
|
||||
while (*p && (p - name) < MAXEMOTENAME)
|
||||
{
|
||||
if (*p == ':')
|
||||
{
|
||||
std::string checkname = std::string(name+1, (p-name)-1);
|
||||
auto it = emotes.find(checkname);
|
||||
|
||||
if (it != emotes.end())
|
||||
match = &it->second;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
++p;
|
||||
}
|
||||
|
||||
if (match && emotelen)
|
||||
*emotelen = p-name+1;
|
||||
|
||||
return match;
|
||||
}
|
||||
|
||||
void M_DrawEmote(INT32 x, INT32 y, emote_t *emote, tic_t anim, INT32 flags)
|
||||
{
|
||||
if (emote->numframes == 0)
|
||||
return;
|
||||
|
||||
const char *lumpname = emote->frames[(anim/emote->timeperframe) % emote->numframes];
|
||||
patch_t *emotepatch = (patch_t*)W_CachePatchName(lumpname, PU_CACHE);
|
||||
|
||||
const int CHARHEIGHT = 6;
|
||||
|
||||
fixed_t scale = FRACUNIT;
|
||||
|
||||
x *= FRACUNIT;
|
||||
y *= FRACUNIT;
|
||||
|
||||
if (emotepatch->width > EMOTEWIDTH)
|
||||
scale = (FRACUNIT/emotepatch->width)*EMOTEWIDTH;
|
||||
else if (emotepatch->width < EMOTEWIDTH)
|
||||
x += (EMOTEWIDTH-emotepatch->width)*FRACUNIT/2;
|
||||
|
||||
y -= (scale*emotepatch->height-CHARHEIGHT*FRACUNIT)/2;
|
||||
|
||||
V_DrawFixedPatch(x, y, scale, flags, emotepatch, NULL);
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
#ifndef __M_EMOTES__
|
||||
#define __M_EMOTES__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "doomdef.h"
|
||||
#include "command.h"
|
||||
|
||||
extern consvar_t cv_emotes;
|
||||
|
||||
#define MAXEMOTENAME 32
|
||||
#define MAXEMOTEFRAMES 32
|
||||
#define EMOTEWIDTH 6
|
||||
|
||||
typedef struct emote_s {
|
||||
char name[MAXEMOTENAME+1];
|
||||
char frames[MAXEMOTEFRAMES][9];
|
||||
UINT8 numframes;
|
||||
tic_t timeperframe;
|
||||
} emote_t;
|
||||
|
||||
// Reads and adds emotes from EMOTES lump, with syntax similar to soc
|
||||
void M_LoadEmotes(UINT16 wadnum);
|
||||
|
||||
// Load emotes from all base wads
|
||||
void M_InitEmotes(void);
|
||||
|
||||
// Finds first matching emote, ignoring first few matches
|
||||
emote_t *M_FindEmote(const char *name, int len, int skips);
|
||||
|
||||
// If first character is not ':', instantly returns null
|
||||
// Starts from ':' character, goes until it finds ':' or end of string
|
||||
// If end of string is found, or closing ':' is found but resulting emote name doesn't exist,
|
||||
// it returns null, otherwise it returns emote and stores into *emotelen how much characters
|
||||
// needs to be skipped to get past emote name
|
||||
emote_t *M_VerifyEmote(const char *name, int *emotelen);
|
||||
|
||||
// Draw the emote, anim should be some kind of timer ticking every game tic
|
||||
// for animated emotes
|
||||
void M_DrawEmote(INT32 x, INT32 y, emote_t *emote, tic_t anim, INT32 flags);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // __M_EMOTES__
|
||||
@@ -15,6 +15,10 @@
|
||||
#ifndef __M_FIXED__
|
||||
#define __M_FIXED__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "doomtype.h"
|
||||
#ifdef __GNUC__
|
||||
#include <stdlib.h>
|
||||
@@ -370,4 +374,8 @@ void FM_MultMatrix(matrix_t *dest, const matrix_t *multme);
|
||||
void FM_Translate(matrix_t *dest, fixed_t x, fixed_t y, fixed_t z);
|
||||
void FM_Scale(matrix_t *dest, fixed_t x, fixed_t y, fixed_t z);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif //m_fixed.h
|
||||
+48
-45
@@ -70,6 +70,7 @@
|
||||
#include "st_stuff.h"
|
||||
#include "i_sound.h"
|
||||
#include "k_kart.h" // SRB2kart
|
||||
#include "k_hud.h" // SRB2kart
|
||||
#include "k_stats.h" // SRB2kart
|
||||
#include "d_player.h" // KITEM_ constants
|
||||
|
||||
@@ -2323,44 +2324,46 @@ static menuitem_t OP_SaturnHudMenu[] =
|
||||
{
|
||||
{IT_HEADER, NULL, "Saturn Hud Options", NULL, 0},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Speedometer Style", &cv_newspeedometer, 10},
|
||||
{IT_STRING | IT_CVAR, NULL, "Battle Speedometer", &cv_battlespeedo, 15},
|
||||
{IT_STRING|IT_CVAR, NULL, "Speedometer Style", &cv_newspeedometer, 10},
|
||||
{IT_STRING|IT_CVAR, NULL, "Battle Speedometer", &cv_battlespeedo, 15},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Colourized HUD", &cv_colorizedhud, 25},
|
||||
{IT_STRING | IT_CVAR, NULL, "Colourized Itembox", &cv_colorizeditembox, 30},
|
||||
{IT_STRING | IT_CVAR, NULL, "Colourized HUD Color", &cv_colorizedhudcolor, 35},
|
||||
{IT_STRING|IT_CVAR, NULL, "Colourized HUD", &cv_colorizedhud, 25},
|
||||
{IT_STRING|IT_CVAR, NULL, "Colourized Itembox", &cv_colorizeditembox, 30},
|
||||
{IT_STRING|IT_CVAR, NULL, "Colourized HUD Color", &cv_colorizedhudcolor, 35},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Input Display", &cv_showinput, 45},
|
||||
{IT_STRING|IT_CVAR, NULL, "Input Display", &cv_showinput, 45},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Stat Display", &cv_showstats, 55},
|
||||
{IT_STRING|IT_CVAR, NULL, "Stat Display", &cv_showstats, 55},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Higher Resolution Portraits", &cv_highresportrait, 65},
|
||||
{IT_STRING|IT_CVAR, NULL, "Higher Resolution Portraits", &cv_highresportrait, 65},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Small Positionnumber", &cv_smallposnum, 75},
|
||||
{IT_STRING | IT_CVAR, NULL, "Positionnumber Animation", &cv_posanim, 80},
|
||||
{IT_STRING|IT_CVAR, NULL, "Small Positionnumber", &cv_smallposnum, 75},
|
||||
{IT_STRING|IT_CVAR, NULL, "Positionnumber Animation", &cv_posanim, 80},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Flash Lap Times", &cv_showlaptimes, 90},
|
||||
{IT_STRING|IT_CVAR, NULL, "Flash Lap Times", &cv_showlaptimes, 90},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Multi-Item icons", &cv_multiitemicon, 100},
|
||||
{IT_STRING | IT_CVAR, NULL, "Item Amount Number", &cv_huditemamount, 105},
|
||||
{IT_STRING | IT_CVAR, NULL, "Animated Roulette", &cv_fancyroulette, 110},
|
||||
{IT_STRING|IT_CVAR, NULL, "Multi-Item icons", &cv_multiitemicon, 100},
|
||||
{IT_STRING|IT_CVAR, NULL, "Item Amount Number", &cv_huditemamount, 105},
|
||||
{IT_STRING|IT_CVAR, NULL, "Animated Roulette", &cv_fancyroulette, 110},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Show Lap Emblem", &cv_showlapemblem, 120},
|
||||
{IT_STRING | IT_CVAR, NULL, "Show Cecho Messages", &cv_cechotoggle, 125},
|
||||
{IT_STRING|IT_CVAR, NULL, "Show Lap Emblem", &cv_showlapemblem, 120},
|
||||
{IT_STRING|IT_CVAR, NULL, "Show Cecho Messages", &cv_cechotoggle, 125},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Show Names on Minimap", &cv_showminimapnames, 135},
|
||||
{IT_STRING | IT_CVAR, NULL, "Small Minimap Players", &cv_minihead, 140},
|
||||
{IT_STRING | IT_CVAR, NULL, "Spin Minimap Icons", &cv_spinoutroll, 145},
|
||||
{IT_STRING | IT_CVAR, NULL, "Player Angle Visual", &cv_showminimapangle, 150},
|
||||
{IT_STRING|IT_CVAR, NULL, "Show Names on Minimap", &cv_showminimapnames, 135},
|
||||
{IT_STRING|IT_CVAR, NULL, "Small Minimap Players", &cv_minihead, 140},
|
||||
{IT_STRING|IT_CVAR, NULL, "Spin Minimap Icons", &cv_spinoutroll, 145},
|
||||
{IT_STRING|IT_CVAR, NULL, "Player Angle Visual", &cv_showminimapangle, 150},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Beta Intermissionscreen", &cv_betainterscreen, 160},
|
||||
{IT_STRING|IT_CVAR, NULL, "Music Credits", &cv_songcredits, 160},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Show Director Prompt", &cv_showdirectorhud, 170},
|
||||
{IT_STRING|IT_CVAR, NULL, "Beta Intermissionscreen", &cv_betainterscreen, 170},
|
||||
|
||||
{IT_STRING | IT_SUBMENU, NULL, "Nametags...", &OP_NametagDef, 180},
|
||||
{IT_STRING | IT_SUBMENU, NULL, "Driftgauge...", &OP_DriftGaugeDef, 185},
|
||||
{IT_STRING|IT_CVAR, NULL, "Show Director Prompt", &cv_showdirectorhud, 180},
|
||||
|
||||
{IT_SUBMENU|IT_STRING, NULL, "Hud Offsets...", &OP_HudOffsetDef, 195},
|
||||
{IT_STRING|IT_SUBMENU, NULL, "Nametags...", &OP_NametagDef, 190},
|
||||
{IT_STRING|IT_SUBMENU, NULL, "Driftgauge...", &OP_DriftGaugeDef, 195},
|
||||
|
||||
{IT_SUBMENU|IT_STRING, NULL, "Hud Offsets...", &OP_HudOffsetDef, 205},
|
||||
};
|
||||
|
||||
static const char* OP_SaturnHudTooltips[] =
|
||||
@@ -2386,6 +2389,7 @@ static const char* OP_SaturnHudTooltips[] =
|
||||
"Minimize the player icons on the minimap.",
|
||||
"Erratically rotate player icons during spinouts.",
|
||||
"Visualize the player facing angle.",
|
||||
"Show the Music Credits and which style.",
|
||||
"Make the Intermission screen look like in beta versions of Kart!\nEither with background or just the rest.",
|
||||
"Show the Director Toggle prompt when spectating.",
|
||||
"Nametag Options.",
|
||||
@@ -2416,6 +2420,7 @@ enum
|
||||
sh_smallmap,
|
||||
sh_iconspinout,
|
||||
sh_minidot,
|
||||
sh_songcred,
|
||||
sh_betainter,
|
||||
sh_directorhud,
|
||||
sh_nametagmen,
|
||||
@@ -8477,7 +8482,7 @@ static void M_MusicTest(INT32 choice)
|
||||
{
|
||||
(void)choice;
|
||||
|
||||
if (!S_PrepareSoundTest())
|
||||
if (!nummusicdefs)
|
||||
{
|
||||
M_StartMessage(M_GetText("No selectable tracks found.\n"),NULL,MM_NOTHING);
|
||||
return;
|
||||
@@ -8556,33 +8561,33 @@ static void M_DrawMusicTest(void)
|
||||
{
|
||||
INT32 t, b, q, m = 128;
|
||||
|
||||
if (numsoundtestdefs <= 8)
|
||||
if (nummusicdefs <= 8)
|
||||
{
|
||||
t = 0;
|
||||
b = numsoundtestdefs - 1;
|
||||
b = nummusicdefs - 1;
|
||||
i = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
q = m;
|
||||
m = (5*m)/numsoundtestdefs;
|
||||
m = (5*m)/nummusicdefs;
|
||||
if (st_sel < 3)
|
||||
{
|
||||
t = 0;
|
||||
b = 7;
|
||||
i = 0;
|
||||
}
|
||||
else if (st_sel >= numsoundtestdefs-4)
|
||||
else if (st_sel >= nummusicdefs-4)
|
||||
{
|
||||
t = numsoundtestdefs - 8;
|
||||
b = numsoundtestdefs - 1;
|
||||
t = nummusicdefs - 8;
|
||||
b = nummusicdefs - 1;
|
||||
i = q-m;
|
||||
}
|
||||
else
|
||||
{
|
||||
t = st_sel - 3;
|
||||
b = st_sel + 4;
|
||||
i = (t * (q-m))/(numsoundtestdefs - 8);
|
||||
i = (t * (q-m))/(nummusicdefs - 8);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8591,7 +8596,7 @@ static void M_DrawMusicTest(void)
|
||||
if (t != 0)
|
||||
V_DrawString(20+280+4, 60+4 - (skullAnimCounter/5), V_YELLOWMAP, "\x1A");
|
||||
|
||||
if (b != numsoundtestdefs - 1)
|
||||
if (b != nummusicdefs - 1)
|
||||
V_DrawString(20+280+4, 60+128-12 + (skullAnimCounter/5), V_YELLOWMAP, "\x1B");
|
||||
|
||||
x = 24;
|
||||
@@ -8605,8 +8610,9 @@ static void M_DrawMusicTest(void)
|
||||
V_DrawFill(20, y-4, 280-1, 16, 237);
|
||||
|
||||
{
|
||||
const musicdef_t *def = S_GetMusicCredit(t);
|
||||
const size_t MAXLENGTH = 34;
|
||||
const char *songname = soundtestdefs[t]->title[0] ? soundtestdefs[t]->title : soundtestdefs[t]->source;
|
||||
const char *songname = def->title[0] ? def->title : def->source;
|
||||
|
||||
size_t namelength = strlen(songname);
|
||||
|
||||
@@ -8619,7 +8625,7 @@ static void M_DrawMusicTest(void)
|
||||
buf[MAXLENGTH] = 0;
|
||||
|
||||
V_DrawString(x, y, (t == st_sel ? V_YELLOWMAP : 0)|V_ALLOWLOWERCASE|V_MONOSPACE, buf);
|
||||
if (curplaying == soundtestdefs[t])
|
||||
if (curplaying == def)
|
||||
{
|
||||
V_DrawFill(20+280-9, y-4, 8, 16, 230);
|
||||
}
|
||||
@@ -8637,7 +8643,7 @@ static void M_HandleMusicTest(INT32 choice)
|
||||
switch (choice)
|
||||
{
|
||||
case KEY_DOWNARROW:
|
||||
if (st_sel++ >= numsoundtestdefs-1)
|
||||
if (st_sel++ >= nummusicdefs-1)
|
||||
st_sel = 0;
|
||||
{
|
||||
S_StartSound(NULL, sfx_menu1);
|
||||
@@ -8646,18 +8652,18 @@ static void M_HandleMusicTest(INT32 choice)
|
||||
break;
|
||||
case KEY_UPARROW:
|
||||
if (!st_sel--)
|
||||
st_sel = numsoundtestdefs-1;
|
||||
st_sel = nummusicdefs-1;
|
||||
{
|
||||
S_StartSound(NULL, sfx_menu1);
|
||||
}
|
||||
st_musictime = 0;
|
||||
break;
|
||||
case KEY_PGDN:
|
||||
if (st_sel < numsoundtestdefs-1)
|
||||
if (st_sel < nummusicdefs-1)
|
||||
{
|
||||
st_sel += 3;
|
||||
if (st_sel >= numsoundtestdefs-1)
|
||||
st_sel = numsoundtestdefs-1;
|
||||
if (st_sel >= nummusicdefs-1)
|
||||
st_sel = nummusicdefs-1;
|
||||
S_StartSound(NULL, sfx_menu1);
|
||||
}
|
||||
st_musictime = 0;
|
||||
@@ -8691,7 +8697,7 @@ static void M_HandleMusicTest(INT32 choice)
|
||||
case KEY_ENTER:
|
||||
S_StopSounds();
|
||||
S_StopMusic();
|
||||
curplaying = soundtestdefs[st_sel];
|
||||
curplaying = S_GetMusicCredit(st_sel);
|
||||
S_ChangeMusicInternal(curplaying->name, true);
|
||||
break;
|
||||
|
||||
@@ -8700,9 +8706,6 @@ static void M_HandleMusicTest(INT32 choice)
|
||||
}
|
||||
if (exitmenu)
|
||||
{
|
||||
Z_Free(soundtestdefs);
|
||||
soundtestdefs = NULL;
|
||||
|
||||
if (currentMenu->prevMenu)
|
||||
M_SetupNextMenu(currentMenu->prevMenu);
|
||||
else
|
||||
|
||||
+169
-5
@@ -130,6 +130,82 @@ static void M_TextInputPaste(textinput_t *input)
|
||||
M_TextInputAddString(input, paste);
|
||||
}
|
||||
|
||||
static void M_TextInputLeft(textinput_t *input, boolean emotes)
|
||||
{
|
||||
// Just do it simple way if possible
|
||||
if (!emotes || input->cursor < 2 || input->buffer[input->cursor-1] != ':')
|
||||
{
|
||||
if (input->cursor != 0)
|
||||
--input->cursor;
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise we need to check if we have to skip emote
|
||||
size_t start = input->cursor-2;
|
||||
|
||||
while (input->buffer[start] != ':')
|
||||
{
|
||||
// We reached start of string and didn't find ':' symbol, thats definitely not an emote
|
||||
// so just do it simple way
|
||||
if (start == 0)
|
||||
{
|
||||
M_TextInputLeft(input, false);
|
||||
return;
|
||||
}
|
||||
|
||||
--start;
|
||||
}
|
||||
|
||||
int emotelen = 0;
|
||||
if (M_VerifyEmote(input->buffer+start, &emotelen))
|
||||
input->cursor -= emotelen; // also skip the :
|
||||
else
|
||||
M_TextInputLeft(input, false); // Not a valid emote, do the simple thing
|
||||
}
|
||||
|
||||
static void M_TextInputRight(textinput_t *input, boolean emotes)
|
||||
{
|
||||
// Just do it simple way if possible
|
||||
if (!emotes || input->cursor == input->length || input->buffer[input->cursor] != ':')
|
||||
{
|
||||
if (input->cursor < input->length)
|
||||
++input->cursor;
|
||||
return;
|
||||
}
|
||||
|
||||
int emotelen = 0;
|
||||
if (M_VerifyEmote(input->buffer+input->cursor, &emotelen))
|
||||
input->cursor += emotelen; // Also skip the :
|
||||
else
|
||||
M_TextInputRight(input, false); // Not a valid emote, do the simple thing
|
||||
}
|
||||
|
||||
// Check if we're inside a valid emote
|
||||
static boolean M_TextInputCheckEmote(textinput_t *input)
|
||||
{
|
||||
int start = input->cursor;
|
||||
|
||||
// Definitely not an emote
|
||||
if (start == 0)
|
||||
return false;
|
||||
|
||||
// Might be closing :, need to skip it just in case
|
||||
if (input->buffer[start] == ':')
|
||||
--start;
|
||||
|
||||
while (input->buffer[start] != ':')
|
||||
{
|
||||
// No ':' found, definitely not inside emote
|
||||
if (start == 0)
|
||||
return false;
|
||||
|
||||
--start;
|
||||
}
|
||||
|
||||
// Found what may be emote start, now we can check
|
||||
return M_VerifyEmote(input->buffer+start, NULL) != NULL;
|
||||
}
|
||||
|
||||
void M_TextInputInit(textinput_t *input, char *buffer, size_t buffer_size)
|
||||
{
|
||||
input->buffer = buffer;
|
||||
@@ -156,7 +232,7 @@ void M_TextInputSetString(textinput_t *input, const char *c)
|
||||
input->cursor = input->select = input->length = strlen(c);
|
||||
}
|
||||
|
||||
boolean M_TextInputHandle(textinput_t *input, INT32 key)
|
||||
static boolean M_TextInputHandleBase(textinput_t *input, INT32 key, boolean emotes)
|
||||
{
|
||||
if (key == KEY_LSHIFT || key == KEY_RSHIFT
|
||||
|| key == KEY_LCTRL || key == KEY_RCTRL
|
||||
@@ -241,16 +317,14 @@ boolean M_TextInputHandle(textinput_t *input, INT32 key)
|
||||
|
||||
if (key == KEY_LEFTARROW)
|
||||
{
|
||||
if (input->cursor != 0)
|
||||
--input->cursor;
|
||||
M_TextInputLeft(input, emotes);
|
||||
if (!shiftdown)
|
||||
input->select = input->cursor;
|
||||
return true;
|
||||
}
|
||||
else if (key == KEY_RIGHTARROW)
|
||||
{
|
||||
if (input->cursor < input->length)
|
||||
++input->cursor;
|
||||
M_TextInputRight(input, emotes);
|
||||
if (!shiftdown)
|
||||
input->select = input->cursor;
|
||||
return true;
|
||||
@@ -320,6 +394,96 @@ boolean M_TextInputHandle(textinput_t *input, INT32 key)
|
||||
return true;
|
||||
}
|
||||
|
||||
// Just an alias, more or less
|
||||
boolean M_TextInputHandle(textinput_t *input, INT32 key)
|
||||
{
|
||||
return M_TextInputHandleBase(input, key, false);
|
||||
}
|
||||
|
||||
boolean M_TextInputHandleEmotes(textinput_t *input, INT32 key, emote_t *suggestions[], int maxsuggestions)
|
||||
{
|
||||
boolean ret = M_TextInputHandleBase(input, key, true);
|
||||
|
||||
// After this handled key we ended up inside an emote, lets fix that
|
||||
if (M_TextInputCheckEmote(input))
|
||||
M_TextInputToWordEnd(input, !shiftdown);
|
||||
|
||||
// Always clear the first entry
|
||||
suggestions[0] = NULL;
|
||||
|
||||
// For autocomplete
|
||||
int emotestart = 0;
|
||||
|
||||
// Try find suggestions for emote names
|
||||
for (int i = input->cursor-1; i >= 0 && input->cursor-i <= MAXEMOTENAME; --i)
|
||||
{
|
||||
// Space can't be part of emote name
|
||||
if (isspace(input->buffer[i]))
|
||||
break;
|
||||
|
||||
// Found a :, try suggest emotes
|
||||
if (input->buffer[i] == ':')
|
||||
{
|
||||
emotestart = i+1;
|
||||
// ...But only if we typed at least something
|
||||
if ((int)input->cursor-(i-1) < 3)
|
||||
break;
|
||||
|
||||
for (int skip = 0; skip < maxsuggestions; ++skip)
|
||||
{
|
||||
suggestions[skip] = M_FindEmote(input->buffer+i+1, input->cursor-i-1, skip);
|
||||
|
||||
// No more suggestions
|
||||
if (!suggestions[skip])
|
||||
break;
|
||||
}
|
||||
|
||||
// In any case, we found what we wanted, can exit the loop now
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If we suggest emotes, try autocomplete
|
||||
if (key == '\t' && suggestions[0])
|
||||
{
|
||||
int pos = (input->cursor-emotestart);
|
||||
boolean autocomplete = true;
|
||||
|
||||
while (autocomplete)
|
||||
{
|
||||
// Check if current character matches for all suggestions
|
||||
char c = suggestions[0]->name[pos];
|
||||
|
||||
// End of string reached
|
||||
if (!c)
|
||||
break;
|
||||
|
||||
for (int i = 1; i < maxsuggestions && suggestions[i]; ++i)
|
||||
{
|
||||
if (suggestions[i]->name[pos] != c)
|
||||
{
|
||||
autocomplete = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
++pos;
|
||||
|
||||
if (autocomplete)
|
||||
M_TextInputAddChar(input, c);
|
||||
}
|
||||
|
||||
// This was the only suggestion, finish autocomplete with a ':' and clear suggestions
|
||||
if (maxsuggestions == 1 || !suggestions[1])
|
||||
{
|
||||
M_TextInputAddChar(input, ':');
|
||||
suggestions[0] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void M_DrawTextInputScroll(INT32 x, INT32 y, textinput_t *input, INT32 flags, INT32 MAXINPUTWIDTH)
|
||||
{
|
||||
if (renderisnewtic)
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define __M_TEXTINPUT__
|
||||
|
||||
#include "doomtype.h"
|
||||
#include "m_emotes.h" // M_VerifyEmote, M_FindEmote
|
||||
|
||||
typedef struct textinput_s {
|
||||
size_t cursor;
|
||||
@@ -22,6 +23,10 @@ void M_TextInputSetString(textinput_t *input, const char *c);
|
||||
|
||||
boolean M_TextInputHandle(textinput_t *input, INT32 key);
|
||||
|
||||
// Does everything same as M_TextInputHandle, but also handles emotes in input string
|
||||
// If currently typing something that looks like an existing emote, return suggestions for it
|
||||
boolean M_TextInputHandleEmotes(textinput_t *input, INT32 key, emote_t *suggestions[], int maxsuggestions);
|
||||
|
||||
#define M_DrawTextInput(x, y, input, flags) M_DrawTextInputScroll((x), (y), (input), (flags), ((input)->buffer_size-1)*8)
|
||||
void M_DrawTextInputScroll(INT32 x, INT32 y, textinput_t *input, INT32 flags, INT32 MAXINPUTWIDTH);
|
||||
|
||||
|
||||
+144
-106
@@ -34,6 +34,7 @@
|
||||
#include "r_fps.h" // R_ResetViewInterpolation in level load
|
||||
|
||||
#include "s_sound.h"
|
||||
#include "m_emotes.h"
|
||||
#include "st_stuff.h"
|
||||
#include "w_wad.h"
|
||||
#include "z_zone.h"
|
||||
@@ -67,6 +68,8 @@
|
||||
#include "lua_script.h"
|
||||
#include "lua_hook.h"
|
||||
|
||||
#include "y_inter.h"
|
||||
|
||||
#if !defined (UNDER_CE)
|
||||
#include <time.h>
|
||||
#endif
|
||||
@@ -3131,11 +3134,128 @@ boolean P_AddWadFile(const char *wadfilename, boolean local)
|
||||
return true;
|
||||
}
|
||||
|
||||
// check for replacement votescreen backgrounds
|
||||
boolean wideracereplaced = false;
|
||||
boolean racereplaced = false;
|
||||
boolean widebattlereplaced = false;
|
||||
boolean battlereplaced = false;
|
||||
static size_t sreplaces = 0, mreplaces = 0, digmreplaces = 0;
|
||||
|
||||
//
|
||||
// search for sound replacements
|
||||
//
|
||||
static boolean P_CheckSoundReplacements(UINT16 wadnum, char *name, size_t i)
|
||||
{
|
||||
size_t j;
|
||||
lumpnum_t lumpnum = (i|(wadnum<<16));
|
||||
|
||||
if (name[0] == 'D')
|
||||
{
|
||||
if (name[1] == 'S')
|
||||
{
|
||||
for (j = 1; j < NUMSFX; j++)
|
||||
{
|
||||
if (S_sfx[j].name && !strnicmp(S_sfx[j].name, name + 2, 6)
|
||||
&& (S_sfx[j].lumpnum != lumpnum) && (S_sfx[j].lumpnum != LUMPERROR))
|
||||
{
|
||||
// the sound will be reloaded when needed,
|
||||
// since sfx->data will be NULL
|
||||
CONS_Debug(DBG_SETUP, "Sound %.8s replaced\n", name);
|
||||
|
||||
I_FreeSfx(&S_sfx[j]);
|
||||
|
||||
// Re-cache it
|
||||
if (S_PrecacheSound())
|
||||
S_sfx[j].data = I_GetSfx(&S_sfx[j]);
|
||||
|
||||
sreplaces++;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (name[1] == '_')
|
||||
{
|
||||
CONS_Debug(DBG_SETUP, "Music %.8s ignored\n", name);
|
||||
mreplaces++;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (name[0] == 'O' && name[1] == '_')
|
||||
{
|
||||
CONS_Debug(DBG_SETUP, "Music %.8s replaced\n", name);
|
||||
digmreplaces++;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// search for maps
|
||||
//
|
||||
static boolean P_CheckMapReplacements(char *name)
|
||||
{
|
||||
if (memcmp(name, "MAP", 3) == 0) // Ignore the headers
|
||||
{
|
||||
INT16 num;
|
||||
|
||||
if (name[5] != '\0')
|
||||
return false;
|
||||
|
||||
num = (INT16)M_MapNumber(name[3], name[4]);
|
||||
|
||||
// we want to record whether this map exists. if it doesn't have a header, we can assume it's not relephant
|
||||
if (num <= NUMMAPS && mapheaderinfo[num-1])
|
||||
{
|
||||
if (mapheaderinfo[num-1]->menuflags & LF2_EXISTSHACK)
|
||||
G_SetGameModified(multiplayer, true); // oops, double-defined - no record attack privileges for you
|
||||
mapheaderinfo[num-1]->menuflags |= LF2_EXISTSHACK;
|
||||
}
|
||||
|
||||
if (num == gamemap)
|
||||
partadd_replacescurrentmap = true;
|
||||
|
||||
CONS_Printf("%s\n", name);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// check for non Lua votescreen replacements
|
||||
//
|
||||
static boolean P_CheckVoteReplacements(char *name)
|
||||
{
|
||||
// widescreen patch Race
|
||||
if (!VoteScreen.replaced.widerace && !memcmp(name, "INTERSCW", 8))
|
||||
{
|
||||
VoteScreen.replaced.widerace = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!VoteScreen.replaced.race && !memcmp(name, "INTERSCR", 8))
|
||||
{
|
||||
VoteScreen.replaced.race = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// widescreen patch Battle
|
||||
if (!VoteScreen.replaced.widebattle && !memcmp(name, "BATTLSCW", 8))
|
||||
{
|
||||
VoteScreen.replaced.widebattle = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!VoteScreen.replaced.battle && !memcmp(name, "BATTLSCR", 8))
|
||||
{
|
||||
VoteScreen.replaced.battle = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (VoteScreen.replaced.widerace && VoteScreen.replaced.race
|
||||
&& VoteScreen.replaced.widebattle && VoteScreen.replaced.battle)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// Add a WAD file and do the per-WAD setup stages.
|
||||
@@ -3143,12 +3263,15 @@ boolean battlereplaced = false;
|
||||
//
|
||||
UINT16 P_PartialAddWadFile(const char *wadfilename, boolean local)
|
||||
{
|
||||
size_t i, j, sreplaces = 0, mreplaces = 0, digmreplaces = 0;
|
||||
size_t i;
|
||||
UINT16 numlumps, wadnum;
|
||||
char *name;
|
||||
boolean mapsadded = false;
|
||||
static boolean allvotereplaced = false;
|
||||
lumpinfo_t *lumpinfo;
|
||||
|
||||
sreplaces = mreplaces = digmreplaces = 0;
|
||||
|
||||
if ((numlumps = W_InitFile(wadfilename, local)) == INT16_MAX)
|
||||
{
|
||||
refreshdirmenu |= REFRESHDIR_NOTLOADED;
|
||||
@@ -3163,46 +3286,24 @@ UINT16 P_PartialAddWadFile(const char *wadfilename, boolean local)
|
||||
|
||||
wadfiles[wadnum]->localfile = local;
|
||||
|
||||
//
|
||||
// search for sound replacements
|
||||
//
|
||||
lumpinfo = wadfiles[wadnum]->lumpinfo;
|
||||
for (i = 0; i < numlumps; i++, lumpinfo++)
|
||||
{
|
||||
name = lumpinfo->name;
|
||||
lumpnum_t lumpnum = i|(wadnum<<16);
|
||||
|
||||
if (name[0] == 'D')
|
||||
if (P_CheckSoundReplacements(wadnum, name, i))
|
||||
continue;
|
||||
|
||||
if (P_CheckMapReplacements(name))
|
||||
{
|
||||
if (name[1] == 'S') for (j = 1; j < NUMSFX; j++)
|
||||
{
|
||||
if (S_sfx[j].name && !strnicmp(S_sfx[j].name, name + 2, 6) && S_sfx[j].lumpnum != lumpnum && S_sfx[j].lumpnum != LUMPERROR)
|
||||
{
|
||||
// the sound will be reloaded when needed,
|
||||
// since sfx->data will be NULL
|
||||
CONS_Debug(DBG_SETUP, "Sound %.8s replaced\n", name);
|
||||
|
||||
I_FreeSfx(&S_sfx[j]);
|
||||
|
||||
// Re-cache it
|
||||
if (S_PrecacheSound())
|
||||
S_sfx[j].data = I_GetSfx(&S_sfx[j]);
|
||||
|
||||
sreplaces++;
|
||||
}
|
||||
}
|
||||
else if (name[1] == '_')
|
||||
{
|
||||
CONS_Debug(DBG_SETUP, "Music %.8s ignored\n", name);
|
||||
mreplaces++;
|
||||
}
|
||||
}
|
||||
else if (name[0] == 'O' && name[1] == '_')
|
||||
{
|
||||
CONS_Debug(DBG_SETUP, "Music %.8s replaced\n", name);
|
||||
digmreplaces++;
|
||||
mapsadded = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!allvotereplaced && P_CheckVoteReplacements(name))
|
||||
allvotereplaced = true;
|
||||
}
|
||||
|
||||
if (!devparm && sreplaces)
|
||||
CONS_Printf(M_GetText("%s sounds replaced\n"), sizeu1(sreplaces));
|
||||
if (!devparm && mreplaces)
|
||||
@@ -3210,6 +3311,9 @@ UINT16 P_PartialAddWadFile(const char *wadfilename, boolean local)
|
||||
if (!devparm && digmreplaces)
|
||||
CONS_Printf(M_GetText("%s digital musics replaced\n"), sizeu1(digmreplaces));
|
||||
|
||||
if (!mapsadded)
|
||||
CONS_Printf(M_GetText("No maps added\n"));
|
||||
|
||||
//
|
||||
// search for sprite replacements
|
||||
//
|
||||
@@ -3235,79 +3339,13 @@ UINT16 P_PartialAddWadFile(const char *wadfilename, boolean local)
|
||||
S_LoadMusicDefs(wadnum);
|
||||
|
||||
//
|
||||
// search for maps
|
||||
// look for emotes
|
||||
//
|
||||
lumpinfo = wadfiles[wadnum]->lumpinfo;
|
||||
for (i = 0; i < numlumps; i++, lumpinfo++)
|
||||
{
|
||||
name = lumpinfo->name;
|
||||
|
||||
if (name[0] == 'M' && name[1] == 'A' && name[2] == 'P') // Ignore the headers
|
||||
{
|
||||
INT16 num;
|
||||
if (name[5]!='\0')
|
||||
continue;
|
||||
num = (INT16)M_MapNumber(name[3], name[4]);
|
||||
|
||||
// we want to record whether this map exists. if it doesn't have a header, we can assume it's not relephant
|
||||
if (num <= NUMMAPS && mapheaderinfo[num-1])
|
||||
{
|
||||
if (mapheaderinfo[num-1]->menuflags & LF2_EXISTSHACK)
|
||||
G_SetGameModified(multiplayer, true); // oops, double-defined - no record attack privileges for you
|
||||
mapheaderinfo[num-1]->menuflags |= LF2_EXISTSHACK;
|
||||
}
|
||||
|
||||
if (num == gamemap)
|
||||
partadd_replacescurrentmap = true;
|
||||
|
||||
CONS_Printf("%s\n", name);
|
||||
mapsadded = true;
|
||||
}
|
||||
}
|
||||
if (!mapsadded)
|
||||
CONS_Printf(M_GetText("No maps added\n"));
|
||||
M_LoadEmotes(wadnum);
|
||||
|
||||
// TODO: Experimental SPRTINFO support, test first
|
||||
R_LoadSpriteInfoLumps(wadnum, wadfiles[wadnum]->numlumps);
|
||||
|
||||
//
|
||||
// check for votescreen replacements
|
||||
//
|
||||
if (!wideracereplaced && !racereplaced && !widebattlereplaced && !battlereplaced)
|
||||
{
|
||||
lumpinfo = wadfiles[wadnum]->lumpinfo;
|
||||
for (i = 0; i < numlumps; i++, lumpinfo++)
|
||||
{
|
||||
name = lumpinfo->name;
|
||||
|
||||
// widescreen patch Race
|
||||
if (!wideracereplaced && !strncmp(name, "INTERSCW", 8))
|
||||
{
|
||||
wideracereplaced = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!racereplaced && !strncmp(name, "INTERSCR", 8))
|
||||
{
|
||||
racereplaced = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
// widescreen patch Battle
|
||||
if (!widebattlereplaced && !strncmp(name, "BATTLSCW", 8))
|
||||
{
|
||||
widebattlereplaced = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!battlereplaced && !strncmp(name, "BATTLSCR", 8))
|
||||
{
|
||||
battlereplaced = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
refreshdirmenu &= ~REFRESHDIR_GAMEDATA; // Under usual circumstances we'd wait for REFRESHDIR_GAMEDATA to disappear the next frame, but it's a bit too dangerous for that...
|
||||
partadd_stage = 0;
|
||||
return wadnum;
|
||||
|
||||
@@ -73,11 +73,6 @@ void HWR_LoadLevel(boolean reloadinggamestate);
|
||||
|
||||
boolean P_AddWadFile(const char *wadfilename, boolean local);
|
||||
|
||||
extern boolean wideracereplaced;
|
||||
extern boolean racereplaced;
|
||||
extern boolean widebattlereplaced;
|
||||
extern boolean battlereplaced;
|
||||
|
||||
// WARNING: The following functions should be grouped as follows:
|
||||
// any amount of PartialAdds followed by MultiSetups until returned true,
|
||||
// as soon as possible.
|
||||
|
||||
+3
-3
@@ -385,15 +385,15 @@ static void R_AddLine(seg_t *line)
|
||||
backsector = line->backsector;
|
||||
|
||||
// Portal line
|
||||
if (line->linedef->special == 40 && line->side == 0)
|
||||
if (line->linedef->special == PORTALSPECIAL && line->side == 0)
|
||||
{
|
||||
if (portalrender < cv_maxportals.value)
|
||||
{
|
||||
// Find the other side!
|
||||
INT32 line2 = P_FindSpecialLineFromTag(40, line->linedef->tag, -1);
|
||||
INT32 line2 = P_FindSpecialLineFromTag(PORTALSPECIAL, line->linedef->tag, -1);
|
||||
|
||||
if (line->linedef == &lines[line2])
|
||||
line2 = P_FindSpecialLineFromTag(40, line->linedef->tag, line2);
|
||||
line2 = P_FindSpecialLineFromTag(PORTALSPECIAL, line->linedef->tag, line2);
|
||||
|
||||
if (line2 >= 0) // found it!
|
||||
{
|
||||
|
||||
@@ -420,6 +420,7 @@ typedef enum
|
||||
} slopetype_t;
|
||||
|
||||
#define HORIZONSPECIAL 41
|
||||
#define PORTALSPECIAL 40
|
||||
|
||||
typedef struct line_s
|
||||
{
|
||||
|
||||
+9
-6
@@ -179,12 +179,15 @@ extern lumpnum_t viewborderlump[8];
|
||||
#define GTC_MENUCACHE GTC_CACHE
|
||||
//@TODO Add a separate caching mechanism for menu colormaps distinct from in-level GTC_CACHE. For now this is still preferable to memory leaks...
|
||||
|
||||
#define TC_DEFAULT -1
|
||||
#define TC_BOSS -2
|
||||
#define TC_METALSONIC -3 // For Metal Sonic battle
|
||||
#define TC_ALLWHITE -4 // For Cy-Brak-demon
|
||||
#define TC_RAINBOW -5 // For invincibility power
|
||||
#define TC_BLINK -6 // For item blinking
|
||||
enum
|
||||
{
|
||||
TC_BLINK = -6, // For item blinking, according to kart
|
||||
TC_RAINBOW, // For single colour
|
||||
TC_ALLWHITE, // For Cy-Brak-demon
|
||||
TC_METALSONIC, // For Metal Sonic battle
|
||||
TC_BOSS,
|
||||
TC_DEFAULT
|
||||
};
|
||||
|
||||
// Initialize color translation tables, for player rendering etc.
|
||||
UINT8* R_GetTranslationColormap(INT32 skinnum, skincolors_t color, UINT8 flags);
|
||||
|
||||
+16
-17
@@ -1164,8 +1164,6 @@ fixed_t R_GetSpriteDirectionalLighting(angle_t angle)
|
||||
return extralight;
|
||||
}
|
||||
|
||||
#define std_R_QuickCamDist(x, y) std::max(abs(((x)>>FRACBITS) - (viewx>>FRACBITS)), abs(((y)>>FRACBITS) - (viewy>>FRACBITS)))
|
||||
|
||||
//
|
||||
// R_ProjectSprite
|
||||
// Generates a vissprite for a thing
|
||||
@@ -1206,7 +1204,6 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||
//SoM: 3/17/2000
|
||||
fixed_t gz, gzt;
|
||||
INT32 heightsec, phs;
|
||||
INT32 dist = -1;
|
||||
INT32 light = 0;
|
||||
lighttable_t **lights_array = spritelights;
|
||||
fixed_t this_scale;
|
||||
@@ -1233,14 +1230,11 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||
const boolean hflip = (!(thing->frame & FF_HORIZONTALFLIP) != !mirrored);
|
||||
const boolean papersprite = (thing->frame & FF_PAPERSPRITE);
|
||||
|
||||
if (cv_maxinterpdist.value)
|
||||
dist = std_R_QuickCamDist(thing->x, thing->y);
|
||||
|
||||
// uncapped/interpolation
|
||||
interpmobjstate_t interp = {};
|
||||
|
||||
// do interpolation
|
||||
if (R_UsingFrameInterpolation() && !paused && (!cv_maxinterpdist.value || dist < cv_maxinterpdist.value))
|
||||
if (R_UsingFrameInterpolation() && !paused && R_CheckInterpDist(oldthing))
|
||||
{
|
||||
R_InterpolateMobjState(oldthing, rendertimefrac, &interp);
|
||||
}
|
||||
@@ -1862,25 +1856,20 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
|
||||
fixed_t gz, gzt;
|
||||
fixed_t this_scale;
|
||||
|
||||
INT32 dist = 1;
|
||||
|
||||
if (!thing || thing->subsector == NULL)
|
||||
return;
|
||||
|
||||
if (cv_maxinterpdist.value)
|
||||
dist = std_R_QuickCamDist(thing->x, thing->y);
|
||||
|
||||
// uncapped/interpolation
|
||||
interpmobjstate_t interp = {};
|
||||
|
||||
// okay... this is a hack, but weather isn't networked, so it should be ok
|
||||
if (!P_PrecipThinker(thing))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// uncapped/interpolation
|
||||
interpmobjstate_t interp = {};
|
||||
|
||||
// do interpolation
|
||||
if (R_UsingFrameInterpolation() && !paused && (!cv_maxinterpdist.value || dist < cv_maxinterpdist.value))
|
||||
if (R_UsingFrameInterpolation() && !paused && R_CheckInterpDist((mobj_t*)thing))
|
||||
{
|
||||
R_InterpolatePrecipMobjState(thing, rendertimefrac, &interp);
|
||||
}
|
||||
@@ -2919,7 +2908,7 @@ boolean R_ThingVisible (mobj_t *thing)
|
||||
|
||||
if (splitscreen)
|
||||
{
|
||||
if ((viewssnum == 0 && (thing->eflags & MFE_DRAWONLYFORP1))
|
||||
if ((viewssnum == 0 && (thing->eflags & MFE_DRAWONLYFORP1))
|
||||
|| (viewssnum == 1 && (thing->eflags & MFE_DRAWONLYFORP2))
|
||||
|| (viewssnum == 2 && (thing->eflags & MFE_DRAWONLYFORP2))
|
||||
|| (viewssnum == 3 && (thing->eflags & MFE_DRAWONLYFORP4)))
|
||||
@@ -2942,6 +2931,16 @@ boolean R_ThingWithinDist(mobj_t *thing, INT32 limit_dist)
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean R_CheckInterpDist(mobj_t *thing)
|
||||
{
|
||||
if (!cv_maxinterpdist.value)
|
||||
return true;
|
||||
|
||||
const INT32 dist = R_QuickCamDist(thing->x, thing->y);
|
||||
|
||||
return (dist < cv_maxinterpdist.value);
|
||||
}
|
||||
|
||||
boolean R_ThingIsFullBright(mobj_t *thing)
|
||||
{
|
||||
return ((thing->frame & FF_BRIGHTMASK) == FF_FULLBRIGHT);
|
||||
|
||||
@@ -39,7 +39,12 @@ extern "C" {
|
||||
// as an non-fixed-point integer.
|
||||
// It is very rough, tho it is used only for optimizing out unnecessary
|
||||
// interpolation, so it is kinda ok on big distances.
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define R_QuickCamDist(x, y) std::max(std::abs(((x)>>FRACBITS) - (viewx>>FRACBITS)), std::abs(((y)>>FRACBITS) - (viewy>>FRACBITS)))
|
||||
#else
|
||||
#define R_QuickCamDist(x, y) max(abs(((x)>>FRACBITS) - (viewx>>FRACBITS)), abs(((y)>>FRACBITS) - (viewy>>FRACBITS)))
|
||||
#endif
|
||||
|
||||
// Constant arrays used for psprite clipping
|
||||
// and initializing clipping.
|
||||
@@ -84,6 +89,7 @@ void R_DrawMasked(maskcount_t* masks, INT32 nummasks);
|
||||
|
||||
boolean R_ThingVisible(mobj_t *thing);
|
||||
boolean R_ThingWithinDist(mobj_t *thing, INT32 limit_dist);
|
||||
boolean R_CheckInterpDist(mobj_t *thing);
|
||||
|
||||
boolean R_ThingIsFullBright(mobj_t *thing);
|
||||
boolean R_ThingIsSemiBright(mobj_t *thing);
|
||||
|
||||
+58
-43
@@ -32,6 +32,7 @@
|
||||
#include "m_menu.h" // bird music stuff
|
||||
|
||||
#include "lua_hook.h" // MusicChange hook
|
||||
#include "lua_hud.h" // LUA_HudEnabled(hud_musiccredit)
|
||||
|
||||
static boolean S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 *vol, INT32 *sep, INT32 *pitch, sfxinfo_t *sfxinfo);
|
||||
static void SetChannelsNum(void);
|
||||
@@ -1202,8 +1203,58 @@ static consvar_t *music_refade_cv;
|
||||
/// Music Definitions
|
||||
/// ------------------------
|
||||
|
||||
musicdef_t *musicdefstart = NULL; // First music definition
|
||||
struct cursongcredit cursongcredit; // Currently displayed song credit info
|
||||
// Similar system to vissprite allocation. Exists so external pointers to musicdefs are not invalidated
|
||||
// when allocating more space for musicdefs
|
||||
#define MUSICDEFCHUNKBITS 6
|
||||
#define MUSICDEFSPERCHUNK (1 << MUSICDEFCHUNKBITS)
|
||||
#define MUSICDEFINDEXMASK (MUSICDEFSPERCHUNK - 1)
|
||||
static musicdef_t **musicdefs = NULL;
|
||||
static INT32 numchunks = 0;
|
||||
INT32 nummusicdefs = 0;
|
||||
|
||||
//
|
||||
// S_GetMusicCredit
|
||||
//
|
||||
// Return music credit with given index.
|
||||
//
|
||||
musicdef_t *S_GetMusicCredit(INT32 i)
|
||||
{
|
||||
if (i < 0 || i >= nummusicdefs)
|
||||
return NULL;
|
||||
|
||||
INT32 chunk = i >> MUSICDEFCHUNKBITS;
|
||||
i &= MUSICDEFINDEXMASK;
|
||||
|
||||
return &musicdefs[chunk][i];
|
||||
}
|
||||
|
||||
//
|
||||
// S_AddMusicCredit
|
||||
//
|
||||
// Return new music credit, allocates memory for it if needed.
|
||||
//
|
||||
static musicdef_t *S_AddMusicCredit(void)
|
||||
{
|
||||
INT32 chunk = nummusicdefs >> MUSICDEFCHUNKBITS;
|
||||
INT32 i = nummusicdefs & MUSICDEFINDEXMASK;
|
||||
|
||||
// Allocate new chunk if needed. Other chunks stay valid
|
||||
if (chunk == numchunks)
|
||||
{
|
||||
++numchunks;
|
||||
musicdefs = (musicdef_t**)Z_Realloc(musicdefs, sizeof(musicdef_t*)*numchunks, PU_STATIC, NULL);
|
||||
musicdefs[chunk] = Z_Calloc(sizeof(musicdef_t)*MUSICDEFSPERCHUNK, PU_STATIC, NULL);
|
||||
}
|
||||
|
||||
// Store "id" of new musicdef (mostly exists only for lua)
|
||||
musicdefs[chunk][i].num = nummusicdefs;
|
||||
|
||||
++nummusicdefs;
|
||||
|
||||
return &musicdefs[chunk][i];
|
||||
}
|
||||
|
||||
struct cursongcredit cursongcredit = {0}; // Currently displayed song credit info
|
||||
|
||||
static boolean
|
||||
ReadMusicDefFields (UINT16 wadnum, int line, char *stoken, musicdef_t **defp)
|
||||
@@ -1231,14 +1282,11 @@ ReadMusicDefFields (UINT16 wadnum, int line, char *stoken, musicdef_t **defp)
|
||||
// Nothing found, add to the end.
|
||||
if (!def)
|
||||
{
|
||||
def = Z_Calloc(sizeof (musicdef_t), PU_STATIC, NULL);
|
||||
def = S_AddMusicCredit();
|
||||
|
||||
STRBUFCPY(def->name, value);
|
||||
strlwr(def->name);
|
||||
def->hash = quickncasehash (def->name, 6);
|
||||
|
||||
def->next = musicdefstart;
|
||||
musicdefstart = def;
|
||||
}
|
||||
|
||||
(*defp) = def;
|
||||
@@ -1423,8 +1471,10 @@ musicdef_t *S_FindMusicCredit(const char *musname)
|
||||
UINT32 hash = quickncasehash (musname, 6);
|
||||
musicdef_t *def;
|
||||
|
||||
for (def = musicdefstart; def; def = def->next)
|
||||
for (INT32 i = 0; i < nummusicdefs; ++i)
|
||||
{
|
||||
def = S_GetMusicCredit(i);
|
||||
|
||||
if (hash != def->hash)
|
||||
continue;
|
||||
if (stricmp(def->name, musname))
|
||||
@@ -1457,7 +1507,7 @@ void S_ShowSpecifiedMusicCredit(const char *musname)
|
||||
|
||||
def = S_FindMusicCredit(musname);
|
||||
|
||||
if (def)
|
||||
if (def && !LUA_HookMusicCredit(def))
|
||||
{
|
||||
cursongcredit.def = def;
|
||||
cursongcredit.anim = 5*TICRATE;
|
||||
@@ -1476,41 +1526,6 @@ void S_ShowMusicCredit(void)
|
||||
S_ShowSpecifiedMusicCredit(music.name);
|
||||
}
|
||||
|
||||
musicdef_t **soundtestdefs = NULL;
|
||||
INT32 numsoundtestdefs = 0;
|
||||
|
||||
//
|
||||
// S_PrepareSoundTest
|
||||
//
|
||||
// Prepare sound test. What am I, your butler?
|
||||
//
|
||||
boolean S_PrepareSoundTest(void)
|
||||
{
|
||||
musicdef_t *def;
|
||||
INT32 pos = numsoundtestdefs = 0;
|
||||
|
||||
for (def = musicdefstart; def; def = def->next)
|
||||
{
|
||||
numsoundtestdefs++;
|
||||
}
|
||||
|
||||
if (!numsoundtestdefs)
|
||||
return false;
|
||||
|
||||
if (soundtestdefs)
|
||||
Z_Free(soundtestdefs);
|
||||
|
||||
if (!(soundtestdefs = Z_Malloc(numsoundtestdefs*sizeof(musicdef_t *), PU_STATIC, NULL)))
|
||||
I_Error("S_PrepareSoundTest(): could not allocate soundtestdefs.");
|
||||
|
||||
for (def = musicdefstart; def /*&& i < numsoundtestdefs*/; def = def->next)
|
||||
{
|
||||
soundtestdefs[pos++] = def;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// ------------------------
|
||||
/// Music Status
|
||||
/// ------------------------
|
||||
|
||||
+3
-8
@@ -182,14 +182,9 @@ typedef struct musicdef_s
|
||||
char alttitle[256];
|
||||
char authors[256];
|
||||
boolean use_info;
|
||||
struct musicdef_s *next;
|
||||
size_t num;
|
||||
} musicdef_t;
|
||||
|
||||
extern musicdef_t *musicdefstart;
|
||||
extern musicdef_t **soundtestdefs;
|
||||
extern INT32 numsoundtestdefs;
|
||||
extern UINT8 soundtestpage;
|
||||
|
||||
extern struct cursongcredit
|
||||
{
|
||||
musicdef_t *def;
|
||||
@@ -198,18 +193,18 @@ extern struct cursongcredit
|
||||
UINT8 trans;
|
||||
} cursongcredit;
|
||||
|
||||
extern INT32 nummusicdefs;
|
||||
|
||||
void S_LoadMusicDefs(UINT16 wadnum);
|
||||
void S_InitMusicDefs(void);
|
||||
void S_LoadMTDefs(UINT16 wadnum);
|
||||
void S_InitMTDefs(void);
|
||||
musicdef_t *S_GetMusicCredit(INT32 i);
|
||||
musicdef_t *S_FindMusicCredit(const char *musname);
|
||||
void S_ShowSpecifiedMusicCredit(const char *musname);
|
||||
void S_ShowMusicCredit(void);
|
||||
void S_ResetMusicCredit(void);
|
||||
|
||||
boolean S_PrepareSoundTest(void);
|
||||
|
||||
//
|
||||
// Music Seeking
|
||||
//
|
||||
|
||||
@@ -180,6 +180,7 @@ static char returnWadPath[256];
|
||||
#include "../screen.h" //vid.WndParent
|
||||
#include "../d_net.h"
|
||||
#include "../g_game.h"
|
||||
#include "../g_demo.h"
|
||||
#include "../filesrch.h"
|
||||
#include "../z_zone.h" // Z_Free
|
||||
#include "endtxt.h"
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "i_time.h"
|
||||
|
||||
#include "k_kart.h" // SRB2kart
|
||||
#include "k_hud.h"
|
||||
|
||||
//random index
|
||||
#include "m_random.h"
|
||||
|
||||
@@ -14,6 +14,10 @@
|
||||
#ifndef __STSTUFF_H__
|
||||
#define __STSTUFF_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "doomtype.h"
|
||||
#include "d_event.h"
|
||||
#include "d_player.h"
|
||||
@@ -142,4 +146,8 @@ extern UINT16 objectsdrawn;
|
||||
extern consvar_t cv_lessflicker;
|
||||
extern consvar_t cv_stagetitle;
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -65,6 +65,7 @@
|
||||
#include "st_stuff.h"
|
||||
#include "m_misc.h" // M_MapNumber
|
||||
#include "p_setup.h" // P_PartialAddFile mayb
|
||||
#include "k_hud.h"
|
||||
|
||||
#ifdef HWRENDER
|
||||
#include "r_data.h"
|
||||
|
||||
+146
-133
@@ -40,6 +40,7 @@
|
||||
#include "m_random.h" // M_RandomKey
|
||||
#include "g_input.h" // PLAYER1INPUTDOWN
|
||||
#include "k_kart.h" // colortranslations
|
||||
#include "k_hud.h"
|
||||
#include "console.h" // cons_menuhighlight
|
||||
#include "lua_hook.h" // IntermissionThinker hook
|
||||
#include "lua_hud.h" // intermission hud hook
|
||||
@@ -57,30 +58,15 @@ typedef struct
|
||||
|
||||
static y_data_t data;
|
||||
|
||||
|
||||
// graphics
|
||||
static patch_t *bgpatch = NULL; // INTERSCR
|
||||
static patch_t *widebgpatch = NULL; // INTERSCW
|
||||
static patch_t *bgtile = NULL; // SPECTILE/SRB2BACK
|
||||
|
||||
static INT32 timer;
|
||||
|
||||
static INT32 intertic;
|
||||
static INT32 endtic = -1;
|
||||
static INT32 sorttic = -1;
|
||||
|
||||
patch_t *animVoteFramesPatches = NULL;
|
||||
// VEXTRN - Vote (V) Extra (EXT) Race (R) Normal (N - Normal sized patch)
|
||||
// VEXTBN - Vote (V) Extra (EXT) Battle (B) Normal (N - Normal sized patch)
|
||||
// VEXTBW - Vote (V) Extra (EXT) Battle (B) Normal (W - Wide patch used in software)
|
||||
// VEXTRW - Vote (V) Extra (EXT) Race (R) Normal (W - Wide patch used in software)
|
||||
char animPrefix[] = "INTSC";
|
||||
char animWidePrefix[] = "INTSW";
|
||||
char *luaVoteScreen = NULL;
|
||||
|
||||
INT32 currentAnimFrame = 0;
|
||||
static INT32 foundAnimVoteFrames = 0;
|
||||
static INT32 foundAnimVoteWideFrames = 0;
|
||||
|
||||
intertype_t intertype = int_none;
|
||||
|
||||
static huddrawlist_h luahuddrawlist_intermission = NULL;
|
||||
@@ -118,17 +104,13 @@ typedef struct
|
||||
boolean loaded;
|
||||
} y_voteclient;
|
||||
|
||||
// votescreen stuff
|
||||
votescreen_t VoteScreen = {0};
|
||||
|
||||
static y_votelvlinfo levelinfo[5];
|
||||
static y_voteclient voteclient;
|
||||
static INT32 votetic;
|
||||
static INT32 voteendtic = -1;
|
||||
static patch_t *cursor = NULL;
|
||||
static patch_t *cursor1 = NULL;
|
||||
static patch_t *cursor2 = NULL;
|
||||
static patch_t *cursor3 = NULL;
|
||||
static patch_t *cursor4 = NULL;
|
||||
static patch_t *randomlvl = NULL;
|
||||
static patch_t *rubyicon = NULL;
|
||||
|
||||
static void Y_UnloadVoteData(void);
|
||||
|
||||
@@ -287,49 +269,6 @@ static void Y_CalculateMatchData(UINT8 rankingsmode, void (*comparison)(INT32))
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Y_AnimatedVoteScreenCheck
|
||||
//
|
||||
// Check if the lumps exist (checking for VEXTR(N|W)xx for race and VEXTRB(N|W)xx for battle)
|
||||
static void Y_AnimatedVoteScreenCheck(void)
|
||||
{
|
||||
char tmpPrefix[] = "INTS";
|
||||
|
||||
if (luaVoteScreen)
|
||||
strncpy(tmpPrefix, luaVoteScreen, 4);
|
||||
else if (G_BattleGametype())
|
||||
strcpy(tmpPrefix, "BTLS");
|
||||
|
||||
strncpy(animPrefix, tmpPrefix, 4);
|
||||
animPrefix[4] = 'C';
|
||||
strncpy(animWidePrefix, tmpPrefix, 4);
|
||||
animWidePrefix[4] = 'W';
|
||||
|
||||
foundAnimVoteFrames = foundAnimVoteWideFrames = 0;
|
||||
currentAnimFrame = 0;
|
||||
|
||||
INT32 i = 1;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
boolean normalLumpExists = W_LumpExists(va("%sC%d", tmpPrefix, i));
|
||||
boolean wideLumpExists = W_LumpExists(va("%sW%d", tmpPrefix, i));
|
||||
|
||||
if (normalLumpExists || wideLumpExists)
|
||||
{
|
||||
if (normalLumpExists)
|
||||
foundAnimVoteFrames++;
|
||||
|
||||
if (wideLumpExists)
|
||||
foundAnimVoteWideFrames++;
|
||||
}
|
||||
else // If we don't find at least frame 1 (e.g VEXTRN1), let's just stop looking
|
||||
break;
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
// Y_PlayerStandingsDrawer
|
||||
//
|
||||
// Handles drawing the center-of-screen player standings.
|
||||
@@ -863,7 +802,8 @@ void Y_StartIntermission(void)
|
||||
//
|
||||
void Y_EndIntermission(void)
|
||||
{
|
||||
Y_UnloadData();
|
||||
if (!dedicated)
|
||||
Y_UnloadData();
|
||||
|
||||
endtic = -1;
|
||||
sorttic = -1;
|
||||
@@ -881,28 +821,72 @@ static void Y_FollowIntermission(void)
|
||||
G_AfterIntermission();
|
||||
}
|
||||
|
||||
#define UNLOAD(x) if (x) {Patch_Free(x);} x = NULL;
|
||||
#define UNLOAD(x) {if ((x) != NULL) {Patch_Free(x);} x = NULL;}
|
||||
|
||||
//
|
||||
// Y_UnloadData
|
||||
//
|
||||
static void Y_UnloadData(void)
|
||||
{
|
||||
// In hardware mode, don't Z_ChangeTag a pointer returned by W_CachePatchName().
|
||||
// It doesn't work and is unnecessary.
|
||||
if (rendermode != render_soft)
|
||||
return;
|
||||
|
||||
// unload the background patches
|
||||
UNLOAD(bgpatch);
|
||||
UNLOAD(widebgpatch);
|
||||
UNLOAD(VoteScreen.bgpatch);
|
||||
UNLOAD(VoteScreen.widebgpatch);
|
||||
UNLOAD(bgtile);
|
||||
//UNLOAD(interpic);
|
||||
}
|
||||
|
||||
// SRB2Kart: Voting!
|
||||
|
||||
static void Y_DrawVoteBackground(patch_t *patch)
|
||||
//
|
||||
// Y_VoteScreenCheck
|
||||
//
|
||||
static void Y_VoteScreenCheck(void)
|
||||
{
|
||||
strcpy(VoteScreen.Prefix, "INTS");
|
||||
|
||||
if (VoteScreen.luaPrefix[0] != 0)
|
||||
strlcpy(VoteScreen.Prefix, VoteScreen.luaPrefix, sizeof(VoteScreen.Prefix));
|
||||
else if (G_BattleGametype())
|
||||
strcpy(VoteScreen.Prefix, "BTLS");
|
||||
|
||||
VoteScreen.foundLuaVoteFrames = VoteScreen.foundLuaVoteWideFrames = 0;
|
||||
VoteScreen.currentAnimFrame = 0;
|
||||
|
||||
INT32 i = 1;
|
||||
|
||||
// check for lua vote background replacements
|
||||
for (;;)
|
||||
{
|
||||
// Check if the lumps exist (checking for VEXTR(N|W)xx for race and VEXTRB(N|W)xx for battle)
|
||||
boolean normalLumpExists = W_LumpExists(va("%sC%d", VoteScreen.Prefix, i));
|
||||
boolean wideLumpExists = W_LumpExists(va("%sW%d", VoteScreen.Prefix, i));
|
||||
|
||||
if (normalLumpExists || wideLumpExists)
|
||||
{
|
||||
if (normalLumpExists)
|
||||
VoteScreen.foundLuaVoteFrames++;
|
||||
|
||||
if (wideLumpExists)
|
||||
VoteScreen.foundLuaVoteWideFrames++;
|
||||
}
|
||||
else // If we don't find at least frame 1 (e.g VEXTRN1), let's just stop looking
|
||||
break;
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
// non lua vote background handling
|
||||
boolean prefbattletype = ((votelevels[0][1] & ~0x80) == GT_MATCH);
|
||||
VoteScreen.widebgpatch = W_CachePatchName((prefbattletype ? "BATTLSCW" : "INTERSCW"), PU_PATCH);
|
||||
VoteScreen.bgpatch = W_CachePatchName((prefbattletype ? "BATTLSCR" : "INTERSCR"), PU_PATCH);
|
||||
}
|
||||
|
||||
//
|
||||
// Y_VoteBackgroundDrawer
|
||||
//
|
||||
// Determines which patch drawer to use for scaling
|
||||
//
|
||||
static void Y_VoteBackgroundDrawer(patch_t *patch)
|
||||
{
|
||||
switch (cv_votebgscaling.value)
|
||||
{
|
||||
@@ -924,57 +908,74 @@ static void Y_DrawVoteBackground(patch_t *patch)
|
||||
}
|
||||
}
|
||||
|
||||
// Y_DrawAnimatedVoteScreenPatch
|
||||
//
|
||||
// Draw animated patch based on frame counter on vote screen
|
||||
// Y_DrawLuaVoteScreenPatch
|
||||
//
|
||||
static void Y_DrawAnimatedVoteScreenPatch(boolean widePatch)
|
||||
// Handles votebackgrounds set by "setVoteBackground"
|
||||
// Aswell as animated patches
|
||||
//
|
||||
static void Y_DrawLuaVoteScreenPatch(boolean widePatch)
|
||||
{
|
||||
INT32 nextframe = 0;
|
||||
patch_t *votebg = NULL;
|
||||
char tempAnimPrefix[7];
|
||||
const INT32 tempFoundAnimVoteFrames = ((widePatch ? foundAnimVoteWideFrames : foundAnimVoteFrames) - 1);
|
||||
char tempPrefix[6];
|
||||
const INT32 tempfoundAnimLuaVoteFrames = ((widePatch ? VoteScreen.foundLuaVoteWideFrames : VoteScreen.foundLuaVoteFrames) - 1);
|
||||
|
||||
strcpy(tempAnimPrefix, (widePatch ? animWidePrefix : animPrefix));
|
||||
strcpy(tempPrefix, va("%s%s", VoteScreen.Prefix, (widePatch ? "W" : "C")));
|
||||
|
||||
// Draw non animated patch
|
||||
if (!tempfoundAnimLuaVoteFrames)
|
||||
{
|
||||
votebg = W_CachePatchName(va("%s1", tempPrefix), PU_PATCH);
|
||||
Y_VoteBackgroundDrawer(votebg);
|
||||
return;
|
||||
}
|
||||
|
||||
// Draw animated patch based on frame counter on vote screen
|
||||
|
||||
// Just in case someone provides LESS widescreen frames than normal frames or vice versa, reset the frame counter to 0
|
||||
if (currentAnimFrame > tempFoundAnimVoteFrames)
|
||||
currentAnimFrame = 0;
|
||||
if (VoteScreen.currentAnimFrame > tempfoundAnimLuaVoteFrames)
|
||||
VoteScreen.currentAnimFrame = 0;
|
||||
|
||||
nextframe = (currentAnimFrame + 1);
|
||||
nextframe = (VoteScreen.currentAnimFrame + 1);
|
||||
|
||||
votebg = W_CachePatchName(va("%s%d", (widePatch ? animWidePrefix : animPrefix), nextframe), PU_PATCH);
|
||||
votebg = W_CachePatchName(va("%s%d", tempPrefix, nextframe), PU_PATCH);
|
||||
|
||||
Y_DrawVoteBackground(votebg);
|
||||
Y_VoteBackgroundDrawer(votebg);
|
||||
|
||||
if (renderisnewtic && (votetic % 2 == 0) && !paused)
|
||||
currentAnimFrame = (nextframe > tempFoundAnimVoteFrames) ? 0 : nextframe;
|
||||
VoteScreen.currentAnimFrame = (nextframe > tempfoundAnimLuaVoteFrames) ? 0 : nextframe;
|
||||
}
|
||||
|
||||
//
|
||||
// Y_DrawVoteScreenPatch
|
||||
//
|
||||
static void Y_DrawVoteScreenPatch(void)
|
||||
{
|
||||
patch_t *votebg = NULL;
|
||||
const boolean widescreen = (vid.width / vid.dupx > 320);
|
||||
|
||||
if (foundAnimVoteWideFrames || foundAnimVoteFrames)
|
||||
if (VoteScreen.foundLuaVoteWideFrames || VoteScreen.foundLuaVoteFrames)
|
||||
{
|
||||
Y_DrawAnimatedVoteScreenPatch((foundAnimVoteWideFrames && widescreen));
|
||||
Y_DrawLuaVoteScreenPatch(((widescreen && VoteScreen.foundLuaVoteWideFrames) || !VoteScreen.foundLuaVoteFrames));
|
||||
return;
|
||||
}
|
||||
|
||||
votebg = bgpatch; // non widescreen patch
|
||||
// non widescreen patch
|
||||
votebg = VoteScreen.bgpatch;
|
||||
|
||||
UINT8 prefgametype = (votelevels[0][1] & ~0x80);
|
||||
const boolean widebgreplaced = (prefgametype == GT_MATCH) ? widebattlereplaced : wideracereplaced;
|
||||
const boolean bgreplaced = (prefgametype == GT_MATCH) ? battlereplaced : racereplaced;
|
||||
const boolean widebgreplaced = (prefgametype == GT_MATCH) ? VoteScreen.replaced.widebattle : VoteScreen.replaced.widerace;
|
||||
const boolean bgreplaced = (prefgametype == GT_MATCH) ? VoteScreen.replaced.battle : VoteScreen.replaced.race;
|
||||
|
||||
// we check a bunch of stuff to always have a "valid" fallback
|
||||
if ((widescreen && (widebgreplaced || !bgreplaced))
|
||||
|| (!widescreen && (widebgreplaced && !bgreplaced)))
|
||||
{
|
||||
votebg = widebgpatch;
|
||||
votebg = VoteScreen.widebgpatch; // widescreen patch
|
||||
}
|
||||
|
||||
Y_DrawVoteBackground(votebg);
|
||||
Y_VoteBackgroundDrawer(votebg);
|
||||
}
|
||||
|
||||
//
|
||||
@@ -1037,7 +1038,7 @@ void Y_VoteDrawer(void)
|
||||
if (i == 3)
|
||||
{
|
||||
str = "RANDOM";
|
||||
pic = randomlvl;
|
||||
pic = VoteScreen.randomlvl;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1061,7 +1062,7 @@ void Y_VoteDrawer(void)
|
||||
|
||||
if (!splitscreen)
|
||||
{
|
||||
thiscurs = cursor;
|
||||
thiscurs = VoteScreen.cursor[0];
|
||||
p = consoleplayer;
|
||||
color = levelinfo[i].gtc;
|
||||
colormap = NULL;
|
||||
@@ -1071,19 +1072,19 @@ void Y_VoteDrawer(void)
|
||||
switch (j)
|
||||
{
|
||||
case 1:
|
||||
thiscurs = cursor2;
|
||||
thiscurs = VoteScreen.cursor[2];
|
||||
p = displayplayers[1];
|
||||
break;
|
||||
case 2:
|
||||
thiscurs = cursor3;
|
||||
thiscurs = VoteScreen.cursor[3];
|
||||
p = displayplayers[2];
|
||||
break;
|
||||
case 3:
|
||||
thiscurs = cursor4;
|
||||
thiscurs = VoteScreen.cursor[4];
|
||||
p = displayplayers[3];
|
||||
break;
|
||||
default:
|
||||
thiscurs = cursor1;
|
||||
thiscurs = VoteScreen.cursor[1];
|
||||
p = displayplayers[0];
|
||||
break;
|
||||
}
|
||||
@@ -1111,7 +1112,7 @@ void Y_VoteDrawer(void)
|
||||
else
|
||||
{
|
||||
V_DrawFixedPatch((BASEVIDWIDTH-20)<<FRACBITS, (y)<<FRACBITS, FRACUNIT/2, V_FLIP|V_SNAPTORIGHT, pic, 0);
|
||||
V_DrawFixedPatch((BASEVIDWIDTH-60)<<FRACBITS, ((y+25)<<FRACBITS) - (rubyheight<<1), FRACUNIT, V_SNAPTORIGHT, rubyicon, NULL);
|
||||
V_DrawFixedPatch((BASEVIDWIDTH-60)<<FRACBITS, ((y+25)<<FRACBITS) - (rubyheight<<1), FRACUNIT, V_SNAPTORIGHT, VoteScreen.rubyicon, NULL);
|
||||
}
|
||||
|
||||
V_DrawRightAlignedThinString(BASEVIDWIDTH-21, 40+y, V_SNAPTORIGHT|V_6WIDTHSPACE, str);
|
||||
@@ -1135,7 +1136,7 @@ void Y_VoteDrawer(void)
|
||||
else
|
||||
{
|
||||
V_DrawFixedPatch((BASEVIDWIDTH-20)<<FRACBITS, y<<FRACBITS, FRACUNIT/4, V_FLIP|V_SNAPTORIGHT, pic, 0);
|
||||
V_DrawFixedPatch((BASEVIDWIDTH-40)<<FRACBITS, (y<<FRACBITS) + (25<<(FRACBITS-1)) - rubyheight, FRACUNIT/2, V_SNAPTORIGHT, rubyicon, NULL);
|
||||
V_DrawFixedPatch((BASEVIDWIDTH-40)<<FRACBITS, (y<<FRACBITS) + (25<<(FRACBITS-1)) - rubyheight, FRACUNIT/2, V_SNAPTORIGHT, VoteScreen.rubyicon, NULL);
|
||||
}
|
||||
|
||||
if (levelinfo[i].gts)
|
||||
@@ -1164,13 +1165,13 @@ void Y_VoteDrawer(void)
|
||||
patch_t *pic;
|
||||
|
||||
if (votes[i] >= 3 && (i != pickedvote || voteendtic == -1))
|
||||
pic = randomlvl;
|
||||
pic = VoteScreen.randomlvl;
|
||||
else
|
||||
pic = levelinfo[votes[i]].pic;
|
||||
|
||||
if (!timer && i == voteclient.ranim)
|
||||
{
|
||||
V_DrawScaledPatch(x-18, y+9, V_SNAPTOLEFT, cursor);
|
||||
V_DrawScaledPatch(x-18, y+9, V_SNAPTOLEFT, VoteScreen.cursor[0]);
|
||||
if (voteendtic != -1 && !(votetic % 4))
|
||||
V_DrawFill(x-1, y-1, 42, 27, 120|V_SNAPTOLEFT);
|
||||
else
|
||||
@@ -1182,7 +1183,7 @@ void Y_VoteDrawer(void)
|
||||
else
|
||||
{
|
||||
V_DrawFixedPatch((x+40)<<FRACBITS, (y)<<FRACBITS, FRACUNIT/4, V_SNAPTOLEFT|V_FLIP, pic, 0);
|
||||
V_DrawFixedPatch((x+20)<<FRACBITS, (y<<FRACBITS) + (25<<(FRACBITS-1)) - rubyheight, FRACUNIT/2, V_SNAPTOLEFT, rubyicon, NULL);
|
||||
V_DrawFixedPatch((x+20)<<FRACBITS, (y<<FRACBITS) + (25<<(FRACBITS-1)) - rubyheight, FRACUNIT/2, V_SNAPTOLEFT, VoteScreen.rubyicon, NULL);
|
||||
}
|
||||
|
||||
if (levelinfo[votes[i]].gts)
|
||||
@@ -1471,10 +1472,28 @@ void Y_VoteTicker(void)
|
||||
//
|
||||
// MK online style voting screen, appears after intermission
|
||||
//
|
||||
|
||||
static void Y_InitVoteDrawing(void)
|
||||
{
|
||||
if (dedicated)
|
||||
return;
|
||||
|
||||
// setup the background patches
|
||||
Y_VoteScreenCheck();
|
||||
|
||||
VoteScreen.cursor[0] = W_CachePatchName("M_CURSOR", PU_PATCH);
|
||||
VoteScreen.cursor[1] = W_CachePatchName("P1CURSOR", PU_PATCH);
|
||||
VoteScreen.cursor[2] = W_CachePatchName("P2CURSOR", PU_PATCH);
|
||||
VoteScreen.cursor[3] = W_CachePatchName("P3CURSOR", PU_PATCH);
|
||||
VoteScreen.cursor[4] = W_CachePatchName("P4CURSOR", PU_PATCH);
|
||||
|
||||
VoteScreen.randomlvl = W_CachePatchName("RANDOMLV", PU_PATCH);
|
||||
VoteScreen.rubyicon = W_CachePatchName("RUBYICON", PU_PATCH);
|
||||
}
|
||||
|
||||
void Y_StartVote(void)
|
||||
{
|
||||
INT32 i = 0;
|
||||
UINT8 prefgametype = (votelevels[0][1] & ~0x80);
|
||||
|
||||
votetic = -1;
|
||||
|
||||
@@ -1483,17 +1502,8 @@ void Y_StartVote(void)
|
||||
I_Error("voteendtic is dirty");
|
||||
#endif
|
||||
|
||||
Y_AnimatedVoteScreenCheck();
|
||||
|
||||
widebgpatch = W_CachePatchName(((prefgametype == GT_MATCH) ? "BATTLSCW" : "INTERSCW"), PU_PATCH);
|
||||
bgpatch = W_CachePatchName(((prefgametype == GT_MATCH) ? "BATTLSCR" : "INTERSCR"), PU_PATCH);
|
||||
cursor = W_CachePatchName("M_CURSOR", PU_PATCH);
|
||||
cursor1 = W_CachePatchName("P1CURSOR", PU_PATCH);
|
||||
cursor2 = W_CachePatchName("P2CURSOR", PU_PATCH);
|
||||
cursor3 = W_CachePatchName("P3CURSOR", PU_PATCH);
|
||||
cursor4 = W_CachePatchName("P4CURSOR", PU_PATCH);
|
||||
randomlvl = W_CachePatchName("RANDOMLV", PU_PATCH);
|
||||
rubyicon = W_CachePatchName("RUBYICON", PU_PATCH);
|
||||
// cache vote patches
|
||||
Y_InitVoteDrawing();
|
||||
|
||||
timer = cv_votetime.value*TICRATE;
|
||||
pickedvote = -1;
|
||||
@@ -1559,11 +1569,14 @@ void Y_StartVote(void)
|
||||
levelinfo[i].gts = NULL;
|
||||
|
||||
// set up the pic
|
||||
lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(votelevels[i][0]+1)));
|
||||
if (lumpnum != LUMPERROR)
|
||||
levelinfo[i].pic = W_CachePatchName(va("%sP", G_BuildMapName(votelevels[i][0]+1)), PU_PATCH);
|
||||
else
|
||||
levelinfo[i].pic = W_CachePatchName("BLANKLVL", PU_PATCH);
|
||||
if (!dedicated)
|
||||
{
|
||||
lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(votelevels[i][0]+1)));
|
||||
if (lumpnum != LUMPERROR)
|
||||
levelinfo[i].pic = W_CachePatchName(va("%sP", G_BuildMapName(votelevels[i][0]+1)), PU_PATCH);
|
||||
else
|
||||
levelinfo[i].pic = W_CachePatchName("BLANKLVL", PU_PATCH);
|
||||
}
|
||||
}
|
||||
|
||||
voteclient.loaded = true;
|
||||
@@ -1588,18 +1601,18 @@ static void Y_UnloadVoteData(void)
|
||||
{
|
||||
voteclient.loaded = false;
|
||||
|
||||
if (rendermode != render_soft)
|
||||
if (dedicated)
|
||||
return;
|
||||
|
||||
UNLOAD(widebgpatch);
|
||||
UNLOAD(bgpatch);
|
||||
UNLOAD(cursor);
|
||||
UNLOAD(cursor1);
|
||||
UNLOAD(cursor2);
|
||||
UNLOAD(cursor3);
|
||||
UNLOAD(cursor4);
|
||||
UNLOAD(randomlvl);
|
||||
UNLOAD(rubyicon);
|
||||
UNLOAD(VoteScreen.widebgpatch);
|
||||
UNLOAD(VoteScreen.bgpatch);
|
||||
UNLOAD(VoteScreen.cursor[0]);
|
||||
UNLOAD(VoteScreen.cursor[1]);
|
||||
UNLOAD(VoteScreen.cursor[2]);
|
||||
UNLOAD(VoteScreen.cursor[3]);
|
||||
UNLOAD(VoteScreen.cursor[4]);
|
||||
UNLOAD(VoteScreen.randomlvl);
|
||||
UNLOAD(VoteScreen.rubyicon);
|
||||
|
||||
UNLOAD(levelinfo[3].pic);
|
||||
UNLOAD(levelinfo[2].pic);
|
||||
|
||||
+34
-1
@@ -10,7 +10,6 @@
|
||||
/// \brief Tally screens, or "Intermissions" as they were formally called in Doom
|
||||
|
||||
extern boolean usebuffer;
|
||||
extern char *luaVoteScreen;
|
||||
|
||||
void Y_IntermissionDrawer(void);
|
||||
void Y_Ticker(void);
|
||||
@@ -55,3 +54,37 @@ typedef enum
|
||||
int_classicrace, // Competition
|
||||
} intertype_t;
|
||||
extern intertype_t intertype;
|
||||
|
||||
// Votescreen stuff
|
||||
typedef struct
|
||||
{
|
||||
boolean race; // non lua race patch replaced
|
||||
boolean widerace; // non lua widescreen race patch replaced
|
||||
boolean battle; // non lua battle patch replaced
|
||||
boolean widebattle; // non lua widescreen battle patch replaced
|
||||
} votereplace_t;
|
||||
|
||||
// VEXTRN - Vote (V) Extra (EXT) Race (R) Normal (N - Normal sized patch)
|
||||
// VEXTRW - Vote (V) Extra (EXT) Race (R) Normal (W - Wide patch)
|
||||
// VEXTBN - Vote (V) Extra (EXT) Battle (B) Normal (N - Normal sized patch)
|
||||
// VEXTBW - Vote (V) Extra (EXT) Battle (B) Normal (W - Wide patch)
|
||||
typedef struct
|
||||
{
|
||||
char Prefix[5]; // Race = INTSX, Battle = BTLSX
|
||||
char luaPrefix[5]; // prefix for lua votescreens
|
||||
|
||||
INT32 currentAnimFrame; // current animated background frame
|
||||
|
||||
INT32 foundLuaVoteFrames; // normal lua patch frames
|
||||
INT32 foundLuaVoteWideFrames; // widescreen lua patch frames
|
||||
|
||||
votereplace_t replaced; // checks which non lua patch has been replaced
|
||||
|
||||
patch_t *bgpatch; // votebackground patch
|
||||
patch_t *widebgpatch; // wide votebackground patch
|
||||
|
||||
patch_t *cursor[5]; // cursor patches
|
||||
patch_t *randomlvl; // randomlevel patch
|
||||
patch_t *rubyicon; // encore ruby patch
|
||||
} votescreen_t;
|
||||
extern votescreen_t VoteScreen;
|
||||
Reference in new issue
Block a user