From b5310a1f68a912f589798a592dd0f3e104503c47 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 27 Nov 2022 16:45:28 -0800 Subject: [PATCH 01/66] Add typedef.h All typedefs for structs that were present in other header files have been moved to here. (Except node_t because the renderer and netcode both define node_t LOL.) --- src/am_map.h | 8 +- src/command.h | 12 +- src/d_clisrv.h | 80 ++++---- src/d_event.h | 4 +- src/d_netcmd.h | 12 +- src/d_netfil.h | 10 +- src/d_player.h | 16 +- src/d_think.h | 4 +- src/d_ticcmd.h | 4 +- src/deh_tables.h | 4 +- src/dehacked.h | 4 +- src/discord.h | 4 +- src/doomdata.h | 32 +-- src/doomdef.h | 4 +- src/doomstat.h | 44 ++--- src/doomtype.h | 2 + src/font.h | 4 +- src/g_demo.h | 12 +- src/g_game.h | 5 +- src/hu_stuff.h | 4 +- src/i_joy.h | 3 +- src/i_net.h | 12 +- src/i_system.h | 8 +- src/i_time.h | 4 +- src/info.h | 8 +- src/k_bheap.h | 8 +- src/k_boss.h | 4 +- src/k_bot.h | 4 +- src/k_brightmap.h | 4 +- src/k_follower.h | 8 +- src/k_hud.h | 4 +- src/k_menu.h | 24 +-- src/k_pathfind.h | 12 +- src/k_profiles.h | 4 +- src/k_terrain.h | 20 +- src/k_waypoint.h | 4 +- src/lua_hudlib_drawlist.h | 2 - src/m_aatree.c | 2 +- src/m_aatree.h | 1 - src/m_cond.h | 20 +- src/m_dllist.h | 4 +- src/m_fixed.h | 12 +- src/m_perfstats.h | 8 +- src/m_queue.h | 8 +- src/mserv.h | 8 +- src/p_local.h | 20 +- src/p_maputl.h | 8 +- src/p_mobj.h | 12 +- src/p_polyobj.h | 72 +++---- src/p_saveg.h | 4 +- src/p_setup.h | 4 +- src/p_slopes.h | 8 +- src/p_spec.h | 112 +++++------ src/r_data.h | 4 +- src/r_defs.h | 100 +++++----- src/r_draw.h | 4 +- src/r_fps.h | 12 +- src/r_picformats.h | 8 +- src/r_plane.h | 8 +- src/r_portal.h | 4 +- src/r_skins.h | 4 +- src/r_splats.h | 4 +- src/r_state.h | 4 +- src/r_textures.h | 8 +- src/r_things.h | 12 +- src/s_sound.h | 20 +- src/screen.h | 12 +- src/sounds.h | 3 +- src/taglist.h | 8 +- src/typedef.h | 397 ++++++++++++++++++++++++++++++++++++++ src/v_video.h | 4 +- src/w_wad.h | 24 +-- 72 files changed, 867 insertions(+), 478 deletions(-) create mode 100644 src/typedef.h diff --git a/src/am_map.h b/src/am_map.h index 1c8fa70e4..596a17d46 100644 --- a/src/am_map.h +++ b/src/am_map.h @@ -16,15 +16,15 @@ #include "d_event.h" -typedef struct +struct fpoint_t { INT32 x, y; -} fpoint_t; +}; -typedef struct +struct fline_t { fpoint_t a, b; -} fline_t; +}; extern boolean am_recalc; // true if screen size changes extern boolean automapactive; // In AutoMap mode? diff --git a/src/command.h b/src/command.h index 35330d5d4..94cf2f269 100644 --- a/src/command.h +++ b/src/command.h @@ -79,14 +79,14 @@ void COM_Init(void); // Variable sized buffers // ====================== -typedef struct vsbuf_s +struct vsbuf_t { boolean allowoverflow; // if false, do a I_Error boolean overflowed; // set to true if the buffer size failed UINT8 *data; size_t maxsize; size_t cursize; -} vsbuf_t; +}; void VS_Alloc(vsbuf_t *buf, size_t initsize); void VS_Free(vsbuf_t *buf); @@ -127,13 +127,13 @@ typedef enum CV_NOLUA = 4096,/* don't let this be called from Lua */ } cvflags_t; -typedef struct CV_PossibleValue_s +struct CV_PossibleValue_t { INT32 value; const char *strvalue; -} CV_PossibleValue_t; +}; -typedef struct consvar_s //NULL, NULL, 0, NULL, NULL |, 0, NULL, NULL, 0, 0, NULL +struct consvar_s //NULL, NULL, 0, NULL, NULL |, 0, NULL, NULL, 0, 0, NULL { const char *name; const char *defaultvalue; @@ -158,7 +158,7 @@ typedef struct consvar_s //NULL, NULL, 0, NULL, NULL |, 0, NULL, NULL, 0, 0, NUL // used only with CV_NETVAR char changed; // has variable been changed by the user? 0 = no, 1 = yes struct consvar_s *next; -} consvar_t; +}; /* name, defaultvalue, flags, PossibleValue, func */ #define CVAR_INIT( ... ) \ diff --git a/src/d_clisrv.h b/src/d_clisrv.h index eb11ca04a..4effefde8 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -130,43 +130,43 @@ void Command_Numnodes(void); #endif // Client to server packet -typedef struct +struct clientcmd_pak { UINT8 client_tic; UINT8 resendfrom; INT16 consistancy; ticcmd_t cmd; -} ATTRPACK clientcmd_pak; +} ATTRPACK; // Splitscreen packet // WARNING: must have the same format of clientcmd_pak, for more easy use -typedef struct +struct client2cmd_pak { UINT8 client_tic; UINT8 resendfrom; INT16 consistancy; ticcmd_t cmd, cmd2; -} ATTRPACK client2cmd_pak; +} ATTRPACK; // 3P Splitscreen packet // WARNING: must have the same format of clientcmd_pak, for more easy use -typedef struct +struct client3cmd_pak { UINT8 client_tic; UINT8 resendfrom; INT16 consistancy; ticcmd_t cmd, cmd2, cmd3; -} ATTRPACK client3cmd_pak; +} ATTRPACK; // 4P Splitscreen packet // WARNING: must have the same format of clientcmd_pak, for more easy use -typedef struct +struct client4cmd_pak { UINT8 client_tic; UINT8 resendfrom; INT16 consistancy; ticcmd_t cmd, cmd2, cmd3, cmd4; -} ATTRPACK client4cmd_pak; +} ATTRPACK; #ifdef _MSC_VER #pragma warning(disable : 4200) @@ -174,15 +174,15 @@ typedef struct // Server to client packet // this packet is too large -typedef struct +struct servertics_pak { UINT8 starttic; UINT8 numtics; UINT8 numslots; // "Slots filled": Highest player number in use plus one. ticcmd_t cmds[45]; // Normally [BACKUPTIC][MAXPLAYERS] but too large -} ATTRPACK servertics_pak; +} ATTRPACK; -typedef struct +struct serverconfig_pak { UINT8 version; // Different versions don't work UINT8 subversion; // Contains build version @@ -204,9 +204,9 @@ typedef struct UINT8 maxplayer; boolean allownewplayer; boolean discordinvites; -} ATTRPACK serverconfig_pak; +} ATTRPACK; -typedef struct +struct filetx_pak { UINT8 fileid; UINT32 filesize; @@ -214,21 +214,21 @@ typedef struct UINT32 position; UINT16 size; UINT8 data[]; // Size is variable using hardware_MAXPACKETLENGTH -} ATTRPACK filetx_pak; +} ATTRPACK; -typedef struct +struct fileacksegment_t { UINT32 start; UINT32 acks; -} ATTRPACK fileacksegment_t; +} ATTRPACK; -typedef struct +struct fileack_pak { UINT8 fileid; UINT8 iteration; UINT8 numsegments; fileacksegment_t segments[]; -} ATTRPACK fileack_pak; +} ATTRPACK; #ifdef _MSC_VER #pragma warning(default : 4200) @@ -236,7 +236,7 @@ typedef struct #define MAXAPPLICATION 16 -typedef struct +struct clientconfig_pak { UINT8 _255;/* see serverinfo_pak */ UINT8 packetversion; @@ -246,7 +246,7 @@ typedef struct UINT8 localplayers; // number of splitscreen players UINT8 mode; char names[MAXSPLITSCREENPLAYERS][MAXPLAYERNAME]; -} ATTRPACK clientconfig_pak; +} ATTRPACK; #define SV_SPEEDMASK 0x03 // used to send kartspeed #define SV_DEDICATED 0x40 // server is dedicated @@ -256,7 +256,7 @@ typedef struct #define MAXFILENEEDED 915 #define MAX_MIRROR_LENGTH 256 // This packet is too large -typedef struct +struct serverinfo_pak { /* In the old packet, 'version' is the first field. Now that field is set @@ -289,27 +289,27 @@ typedef struct char httpsource[MAX_MIRROR_LENGTH]; // HTTP URL to download from, always defined for compatibility INT16 avgpwrlv; // Kart avg power level UINT8 fileneeded[MAXFILENEEDED]; // is filled with writexxx (byteptr.h) -} ATTRPACK serverinfo_pak; +} ATTRPACK; -typedef struct +struct serverrefuse_pak { char reason[255]; -} ATTRPACK serverrefuse_pak; +} ATTRPACK; -typedef struct +struct askinfo_pak { UINT8 version; tic_t time; // used for ping evaluation -} ATTRPACK askinfo_pak; +} ATTRPACK; -typedef struct +struct msaskinfo_pak { char clientaddr[22]; tic_t time; // used for ping evaluation -} ATTRPACK msaskinfo_pak; +} ATTRPACK; // Shorter player information for external use. -typedef struct +struct plrinfo { UINT8 num; char name[MAXPLAYERNAME+1]; @@ -319,10 +319,10 @@ typedef struct UINT8 data; // Color is first four bits, hasflag, isit and issuper have one bit each, the last is unused. UINT32 score; UINT16 timeinserver; // In seconds. -} ATTRPACK plrinfo; +} ATTRPACK; // Shortest player information for join during intermission. -typedef struct +struct plrconfig { char name[MAXPLAYERNAME+1]; UINT8 skin; @@ -330,20 +330,20 @@ typedef struct UINT32 pflags; UINT32 score; UINT8 ctfteam; -} ATTRPACK plrconfig; +} ATTRPACK; -typedef struct +struct filesneededconfig_pak { INT32 first; UINT8 num; UINT8 more; UINT8 files[MAXFILENEEDED]; // is filled with writexxx (byteptr.h) -} ATTRPACK filesneededconfig_pak; +} ATTRPACK; // // Network packet data // -typedef struct +struct doomdata_t { UINT32 checksum; UINT8 ack; // If not zero the node asks for acknowledgement, the receiver must resend the ack @@ -375,18 +375,18 @@ typedef struct filesneededconfig_pak filesneededcfg; // ??? bytes UINT32 pingtable[MAXPLAYERS+1]; // 68 bytes } u; // This is needed to pack diff packet types data together -} ATTRPACK doomdata_t; +} ATTRPACK; #if defined(_MSC_VER) #pragma pack() #endif #define MAXSERVERLIST (MAXNETNODES-1) -typedef struct +struct serverelem_t { SINT8 node; serverinfo_pak info; -} serverelem_t; +}; extern serverelem_t serverlist[MAXSERVERLIST]; extern UINT32 serverlistcount; @@ -528,7 +528,7 @@ extern boolean hu_stopped; // SRB2Kart // -typedef struct rewind_s { +struct rewind_s { UINT8 savebuffer[(768*1024)]; tic_t leveltime; size_t demopos; @@ -537,7 +537,7 @@ typedef struct rewind_s { mobj_t oldghost[MAXPLAYERS]; struct rewind_s *next; -} rewind_t; +}; void CL_ClearRewinds(void); rewind_t *CL_SaveRewindPoint(size_t demopos); diff --git a/src/d_event.h b/src/d_event.h index 5a8c915a3..3ae1010c4 100644 --- a/src/d_event.h +++ b/src/d_event.h @@ -28,14 +28,14 @@ typedef enum } evtype_t; // Event structure. -typedef struct +struct event_t { evtype_t type; INT32 data1; // keys / mouse/joystick buttons INT32 data2; // mouse/joystick x move INT32 data3; // mouse/joystick y move INT32 device; // which player's device it belongs to -} event_t; +}; // // GLOBAL VARIABLES diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 1583ec5d8..3f4d00645 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -217,22 +217,22 @@ extern const char *netxcmdnames[MAXNETXCMD - 1]; //Packet composition for Command_TeamChange_f() ServerTeamChange, etc. //bitwise structs make packing bits a little easier, but byte alignment harder? //todo: decide whether to make the other netcommands conform, or just get rid of this experiment. -typedef struct { +struct changeteam_packet_t { UINT32 playernum : 5; // value 0 to 31 UINT32 newteam : 5; // value 0 to 31 UINT32 verification : 1; // value 0 to 1 UINT32 autobalance : 1; // value 0 to 1 UINT32 scrambled : 1; // value 0 to 1 -} ATTRPACK changeteam_packet_t; +} ATTRPACK; #ifdef _MSC_VER #pragma warning(default : 4214) #endif -typedef struct { +struct changeteam_value_t { UINT16 l; // liitle endian UINT16 b; // big enian -} ATTRPACK changeteam_value_t; +} ATTRPACK; //Since we do not want other files/modules to know about this data buffer we union it here with a Short Int. //Other files/modules will hand the INT16 back to us and we will decode it here. @@ -270,12 +270,12 @@ void RemoveAdminPlayer(INT32 playernum); void ItemFinder_OnChange(void); void D_SetPassword(const char *pw); -typedef struct +struct scheduleTask_t { UINT16 basetime; UINT16 timer; char *command; -} scheduleTask_t; +}; extern scheduleTask_t **schedule; extern size_t schedule_size; diff --git a/src/d_netfil.h b/src/d_netfil.h index 59fdd99e3..2bc415406 100644 --- a/src/d_netfil.h +++ b/src/d_netfil.h @@ -37,7 +37,7 @@ typedef enum FS_FALLBACK, // HTTP failed } filestatus_t; -typedef struct +struct fileneeded_t { UINT8 willsend; // Is the server willing to send it? char filename[MAX_WADPATH]; @@ -54,7 +54,7 @@ typedef struct UINT32 currentsize; UINT32 totalsize; UINT32 ackresendposition; // Used when resuming downloads -} fileneeded_t; +}; extern INT32 fileneedednum; extern fileneeded_t fileneeded[MAX_WADFILES]; @@ -71,8 +71,6 @@ extern boolean curl_failedwebdownload; extern boolean curl_running; extern INT32 curl_transfers; -typedef struct HTTP_login HTTP_login; - extern struct HTTP_login { char * url; @@ -112,7 +110,7 @@ typedef enum LFTNS_SENT // The node already has the file } luafiletransfernodestatus_t; -typedef struct luafiletransfer_s +struct luafiletransfer_s { char *filename; char *realfilename; @@ -122,7 +120,7 @@ typedef struct luafiletransfer_s luafiletransfernodestatus_t nodestatus[MAXNETNODES]; tic_t nodetimeouts[MAXNETNODES]; struct luafiletransfer_s *next; -} luafiletransfer_t; +}; extern luafiletransfer_t *luafiletransfers; extern boolean waitingforluafiletransfer; diff --git a/src/d_player.h b/src/d_player.h index e9ebe7668..cfd72df1c 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -287,7 +287,7 @@ typedef enum #define GARDENTOP_MAXGRINDTIME (45) // player_t struct for all respawn variables -typedef struct respawnvars_s +struct respawnvars_t { UINT8 state; // see RESPAWNST_ constants in k_respawn.h waypoint_t *wp; // Waypoint that we're going towards, NULL if the position isn't linked to one @@ -301,10 +301,10 @@ typedef struct respawnvars_s tic_t dropdash; // Drop Dash charge timer boolean truedeath; // Your soul has left your body boolean manual; // Respawn coords were manually set, please respawn exactly there -} respawnvars_t; +}; // player_t struct for all bot variables -typedef struct botvars_s +struct botvars_t { UINT8 difficulty; // Bot's difficulty setting UINT8 diffincrease; // In GP: bot difficulty will increase this much next round @@ -321,18 +321,18 @@ typedef struct botvars_s SINT8 turnconfirm; // Confirm turn direction tic_t spindashconfirm; // When high enough, they will try spindashing -} botvars_t; +}; // player_t struct for all skybox variables -typedef struct { +struct skybox_t { mobj_t * viewpoint; mobj_t * centerpoint; -} skybox_t; +}; // ======================================================================== // PLAYER STRUCTURE // ======================================================================== -typedef struct player_s +struct player_s { mobj_t *mo; @@ -612,6 +612,6 @@ typedef struct player_s #ifdef HWRENDER fixed_t fovadd; // adjust FOV for hw rendering #endif -} player_t; +}; #endif diff --git a/src/d_think.h b/src/d_think.h index 4bdac4627..8f786a4ed 100644 --- a/src/d_think.h +++ b/src/d_think.h @@ -40,7 +40,7 @@ typedef union typedef actionf_t think_t; // Doubly linked list of actors. -typedef struct thinker_s +struct thinker_s { struct thinker_s *prev; struct thinker_s *next; @@ -49,6 +49,6 @@ typedef struct thinker_s // killough 11/98: count of how many other objects reference // this one using pointers. Used for garbage collection. INT32 references; -} thinker_t; +}; #endif diff --git a/src/d_ticcmd.h b/src/d_ticcmd.h index 4cf1e7c97..7cf95cb0a 100644 --- a/src/d_ticcmd.h +++ b/src/d_ticcmd.h @@ -63,7 +63,7 @@ typedef enum #pragma pack(1) #endif -typedef struct +struct ticcmd_t { SINT8 forwardmove; // -MAXPLMOVE to MAXPLMOVE (50) INT16 turning; // Turn speed @@ -72,7 +72,7 @@ typedef struct UINT16 buttons; UINT8 latency; // Netgames: how many tics ago was this ticcmd generated from this player's end? UINT8 flags; -} ATTRPACK ticcmd_t; +} ATTRPACK; #if defined(_MSC_VER) #pragma pack() diff --git a/src/deh_tables.h b/src/deh_tables.h index cfb676172..8103634a3 100644 --- a/src/deh_tables.h +++ b/src/deh_tables.h @@ -41,11 +41,11 @@ struct flickytypes_s { /** Action pointer for reading actions from Dehacked lumps. */ -typedef struct +struct actionpointer_t { actionf_t action; ///< Function pointer corresponding to the actual action. const char *name; ///< Name of the action in ALL CAPS. -} actionpointer_t; +}; struct int_const_s { const char *n; diff --git a/src/dehacked.h b/src/dehacked.h index 88d303b33..63cf9cedd 100644 --- a/src/dehacked.h +++ b/src/dehacked.h @@ -57,13 +57,13 @@ extern UINT8 superstack; // the code was first write for a file // converted to use memory with this functions -typedef struct +struct MYFILE { char *data; char *curpos; size_t size; UINT16 wad; -} MYFILE; +}; #define myfeof(a) (a->data + a->size <= a->curpos) char *myfgets(char *buf, size_t bufsize, MYFILE *f); char *myhashfgets(char *buf, size_t bufsize, MYFILE *f); diff --git a/src/discord.h b/src/discord.h index a6bb1134a..99444b3cd 100644 --- a/src/discord.h +++ b/src/discord.h @@ -27,7 +27,7 @@ extern struct discordInfo_s { boolean everyoneCanInvite; } discordInfo; -typedef struct discordRequest_s { +struct discordRequest_s { char *username; // Discord user name. char *discriminator; // Discord discriminator (The little hashtag thing after the username). Separated for a "hide discriminators" cvar. char *userID; // The ID of the Discord user, gets used with Discord_Respond() @@ -40,7 +40,7 @@ typedef struct discordRequest_s { struct discordRequest_s *next; // Next request in the list. struct discordRequest_s *prev; // Previous request in the list. Not used normally, but just in case something funky happens, this should repair the list. -} discordRequest_t; +}; extern discordRequest_t *discordRequestList; diff --git a/src/doomdata.h b/src/doomdata.h index 6d3a6386c..0c02c17d4 100644 --- a/src/doomdata.h +++ b/src/doomdata.h @@ -68,24 +68,24 @@ enum #endif // A single Vertex. -typedef struct +struct mapvertex_t { INT16 x, y; -}ATTRPACK mapvertex_t; +}ATTRPACK; // A SideDef, defining the visual appearance of a wall, // by setting textures and offsets. -typedef struct +struct mapsidedef_t { INT16 textureoffset, rowoffset; char toptexture[8], bottomtexture[8], midtexture[8]; // Front sector, towards viewer. INT16 sector; -} ATTRPACK mapsidedef_t; +} ATTRPACK; // A LineDef, as used for editing, and as input // to the BSP builder. -typedef struct +struct maplinedef_t { INT16 v1, v2; INT16 flags; @@ -93,7 +93,7 @@ typedef struct INT16 tag; // sidenum[1] will be 0xffff if one sided UINT16 sidenum[2]; -} ATTRPACK maplinedef_t; +} ATTRPACK; // // LineDef attributes. @@ -152,7 +152,7 @@ enum }; // Sector definition, from editing. -typedef struct +struct mapsector_t { INT16 floorheight; INT16 ceilingheight; @@ -161,34 +161,34 @@ typedef struct INT16 lightlevel; INT16 special; INT16 tag; -} ATTRPACK mapsector_t; +} ATTRPACK; // SubSector, as generated by BSP. -typedef struct +struct mapsubsector_t { UINT16 numsegs; // Index of first one, segs are stored sequentially. UINT16 firstseg; -} ATTRPACK mapsubsector_t; +} ATTRPACK; // LineSeg, generated by splitting LineDefs // using partition lines selected by BSP builder. -typedef struct +struct mapseg_t { INT16 v1, v2; INT16 angle; INT16 linedef; INT16 side; INT16 offset; -} ATTRPACK mapseg_t; +} ATTRPACK; // BSP node structure. // Indicate a leaf. #define NF_SUBSECTOR 0x8000 -typedef struct +struct mapnode_t { // Partition line from (x,y) to x+dx,y+dy) INT16 x, y; @@ -199,7 +199,7 @@ typedef struct // If NF_SUBSECTOR it's a subsector, else it's a node of another subtree. UINT16 children[2]; -} ATTRPACK mapnode_t; +} ATTRPACK; #if defined(_MSC_VER) #pragma pack() @@ -210,7 +210,7 @@ typedef struct // Thing definition, position, orientation and type, // plus visibility flags and attributes. -typedef struct +struct mapthing_t { INT16 x, y; INT16 angle, pitch, roll; @@ -223,7 +223,7 @@ typedef struct INT32 args[NUMMAPTHINGARGS]; char *stringargs[NUMMAPTHINGSTRINGARGS]; struct mobj_s *mobj; -} mapthing_t; +}; #define ZSHIFT 4 diff --git a/src/doomdef.h b/src/doomdef.h index 8271a4ae2..f54916599 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -210,7 +210,7 @@ extern char logfilename[1024]; // Master Server compatibility ONLY #define MSCOMPAT_MAXPLAYERS (32) -typedef struct skincolor_s +struct skincolor_t { char name[MAXCOLORNAME+1]; // Skincolor name UINT8 ramp[COLORRAMPSIZE]; // Colormap ramp @@ -218,7 +218,7 @@ typedef struct skincolor_s UINT8 invshade; // Signpost color shade UINT16 chatcolor; // Chat color boolean accessible; // Accessible by the color command + setup menu -} skincolor_t; +}; #define FOLLOWERCOLOR_MATCH UINT16_MAX #define FOLLOWERCOLOR_OPPOSITE (UINT16_MAX-1) diff --git a/src/doomstat.h b/src/doomstat.h index 3338e9b76..739c69ad2 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -92,12 +92,12 @@ typedef enum PRECIPFX_WATERPARTICLES = 1<<2 } precipeffect_t; -typedef struct +struct precipprops_t { const char *name; mobjtype_t type; precipeffect_t effects; -} precipprops_t; +}; extern precipprops_t precipprops[MAXPRECIP]; extern preciptype_t precip_freeslot; @@ -107,13 +107,13 @@ extern preciptype_t curWeather; /** Time attack information, currently a very small structure. */ -typedef struct +struct recorddata_t { tic_t time; ///< Time in which the level was finished. tic_t lap; ///< Best lap time for this level. //UINT32 score; ///< Score when the level was finished. //UINT16 rings; ///< Rings when the level was finished. -} recorddata_t; +}; // mapvisited is now a set of flags that says what we've done in the map. #define MV_VISITED (1) @@ -220,7 +220,7 @@ extern UINT16 skincolor_redteam, skincolor_blueteam, skincolor_redring, skincolo extern boolean exitfadestarted; -typedef struct +struct scene_t { UINT8 numpics; char picname[8][8]; @@ -240,13 +240,13 @@ typedef struct UINT8 fadecolor; // Color number for fade, 0 means don't do the first fade UINT8 fadeinid; // ID of the first fade, to a color -- ignored if fadecolor is 0 UINT8 fadeoutid; // ID of the second fade, to the new screen -} scene_t; // TODO: It would probably behoove us to implement subsong/track selection here, too, but I'm lazy -SH +}; // TODO: It would probably behoove us to implement subsong/track selection here, too, but I'm lazy -SH -typedef struct +struct cutscene_t { scene_t scene[128]; // 128 scenes per cutscene. INT32 numscenes; // Number of scenes in this cutscene -} cutscene_t; +}; extern cutscene_t *cutscenes[128]; @@ -261,7 +261,7 @@ extern cutscene_t *cutscenes[128]; #define PROMPT_PIC_LOOP 1 #define PROMPT_PIC_DESTROY 2 #define MAX_PROMPT_PICS 8 -typedef struct +struct textpage_t { UINT8 numpics; UINT8 picmode; // sequence mode after displaying last pic, 0 = persist, 1 = loop, 2 = destroy @@ -294,13 +294,13 @@ typedef struct char nexttag[33]; // next tag to jump to. If set, this overrides nextprompt and nextpage. INT32 timetonext; // time in tics to jump to next page automatically. 0 = don't jump automatically char *text; -} textpage_t; +}; -typedef struct +struct textprompt_t { textpage_t page[MAX_PAGES]; INT32 numpages; // Number of pages in this prompt -} textprompt_t; +}; extern textprompt_t *textprompts[MAX_PROMPTS]; @@ -316,10 +316,10 @@ extern mapthing_t *rflagpoint, *bflagpoint; // Pointers to the flag spawn locati #define GF_BLUEFLAG 2 // A single point in space. -typedef struct +struct mappoint_t { fixed_t x, y, z; -} mappoint_t; +}; extern struct quake { @@ -333,11 +333,11 @@ extern struct quake } quake; // Custom Lua values -typedef struct +struct customoption_t { char option[32]; // 31 usable characters char value[256]; // 255 usable characters. If this seriously isn't enough then wtf. -} customoption_t; +}; // This could support more, but is that a good idea? // Keep in mind that it may encourage people making overly long cups just because they "can", and would be a waste of memory. @@ -347,7 +347,7 @@ typedef struct #define CUPCACHE_SPECIAL (CUPCACHE_BONUS+MAXBONUSLIST) #define CUPCACHE_MAX (CUPCACHE_SPECIAL+1) -typedef struct cupheader_s +struct cupheader_s { UINT16 id; ///< Cup ID char name[15]; ///< Cup title (14 chars) @@ -359,7 +359,7 @@ typedef struct cupheader_s UINT8 emeraldnum; ///< ID of Emerald to use for special stage (1-7 for Chaos Emeralds, 8-14 for Super Emeralds, 0 for no emerald) SINT8 unlockrequired; ///< An unlockable is required to select this cup. -1 for no unlocking required. struct cupheader_s *next; ///< Next cup in linked list -} cupheader_t; +}; extern cupheader_t *kartcupheaders; // Start of cup linked list extern UINT16 numkartcupheaders; @@ -368,7 +368,7 @@ extern UINT16 numkartcupheaders; /** Map header information. */ -typedef struct +struct mapheader_t { // Core game information, not user-modifiable directly char *lumpname; ///< Lump name can be really long @@ -441,7 +441,7 @@ typedef struct // Lua information UINT8 numCustomOptions; ///< Internal. For Lua custom value support. customoption_t *customopts; ///< Custom options. Allocated dynamically for space reasons. Be careful. -} mapheader_t; +}; // level flags #define LF_SCRIPTISFILE (1<<0) ///< True if the script is a file, not a lump. @@ -530,11 +530,11 @@ enum TypeOfLevel #define NUMBASETOLNAMES (4) #define NUMTOLNAMES (NUMBASETOLNAMES + NUMGAMETYPEFREESLOTS) -typedef struct +struct tolinfo_t { const char *name; UINT32 flag; -} tolinfo_t; +}; extern tolinfo_t TYPEOFLEVEL[NUMTOLNAMES]; extern UINT32 lastcustomtol; diff --git a/src/doomtype.h b/src/doomtype.h index 4aabab8b0..95f060008 100644 --- a/src/doomtype.h +++ b/src/doomtype.h @@ -406,4 +406,6 @@ typedef UINT64 precise_t; #define FUNCPTRCAST(p) ((union{void(*f)(void);void*v;})\ {(void(*)(void))p}).v +#include "typedef.h" + #endif //__DOOMTYPE__ diff --git a/src/font.h b/src/font.h index 88bedb44f..0cc6610d0 100644 --- a/src/font.h +++ b/src/font.h @@ -15,9 +15,7 @@ #define MAX_FONTS 32 -typedef struct font font_t; - -struct font +struct font_t { patch_t **font; diff --git a/src/g_demo.h b/src/g_demo.h index a00756a74..78e544342 100644 --- a/src/g_demo.h +++ b/src/g_demo.h @@ -28,12 +28,12 @@ extern consvar_t cv_recordmultiplayerdemos, cv_netdemosyncquality; extern tic_t demostarttime; -typedef struct democharlist_s { +struct democharlist_t { UINT8 mapping; // No, this isn't about levels. It maps to loaded character ID. UINT8 kartspeed; UINT8 kartweight; UINT32 flags; -} democharlist_t; +}; // Publicly-accessible demo vars struct demovars_s { @@ -76,7 +76,7 @@ typedef enum { MD_INVALID } menudemotype_e; -typedef struct menudemo_s { +struct menudemo_t { char filepath[256]; menudemotype_e type; @@ -93,7 +93,7 @@ typedef struct menudemo_s { UINT8 skin, color; UINT32 timeorscore; } standings[MAXPLAYERS]; -} menudemo_t; +}; extern mobj_t *metalplayback; @@ -160,7 +160,7 @@ void G_LoadMetal(UINT8 **buffer); // Your naming conventions are stupid and useless. // There is no conflict here. -typedef struct demoghost { +struct demoghost { UINT8 checksum[16]; UINT8 *buffer, *p, color; UINT8 fadein; @@ -169,7 +169,7 @@ typedef struct demoghost { democharlist_t *skinlist; mobj_t oldmo, *mo; struct demoghost *next; -} demoghost; +}; extern demoghost *ghosts; // G_CheckDemoExtraFiles: checks if our loaded WAD list matches the demo's. diff --git a/src/g_game.h b/src/g_game.h index 9c0bec553..0108cc06d 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -135,7 +135,7 @@ struct searchdim UINT8 siz; }; -typedef struct +struct mapsearchfreq_t { INT16 mapnum; UINT8 matchc; @@ -143,8 +143,7 @@ typedef struct UINT8 keywhc; struct searchdim *keywhd;/* ...in KEYWORD */ UINT8 total;/* total hits */ -} -mapsearchfreq_t; +}; INT32 G_FindMap(const char *query, char **foundmapnamep, mapsearchfreq_t **freqp, INT32 *freqc); diff --git a/src/hu_stuff.h b/src/hu_stuff.h index be0d97df9..078cd0751 100644 --- a/src/hu_stuff.h +++ b/src/hu_stuff.h @@ -81,12 +81,12 @@ extern char english_shiftxform[]; // sorted player lines //------------------------------------ -typedef struct +struct playersort_t { UINT32 count; INT32 num; const char *name; -} playersort_t; +}; //------------------------------------ // chat stuff diff --git a/src/i_joy.h b/src/i_joy.h index b10f4c55d..eb83a6649 100644 --- a/src/i_joy.h +++ b/src/i_joy.h @@ -38,7 +38,7 @@ actually, we need to know if it is a gamepad or analog controls */ -struct JoyType_s +struct JoyType_t { /*! if true, we MUST Poll() to get new joystick data, that is: we NEED the DIRECTINPUTDEVICE2 ! (watchout NT compatibility) */ @@ -48,7 +48,6 @@ struct JoyType_s INT32 bGamepadStyle; }; -typedef struct JoyType_s JoyType_t; /** \brief Joystick info for palyer[sic] 1-4's joystick/gamepad */ diff --git a/src/i_net.h b/src/i_net.h index 8ad08e08c..bc98dca8e 100644 --- a/src/i_net.h +++ b/src/i_net.h @@ -40,7 +40,7 @@ extern INT32 net_bandwidth; // in byte/s #pragma pack(1) #endif -typedef struct +struct doomcom_t { /// Supposed to be DOOMCOM_ID INT32 id; @@ -77,14 +77,14 @@ typedef struct /// The packet data to be sent. char data[MAXPACKETLENGTH]; -} ATTRPACK doomcom_t; +} ATTRPACK; -typedef struct +struct holepunch_t { INT32 magic; INT32 addr; INT16 port; -} ATTRPACK holepunch_t; +} ATTRPACK; #if defined(_MSC_VER) #pragma pack() @@ -172,11 +172,11 @@ extern boolean (*I_SetBanUsername) (const char *username); extern boolean (*I_SetBanReason) (const char *reason); extern boolean (*I_SetUnbanTime) (time_t timestamp); -typedef struct +struct bannednode_t { size_t banid; time_t timeleft; -} bannednode_t; +}; extern bannednode_t *bannednode; /// \brief Called by D_SRB2Main to be defined by extern network driver diff --git a/src/i_system.h b/src/i_system.h index 75e7b49e1..e7b9f2bf5 100644 --- a/src/i_system.h +++ b/src/i_system.h @@ -128,7 +128,7 @@ typedef enum NumberofForces, } FFType; -typedef struct JoyFF_s +struct JoyFF_t { INT32 ForceX; ///< The X of the Force's Vel INT32 ForceY; ///< The Y of the Force's Vel @@ -144,7 +144,7 @@ typedef struct JoyFF_s INT32 Offset; ///< Offset of the effect. UINT32 Phase; ///< Position in the cycle of the periodic effect at which playback begins, in the range from 0 through 35,999 UINT32 Period; ///< Period of the effect, in microseconds. -} JoyFF_t; +}; /** \brief Forcefeedback for the first joystick @@ -298,7 +298,7 @@ char *I_GetUserName(void); */ INT32 I_mkdir(const char *dirname, INT32 unixright); -typedef struct { +struct CPUInfoFlags { int FPU : 1; ///< FPU availabile int CPUID : 1; ///< CPUID instruction int RDTSC : 1; ///< RDTSC instruction @@ -324,7 +324,7 @@ typedef struct { int ALPHAbyte : 1; ///< ? int PAE : 1; ///< Physical Address Extension int CPUs : 8; -} CPUInfoFlags; +}; /** \brief Info about CPU diff --git a/src/i_time.h b/src/i_time.h index cab36133b..8d90c3d09 100644 --- a/src/i_time.h +++ b/src/i_time.h @@ -22,10 +22,10 @@ extern "C" { #endif -typedef struct timestate_s { +struct timestate_t { tic_t time; fixed_t timefrac; -} timestate_t; +}; extern timestate_t g_time; extern consvar_t cv_timescale; diff --git a/src/info.h b/src/info.h index 7dff6e2de..4425b4dc8 100644 --- a/src/info.h +++ b/src/info.h @@ -5567,7 +5567,7 @@ typedef enum state NUMSTATES } statenum_t; -typedef struct +struct state_t { spritenum_t sprite; UINT32 frame; // we use the upper 16 bits for translucency and other shade effects @@ -5576,7 +5576,7 @@ typedef struct INT32 var1; INT32 var2; statenum_t nextstate; -} state_t; +}; extern state_t states[NUMSTATES]; extern char sprnames[NUMSPRITES + 1][5]; @@ -6680,7 +6680,7 @@ typedef enum mobj_type NUMMOBJTYPES } mobjtype_t; -typedef struct +struct mobjinfo_t { INT32 doomednum; statenum_t spawnstate; @@ -6706,7 +6706,7 @@ typedef struct sfxenum_t activesound; UINT32 flags; statenum_t raisestate; -} mobjinfo_t; +}; extern mobjinfo_t mobjinfo[NUMMOBJTYPES]; diff --git a/src/k_bheap.h b/src/k_bheap.h index 04e37492c..881a8973c 100644 --- a/src/k_bheap.h +++ b/src/k_bheap.h @@ -17,21 +17,21 @@ typedef void(*updateindexfunc)(void *const, const size_t); -typedef struct bheapitem_s +struct bheapitem_t { size_t heapindex; // The index in the heap this item is updateindexfunc indexchanged; // A callback function that is called when this item changes index to alert data struct bheap_s *owner; // The heap that owns this item void *data; // data for this heap item UINT32 value; // The value of this item, the lowest value item is first in the array -} bheapitem_t; +}; -typedef struct bheap_s +struct bheap_s { size_t capacity; // capacity of the heap size_t count; // number of items in the heap bheapitem_t *array; // pointer to the heap items array -} bheap_t; +}; /*-------------------------------------------------- diff --git a/src/k_boss.h b/src/k_boss.h index db335bb07..f24365b29 100644 --- a/src/k_boss.h +++ b/src/k_boss.h @@ -26,14 +26,14 @@ typedef enum #define NUMWEAKSPOTS 8 #define WEAKSPOTANIMTIME (3*TICRATE) -typedef struct weakspot_t +struct weakspot_t { mobj_t *spot; spottype_t type; tic_t time; UINT16 color; boolean minimap; -} weakspot_t; +}; #define BOSSHEALTHBARLEN 110 diff --git a/src/k_bot.h b/src/k_bot.h index 858e4f331..60d22700d 100644 --- a/src/k_bot.h +++ b/src/k_bot.h @@ -31,10 +31,10 @@ #define BOTSPINDASHCONFIRM (2*TICRATE) // Point for bots to aim for -typedef struct botprediction_s { +struct botprediction_t { fixed_t x, y; fixed_t radius; -} botprediction_t; +}; // AVAILABLE FOR LUA diff --git a/src/k_brightmap.h b/src/k_brightmap.h index 9ed86b125..2c22a171f 100644 --- a/src/k_brightmap.h +++ b/src/k_brightmap.h @@ -17,7 +17,7 @@ #include "doomdef.h" #include "doomtype.h" -typedef struct brightmapStorage_s +struct brightmapStorage_t { // Brightmap storage struct. // Stores data for brightmap definitions, @@ -28,7 +28,7 @@ typedef struct brightmapStorage_s char brightmapName[9]; // The brightmap's name. UINT32 brightmapHash; // The brightmap name's hash. -} brightmapStorage_t; +}; /*-------------------------------------------------- void K_InitBrightmapsPwad(INT32 wadNum); diff --git a/src/k_follower.h b/src/k_follower.h index 3c1e2a7d1..13c67bb11 100644 --- a/src/k_follower.h +++ b/src/k_follower.h @@ -43,7 +43,7 @@ typedef enum // // We'll define these here because they're really just a mobj that'll follow some rules behind a player // -typedef struct follower_s +struct follower_t { char name[SKINNAMESIZE+1]; // Skin Name. This is what to refer to when asking the commands anything.. char icon[8+1]; // Lump names are only 8 characters. (+1 for \0) @@ -81,19 +81,19 @@ typedef struct follower_s statenum_t losestate; // state when the player has lost statenum_t hitconfirmstate; // state for hit confirm tic_t hitconfirmtime; // time to keep the above playing for -} follower_t; +}; extern INT32 numfollowers; extern follower_t followers[MAXSKINS]; #define MAXFOLLOWERCATEGORIES 32 -typedef struct followercategory_s +struct followercategory_t { char name[SKINNAMESIZE+1]; // Name. This is used for the menus. We'll just follow the same rules as skins for this. char icon[8+1]; // Lump names are only 8 characters. (+1 for \0) UINT8 numincategory; -} followercategory_t; +}; extern INT32 numfollowercategories; extern followercategory_t followercategories[MAXFOLLOWERCATEGORIES]; diff --git a/src/k_hud.h b/src/k_hud.h index 4f84f9dd3..eac04aba2 100644 --- a/src/k_hud.h +++ b/src/k_hud.h @@ -23,12 +23,12 @@ void K_AdjustXYWithSnap(INT32 *x, INT32 *y, UINT32 options, INT32 dupx, INT32 dupy); -typedef struct trackingResult_s +struct trackingResult_t { fixed_t x, y; fixed_t scale; boolean onScreen; -} trackingResult_t; +}; void K_ObjectTracking(trackingResult_t *result, vector3_t *point, boolean reverse); diff --git a/src/k_menu.h b/src/k_menu.h index 588542002..7e222d212 100644 --- a/src/k_menu.h +++ b/src/k_menu.h @@ -107,11 +107,11 @@ typedef union } itemaction_t; // Player Setup menu colors linked list -typedef struct menucolor_s { +struct menucolor_s { struct menucolor_s *next; struct menucolor_s *prev; UINT16 color; -} menucolor_t; +}; extern menucolor_t *menucolorhead, *menucolortail; @@ -121,7 +121,7 @@ extern CV_PossibleValue_t gametype_cons_t[]; // MENU TYPEDEFS // -typedef struct menuitem_s +struct menuitem_t { UINT16 status; // show IT_xxx @@ -134,9 +134,9 @@ typedef struct menuitem_s // extra variables INT32 mvar1; INT32 mvar2; -} menuitem_t; +}; -typedef struct menu_s +struct menu_s { INT16 numitems; // # of menu items struct menu_s *prevMenu; // previous menu @@ -155,7 +155,7 @@ typedef struct menu_s void (*initroutine)(void); // called when starting a new menu boolean (*quitroutine)(void); // called before quit a menu return true if we can boolean (*inputroutine)(INT32); // if set, called every frame in the input handler. Returning true overwrites normal input handling. -} menu_t; +}; typedef enum { @@ -522,7 +522,7 @@ typedef enum MBT_START = 1<<8 } menuButtonCode_t; -typedef struct menucmd_s +struct menucmd_t { SINT8 dpad_ud; // up / down dpad SINT8 dpad_lr; // left / right @@ -530,7 +530,7 @@ typedef struct menucmd_s UINT32 buttonsHeld; // prev frame's buttons UINT16 delay; // menu wait UINT32 delayCount; // num times ya did menu wait (to make the wait shorter each time) -} menucmd_t; +}; extern menucmd_t menucmd[MAXSPLITSCREENPLAYERS]; @@ -607,7 +607,7 @@ typedef enum CSSTEP_READY } setup_mdepth_t; -typedef struct setup_player_s +struct setup_player_t { SINT8 gridx, gridy; UINT8 profilen; @@ -633,7 +633,7 @@ typedef struct setup_player_s tic_t follower_timer; UINT8 follower_frame; state_t *follower_state; -} setup_player_t; +}; extern setup_player_t setup_player[MAXSPLITSCREENPLAYERS]; @@ -800,12 +800,12 @@ void M_ServerListFillDebug(void); // Options menu: // mode descriptions for video mode menu -typedef struct +struct modedesc_t { INT32 modenum; // video mode number in the vidmodes list const char *desc; // XXXxYYY UINT8 goodratio; // aspect correct if 1 -} modedesc_t; +}; #define MAXCOLUMNMODES 12 //max modes displayed in one column diff --git a/src/k_pathfind.h b/src/k_pathfind.h index 3d08d87e7..c18911202 100644 --- a/src/k_pathfind.h +++ b/src/k_pathfind.h @@ -35,27 +35,27 @@ typedef boolean(*getpathfindfinishedfunc)(void*, void*); // A pathfindnode contains information about a node from the pathfinding // heapindex is only used within the pathfinding algorithm itself, and is always 0 after it is completed -typedef struct pathfindnode_s { +struct pathfindnode_s { size_t heapindex; // The index in the openset binary heap. Only valid while the node is in the openset. void *nodedata; struct pathfindnode_s *camefrom; // should eventually be the most efficient predecessor node UINT32 gscore; // The accumulated distance from the start to this node UINT32 hscore; // The heuristic from this node to the goal -} pathfindnode_t; +}; // Contains the final created path after pathfinding is completed -typedef struct path_s { +struct path_t { size_t numnodes; struct pathfindnode_s *array; UINT32 totaldist; -} path_t; +}; // Contains info about the pathfinding used to setup the algorithm // (e.g. the base capacities of the dynamically allocated arrays) // should be setup by the caller before starting pathfinding // base capacities will be 8 if they aren't setup, missing callback functions will cause an error. // Can be accessed after the pathfinding is complete to get the final capacities of them -typedef struct pathfindsetup_s { +struct pathfindsetup_t { size_t opensetcapacity; size_t closedsetcapacity; size_t nodesarraycapacity; @@ -67,7 +67,7 @@ typedef struct pathfindsetup_s { getnodeheuristicfunc getheuristic; getnodetraversablefunc gettraversable; getpathfindfinishedfunc getfinished; -} pathfindsetup_t; +}; /*-------------------------------------------------- diff --git a/src/k_profiles.h b/src/k_profiles.h index 961ac807b..2e65a49fe 100644 --- a/src/k_profiles.h +++ b/src/k_profiles.h @@ -45,7 +45,7 @@ // profile_t definition (WIP) // If you edit, see PR_SaveProfiles and PR_LoadProfiles -typedef struct profile_s +struct profile_t { // Versionning @@ -70,7 +70,7 @@ typedef struct profile_s // Finally, control data itself INT32 controls[num_gamecontrols][MAXINPUTMAPPING]; // Lists of all the controls, defined the same way as default inputs in g_input.c -} profile_t; +}; // Functions diff --git a/src/k_terrain.h b/src/k_terrain.h index 84bdc6ad8..56bf7df34 100644 --- a/src/k_terrain.h +++ b/src/k_terrain.h @@ -22,7 +22,7 @@ #define TERRAIN_NAME_LEN 32 -typedef struct t_splash_s +struct t_splash_t { // Splash definition. // These are particles spawned when hitting the floor. @@ -41,9 +41,9 @@ typedef struct t_splash_s angle_t cone; // Randomized angle of the push-out. UINT8 numParticles; // Number of particles to spawn. -} t_splash_t; +}; -typedef struct t_footstep_s +struct t_footstep_t { // Footstep definition. // These are particles spawned when moving fast enough on a floor. @@ -64,7 +64,7 @@ typedef struct t_footstep_s tic_t sfxFreq; // How frequently to play the sound. tic_t frequency; // How frequently to spawn the particles. fixed_t requiredSpeed; // Speed percentage you need to be at to trigger the particles. -} t_footstep_t; +}; typedef enum { @@ -75,7 +75,7 @@ typedef enum TOV__MAX } t_overlay_action_t; -typedef struct t_overlay_s +struct t_overlay_t { // Overlay definition. // These are sprites displayed on top of the base object. @@ -87,7 +87,7 @@ typedef struct t_overlay_s fixed_t scale; // Thing scale multiplier. UINT16 color; // Colorize effect. SKINCOLOR_NONE has no colorize. fixed_t speed; // Speed-up based on object speed. 0 plays the animation at a constant rate. -} t_overlay_t; +}; typedef enum { @@ -98,7 +98,7 @@ typedef enum TRF_TRIPWIRE = 1<<3 // Texture is a tripwire when used as a midtexture } terrain_flags_t; -typedef struct terrain_s +struct terrain_s { // Terrain definition. // These are all of the properties that the floor gets. @@ -118,9 +118,9 @@ typedef struct terrain_s angle_t speedPadAngle; // Speed pad angle fixed_t floorClip; // Offset for sprites on this ground UINT32 flags; // Flag values (see: terrain_flags_t) -} terrain_t; +}; -typedef struct t_floor_s +struct t_floor_t { // Terrain floor definition. // Ties a texture name to a terrain definition. @@ -128,7 +128,7 @@ typedef struct t_floor_s char textureName[9]; // Floor texture name. UINT32 textureHash; // Floor texture hash. size_t terrainID; // Terrain definition ID. -} t_floor_t; +}; /*-------------------------------------------------- diff --git a/src/k_waypoint.h b/src/k_waypoint.h index 1cb659dbe..9322477e1 100644 --- a/src/k_waypoint.h +++ b/src/k_waypoint.h @@ -20,7 +20,7 @@ #define DEFAULT_WAYPOINT_RADIUS (384) -typedef struct waypoint_s +struct waypoint_s { mobj_t *mobj; boolean onaline; @@ -30,7 +30,7 @@ typedef struct waypoint_s UINT32 *prevwaypointdistances; size_t numnextwaypoints; size_t numprevwaypoints; -} waypoint_t; +}; // AVAILABLE FOR LUA diff --git a/src/lua_hudlib_drawlist.h b/src/lua_hudlib_drawlist.h index 398293602..15249e4f9 100644 --- a/src/lua_hudlib_drawlist.h +++ b/src/lua_hudlib_drawlist.h @@ -24,8 +24,6 @@ extern "C" { #endif -typedef struct huddrawlist_s *huddrawlist_h; - // Create a new drawlist. Returns a handle to it. huddrawlist_h LUA_HUD_CreateDrawList(void); // Clears the draw list. diff --git a/src/m_aatree.c b/src/m_aatree.c index c0bb739f8..506887776 100644 --- a/src/m_aatree.c +++ b/src/m_aatree.c @@ -27,7 +27,7 @@ typedef struct aatree_node_s struct aatree_node_s *left, *right; } aatree_node_t; -struct aatree_s +struct aatree_t { aatree_node_t *root; UINT32 flags; diff --git a/src/m_aatree.h b/src/m_aatree.h index b784eb17a..77bfd05fb 100644 --- a/src/m_aatree.h +++ b/src/m_aatree.h @@ -19,7 +19,6 @@ // Flags for AA trees. #define AATREE_ZUSER 1 // Treat values as z_zone-allocated blocks and set their user fields -typedef struct aatree_s aatree_t; typedef void (*aatree_iter_t)(INT32 key, void *value); aatree_t *M_AATreeAlloc(UINT32 flags); diff --git a/src/m_cond.h b/src/m_cond.h index 323c84347..c340fbef1 100644 --- a/src/m_cond.h +++ b/src/m_cond.h @@ -37,7 +37,7 @@ typedef enum } conditiontype_t; // Condition Set information -typedef struct +struct condition_t { UINT32 id; /// <- The ID of this condition. /// In an unlock condition, all conditions with the same ID @@ -47,14 +47,14 @@ typedef struct INT32 requirement; /// <- The requirement for this variable. INT16 extrainfo1; /// <- Extra information for the condition when needed. INT16 extrainfo2; /// <- Extra information for the condition when needed. -} condition_t; -typedef struct +}; +struct conditionset_t { UINT32 numconditions; /// <- number of conditions. condition_t *condition; /// <- All conditionals to be checked. UINT8 achieved; /// <- Whether this conditional has been achieved already or not. /// (Conditional checking is skipped if true -- it's assumed you can't relock an unlockable) -} conditionset_t; +}; // Emblem information #define ET_GLOBAL 0 // Emblem with a position in space @@ -69,7 +69,7 @@ typedef struct // Map emblem flags #define ME_ENCORE 1 -typedef struct +struct emblem_t { UINT8 type; ///< Emblem type INT16 tag; ///< Tag of emblem mapthing @@ -79,8 +79,8 @@ typedef struct INT32 var; ///< If needed, specifies information on the target amount to achieve (or target skin) char hint[110]; ///< Hint for emblem hints menu UINT8 collected; ///< Do you have this emblem? -} emblem_t; -typedef struct +}; +struct extraemblem_t { char name[20]; ///< Name of the goal (used in the "emblem awarded" cecho) char description[40]; ///< Description of goal (used in statistics) @@ -89,10 +89,10 @@ typedef struct UINT8 sprite; ///< emblem sprite to use, 0 - 25 UINT16 color; ///< skincolor to use UINT8 collected; ///< Do you have this emblem? -} extraemblem_t; +}; // Unlockable information -typedef struct +struct unlockable_t { char name[64]; char objective[64]; @@ -103,7 +103,7 @@ typedef struct UINT8 nocecho; UINT8 nochecklist; UINT8 unlocked; -} unlockable_t; +}; #define SECRET_NONE 0 // Does nil. Use with levels locked by UnlockRequired #define SECRET_HEADER 1 // Does nothing on its own, just serves as a header for the menu diff --git a/src/m_dllist.h b/src/m_dllist.h index 680c2cd80..9b9cfca81 100644 --- a/src/m_dllist.h +++ b/src/m_dllist.h @@ -29,11 +29,11 @@ #pragma warning(disable : 4706) #endif -typedef struct mdllistitem_s +struct mdllistitem_s { struct mdllistitem_s *next; struct mdllistitem_s **prev; -} mdllistitem_t; +}; FUNCINLINE static ATTRINLINE void M_DLListInsert(mdllistitem_t *item, mdllistitem_t **head) { diff --git a/src/m_fixed.h b/src/m_fixed.h index fd8e79b94..b605434fb 100644 --- a/src/m_fixed.h +++ b/src/m_fixed.h @@ -333,11 +333,11 @@ FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FixedRound(fixed_t x) return INT32_MAX; } -typedef struct +struct vector2_t { fixed_t x; fixed_t y; -} vector2_t; +}; vector2_t *FV2_Load(vector2_t *vec, fixed_t x, fixed_t y); vector2_t *FV2_UnLoad(vector2_t *vec, fixed_t *x, fixed_t *y); @@ -361,10 +361,10 @@ boolean FV2_Equal(const vector2_t *a_1, const vector2_t *a_2); fixed_t FV2_Dot(const vector2_t *a_1, const vector2_t *a_2); vector2_t *FV2_Point2Vec (const vector2_t *point1, const vector2_t *point2, vector2_t *a_o); -typedef struct +struct vector3_t { fixed_t x, y, z; -} vector3_t; +}; vector3_t *FV3_Load(vector3_t *vec, fixed_t x, fixed_t y, fixed_t z); vector3_t *FV3_UnLoad(vector3_t *vec, fixed_t *x, fixed_t *y, fixed_t *z); @@ -401,10 +401,10 @@ vector3_t *FV3_IntersectionPoint(const vector3_t *vNormal, const vector3_t *vLin UINT8 FV3_PointOnLineSide(const vector3_t *point, const vector3_t *line); boolean FV3_PointInsideBox(const vector3_t *point, const vector3_t *box); -typedef struct +struct matrix_t { fixed_t m[16]; -} matrix_t; +}; void FM_LoadIdentity(matrix_t* matrix); void FM_CreateObjectMatrix(matrix_t *matrix, fixed_t x, fixed_t y, fixed_t z, fixed_t anglex, fixed_t angley, fixed_t anglez, fixed_t upx, fixed_t upy, fixed_t upz, fixed_t radius); diff --git a/src/m_perfstats.h b/src/m_perfstats.h index 2c448031c..f0a186bf3 100644 --- a/src/m_perfstats.h +++ b/src/m_perfstats.h @@ -38,22 +38,22 @@ extern int ps_checkposition_calls; extern precise_t ps_lua_thinkframe_time; extern int ps_lua_mobjhooks; -typedef struct +struct ps_hookinfo_t { precise_t time_taken; char short_src[LUA_IDSIZE]; -} ps_hookinfo_t; +}; void PS_SetThinkFrameHookInfo(int index, precise_t time_taken, char* short_src); -typedef struct +struct ps_botinfo_t { boolean isBot; precise_t total; precise_t prediction; // K_CreateBotPrediction precise_t nudge; // K_NudgePredictionTowardsObjects precise_t item; // K_BotItemUsage -} ps_botinfo_t; +}; extern ps_botinfo_t ps_bots[MAXPLAYERS]; diff --git a/src/m_queue.h b/src/m_queue.h index 3e9579e11..6ba8e335c 100644 --- a/src/m_queue.h +++ b/src/m_queue.h @@ -13,17 +13,17 @@ #ifndef M_QUEUE_H #define M_QUEUE_H -typedef struct mqueueitem_s +struct mqueueitem_s { struct mqueueitem_s *next; -} mqueueitem_t; +}; -typedef struct mqueue_s +struct mqueue_t { mqueueitem_t head; mqueueitem_t *tail; mqueueitem_t *rover; -} mqueue_t; +}; void M_QueueInit(mqueue_t *queue); void M_QueueInsert(mqueueitem_t *item, mqueue_t *queue); diff --git a/src/mserv.h b/src/mserv.h index eb1152876..b47bf2c25 100644 --- a/src/mserv.h +++ b/src/mserv.h @@ -27,16 +27,16 @@ typedef union } ATTRPACK msg_header_t; // Keep this structure 8 bytes aligned (current size is 80) -typedef struct +struct msg_server_t { msg_header_t header; char ip[16]; char port[8]; char contact[32]; char version[8]; // format is: x.yy.z (like 1.30.2 or 1.31) -} ATTRPACK msg_server_t; +} ATTRPACK; -typedef struct +struct msg_ban_t { msg_header_t header; char ipstart[16]; @@ -44,7 +44,7 @@ typedef struct char endstamp[32]; char reason[255]; INT32 hostonly; -} ATTRPACK msg_ban_t; +} ATTRPACK; #if defined(_MSC_VER) #pragma pack() diff --git a/src/p_local.h b/src/p_local.h index 9bc92cb64..70e26f9d9 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -80,7 +80,7 @@ void P_RemoveThinker(thinker_t *thinker); // // P_USER // -typedef struct camera_s +struct camera_t { boolean chase; angle_t aiming; @@ -119,7 +119,7 @@ typedef struct camera_s // Interpolation data fixed_t old_x, old_y, old_z; angle_t old_angle, old_aiming; -} camera_t; +}; // demo freecam or something before i commit die struct demofreecam_s { @@ -246,11 +246,11 @@ typedef enum NUMJINGLES } jingletype_t; -typedef struct +struct jingle_t { char musname[7]; boolean looping; -} jingle_t; +}; extern jingle_t jingleinfo[NUMJINGLES]; @@ -381,7 +381,7 @@ void P_InternalFlickyHop(mobj_t *actor, fixed_t momz, fixed_t momh, angle_t angl // P_MAP // -typedef struct tm_s +struct tm_t { mobj_t *thing; fixed_t x, y; @@ -411,7 +411,7 @@ typedef struct tm_s // set by PIT_CheckLine() for any line that stopped the PIT_CheckLine() // that is, for any line which is 'solid' line_t *blockingline; -} tm_t; +}; extern tm_t tm; @@ -431,12 +431,12 @@ void P_UnsetThingPosition(mobj_t *thing); void P_SetThingPosition(mobj_t *thing); void P_SetUnderlayPosition(mobj_t *thing); -typedef struct TryMoveResult_s +struct TryMoveResult_t { boolean success; line_t *line; mobj_t *mo; -} TryMoveResult_t; +}; boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y, TryMoveResult_t *result); boolean P_CheckMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff, TryMoveResult_t *result); @@ -496,7 +496,7 @@ extern mobj_t **blocklinks; // for thing chains // // P_INTER // -typedef struct BasicFF_s +struct BasicFF_t { INT32 ForceX; ///< The X of the Force's Vel INT32 ForceY; ///< The Y of the Force's Vel @@ -506,7 +506,7 @@ typedef struct BasicFF_s INT32 Gain; ///< /The gain to be applied to the effect, in the range from 0 through 10,000. //All, CONSTANTFORCE �10,000 to 10,000 INT32 Magnitude; ///< Magnitude of the effect, in the range from 0 through 10,000. -} BasicFF_t; +}; /* Damage/death types, for P_DamageMobj and related */ //// Damage types diff --git a/src/p_maputl.h b/src/p_maputl.h index b53bddfd1..15e2abbf4 100644 --- a/src/p_maputl.h +++ b/src/p_maputl.h @@ -20,12 +20,12 @@ // // P_MAPUTL // -typedef struct +struct divline_t { fixed_t x, y, dx, dy; -} divline_t; +}; -typedef struct +struct intercept_t { fixed_t frac; // along trace line boolean isaline; @@ -34,7 +34,7 @@ typedef struct mobj_t *thing; line_t *line; } d; -} intercept_t; +}; typedef boolean (*traverser_t)(intercept_t *in); diff --git a/src/p_mobj.h b/src/p_mobj.h index b725f2bf0..50686eac9 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -270,7 +270,7 @@ typedef enum { } precipflag_t; // Map Object definition. -typedef struct mobj_s +struct mobj_s { // List: thinker links. thinker_t thinker; @@ -414,7 +414,7 @@ typedef struct mobj_s INT32 dispoffset; // WARNING: New fields must be added separately to savegame and Lua. -} mobj_t; +}; // // For precipitation @@ -423,7 +423,7 @@ typedef struct mobj_s // so please keep the start of the // structure the same. // -typedef struct precipmobj_s +struct precipmobj_s { // List: thinker links. thinker_t thinker; @@ -480,15 +480,15 @@ typedef struct precipmobj_s INT32 tics; // state tic counter state_t *state; UINT32 flags; // flags from mobjinfo tables -} precipmobj_t; +}; -typedef struct actioncache_s +struct actioncache_s { struct actioncache_s *next; struct actioncache_s *prev; struct mobj_s *mobj; INT32 statenum; -} actioncache_t; +}; extern actioncache_t actioncachehead; diff --git a/src/p_polyobj.h b/src/p_polyobj.h index 91333a107..9cb94126b 100644 --- a/src/p_polyobj.h +++ b/src/p_polyobj.h @@ -66,7 +66,7 @@ typedef enum // Polyobject Structure // -typedef struct polyobj_s +struct polyobj_s { mdllistitem_t link; // for subsector links; must be first @@ -114,23 +114,23 @@ typedef struct polyobj_s // these are saved for netgames, so do not let Lua touch these! INT32 spawnflags; // Flags the polyobject originally spawned with INT32 spawntrans; // Translucency the polyobject originally spawned with -} polyobj_t; +}; // // Polyobject Blockmap Link Structure // -typedef struct polymaplink_s +struct polymaplink_t { mdllistitem_t link; // for blockmap links polyobj_t *po; // pointer to polyobject -} polymaplink_t; +}; // // Polyobject Special Thinkers // -typedef struct polyrotate_s +struct polyrotate_t { thinker_t thinker; // must be first @@ -138,9 +138,9 @@ typedef struct polyrotate_s INT32 speed; // speed of movement per frame INT32 distance; // distance to move UINT8 turnobjs; // turn objects? PTF_ flags -} polyrotate_t; +}; -typedef struct polymove_s +struct polymove_t { thinker_t thinker; // must be first @@ -150,7 +150,7 @@ typedef struct polymove_s fixed_t momy; // y component of speed along angle INT32 distance; // total distance to move UINT32 angle; // angle along which to move -} polymove_t; +}; // PolyObject waypoint movement return behavior typedef enum @@ -160,7 +160,7 @@ typedef enum PWR_COMEBACK, // Repeat sequence in reverse } polywaypointreturn_e; -typedef struct polywaypoint_s +struct polywaypoint_t { thinker_t thinker; // must be first @@ -172,9 +172,9 @@ typedef struct polywaypoint_s UINT8 returnbehavior; // behavior after reaching the last waypoint UINT8 continuous; // continuously move - used with PWR_WRAP or PWR_COMEBACK UINT8 stophere; // Will stop after it reaches the next waypoint -} polywaypoint_t; +}; -typedef struct polyslidedoor_s +struct polyslidedoor_t { thinker_t thinker; // must be first @@ -191,9 +191,9 @@ typedef struct polyslidedoor_s fixed_t momx; // x component of speed along angle fixed_t momy; // y component of speed along angle UINT8 closing; // if true, is closing -} polyslidedoor_t; +}; -typedef struct polyswingdoor_s +struct polyswingdoor_t { thinker_t thinker; // must be first @@ -205,9 +205,9 @@ typedef struct polyswingdoor_s INT32 initDistance; // initial distance to travel INT32 distance; // current distance to travel UINT8 closing; // if true, is closing -} polyswingdoor_t; +}; -typedef struct polydisplace_s +struct polydisplace_t { thinker_t thinker; // must be first @@ -216,9 +216,9 @@ typedef struct polydisplace_s fixed_t dx; fixed_t dy; fixed_t oldHeights; -} polydisplace_t; +}; -typedef struct polyrotdisplace_s +struct polyrotdisplace_t { thinker_t thinker; // must be first @@ -227,9 +227,9 @@ typedef struct polyrotdisplace_s fixed_t rotscale; UINT8 turnobjs; fixed_t oldHeights; -} polyrotdisplace_t; +}; -typedef struct polyfade_s +struct polyfade_t { thinker_t thinker; // must be first @@ -241,7 +241,7 @@ typedef struct polyfade_s boolean ticbased; INT32 duration; INT32 timer; -} polyfade_t; +}; // // Line Activation Data Structures @@ -261,23 +261,23 @@ typedef enum PTF_OTHERS = 1<<1, // Turn other mobjs with movement } polyturnflags_e; -typedef struct polyrotdata_s +struct polyrotdata_t { INT32 polyObjNum; // numeric id of polyobject to affect INT32 direction; // direction of rotation INT32 speed; // angular speed INT32 distance; // distance to move UINT8 flags; // TMPR_ flags -} polyrotdata_t; +}; -typedef struct polymovedata_s +struct polymovedata_t { INT32 polyObjNum; // numeric id of polyobject to affect fixed_t distance; // distance to move fixed_t speed; // linear speed angle_t angle; // angle of movement UINT8 overRide; // if true, will override any action on the object -} polymovedata_t; +}; typedef enum { @@ -285,14 +285,14 @@ typedef enum PWF_LOOP = 1<<1, // Loop movement (used with PWR_WRAP or PWR_COMEBACK) } polywaypointflags_e; -typedef struct polywaypointdata_s +struct polywaypointdata_t { INT32 polyObjNum; // numeric id of polyobject to affect INT32 sequence; // waypoint sequence # fixed_t speed; // linear speed UINT8 returnbehavior; // behavior after reaching the last waypoint UINT8 flags; // PWF_ flags -} polywaypointdata_t; +}; typedef enum { @@ -315,7 +315,7 @@ typedef enum POLY_DOOR_SWING, } polydoor_e; -typedef struct polydoordata_s +struct polydoordata_t { INT32 polyObjNum; // numeric id of polyobject to affect INT32 doorType; // polyobj door type @@ -323,31 +323,31 @@ typedef struct polydoordata_s angle_t angle; // for slide door only, angle of motion INT32 distance; // distance to move INT32 delay; // delay time after opening -} polydoordata_t; +}; -typedef struct polydisplacedata_s +struct polydisplacedata_t { INT32 polyObjNum; struct sector_s *controlSector; fixed_t dx; fixed_t dy; -} polydisplacedata_t; +}; -typedef struct polyrotdisplacedata_s +struct polyrotdisplacedata_t { INT32 polyObjNum; struct sector_s *controlSector; fixed_t rotscale; UINT8 turnobjs; -} polyrotdisplacedata_t; +}; -typedef struct polyflagdata_s +struct polyflagdata_t { INT32 polyObjNum; INT32 speed; UINT32 angle; fixed_t momx; -} polyflagdata_t; +}; typedef enum { @@ -358,7 +358,7 @@ typedef enum TMPF_GHOSTFADE = 1<<4, } textmappolyfade_t; -typedef struct polyfadedata_s +struct polyfadedata_t { INT32 polyObjNum; INT32 destvalue; @@ -366,7 +366,7 @@ typedef struct polyfadedata_s boolean doghostfade; boolean ticbased; INT32 speed; -} polyfadedata_t; +}; // // Functions diff --git a/src/p_saveg.h b/src/p_saveg.h index 27865bf50..b7ca6527f 100644 --- a/src/p_saveg.h +++ b/src/p_saveg.h @@ -28,14 +28,14 @@ boolean P_LoadNetGame(boolean reloading); mobj_t *P_FindNewPosition(UINT32 oldposition); -typedef struct +struct savedata_t { UINT8 skin; INT32 score; INT32 lives; UINT16 emeralds; UINT8 numgameovers; -} savedata_t; +}; extern savedata_t savedata; extern UINT8 *save_p; diff --git a/src/p_setup.h b/src/p_setup.h index 04a3233e0..9284a2b0d 100644 --- a/src/p_setup.h +++ b/src/p_setup.h @@ -45,7 +45,7 @@ enum // // MAP used flats lookup table // -typedef struct +struct levelflat_t { char name[9]; // resource name from wad @@ -85,7 +85,7 @@ typedef struct void *mipmap; void *mippic; #endif -} levelflat_t; +}; extern size_t numlevelflats; extern levelflat_t *levelflats; diff --git a/src/p_slopes.h b/src/p_slopes.h index 5543b785f..454dd344f 100644 --- a/src/p_slopes.h +++ b/src/p_slopes.h @@ -117,16 +117,16 @@ typedef enum { } dynplanetype_t; /// Permit slopes to be dynamically altered through a thinker. -typedef struct +struct dynlineplanethink_t { thinker_t thinker; pslope_t *slope; dynplanetype_t type; line_t *sourceline; fixed_t extent; -} dynlineplanethink_t; +}; -typedef struct +struct dynvertexplanethink_t { thinker_t thinker; pslope_t *slope; @@ -135,7 +135,7 @@ typedef struct fixed_t origsecheights[3]; fixed_t origvecheights[3]; UINT8 relative; -} dynvertexplanethink_t; +}; void T_DynamicSlopeLine (dynlineplanethink_t* th); void T_DynamicSlopeVert (dynvertexplanethink_t* th); diff --git a/src/p_spec.h b/src/p_spec.h index 91bc74150..6bfbc535a 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -578,17 +578,17 @@ UINT16 P_GetFFloorID(ffloor_t *fflr); ffloor_t *P_GetFFloorByID(sector_t *sec, UINT16 id); // Use this when you don't know the type of your thinker data struct but need to access its thinker. -typedef struct +struct thinkerdata_t { thinker_t thinker; -} thinkerdata_t; +}; // // P_LIGHTS // /** Fire flicker action structure. */ -typedef struct +struct fireflicker_t { thinker_t thinker; ///< The thinker in use for the effect. sector_t *sector; ///< The sector where action is taking place. @@ -596,29 +596,29 @@ typedef struct INT32 resetcount; INT16 maxlight; ///< The brightest light level to use. INT16 minlight; ///< The darkest light level to use. -} fireflicker_t; +}; -typedef struct +struct lightflash_t { thinker_t thinker; sector_t *sector; INT32 maxlight; INT32 minlight; -} lightflash_t; +}; /** Laser block thinker. */ -typedef struct +struct laserthink_t { thinker_t thinker; ///< Thinker structure for laser. INT16 tag; line_t *sourceline; UINT8 nobosses; -} laserthink_t; +}; /** Strobe light action structure.. */ -typedef struct +struct strobe_t { thinker_t thinker; ///< The thinker in use for the effect. sector_t *sector; ///< The sector where the action is taking place. @@ -627,9 +627,9 @@ typedef struct INT16 maxlight; ///< The maximum light level to use. INT32 darktime; ///< How INT32 to use minlight. INT32 brighttime; ///< How INT32 to use maxlight. -} strobe_t; +}; -typedef struct +struct glow_t { thinker_t thinker; sector_t *sector; @@ -637,11 +637,11 @@ typedef struct INT16 maxlight; INT16 direction; INT16 speed; -} glow_t; +}; /** Thinker struct for fading lights. */ -typedef struct +struct lightlevel_t { thinker_t thinker; ///< Thinker in use for the effect. sector_t *sector; ///< Sector where action is taking place. @@ -652,7 +652,7 @@ typedef struct fixed_t fixedpertic; ///< Fixed point for increment per tic. // The reason for those two above to be fixed point is to deal with decimal values that would otherwise get trimmed away. INT32 timer; ///< Internal timer. -} lightlevel_t; +}; #define GLOWSPEED 8 #define STROBEBRIGHT 5 @@ -709,7 +709,7 @@ typedef enum /** Ceiling movement structure. */ -typedef struct +struct ceiling_t { thinker_t thinker; ///< Thinker for the type of movement. ceiling_e type; ///< Type of movement. @@ -728,7 +728,7 @@ typedef struct INT16 tag; ///< Tag of linedef executor to run when movement is done. fixed_t origspeed; ///< The original, "real" speed. INT32 sourceline; ///< Index of the source linedef -} ceiling_t; +}; #define CEILSPEED (FRACUNIT) @@ -771,7 +771,7 @@ typedef enum bridgeFall, } elevator_e; -typedef struct +struct floormove_t { thinker_t thinker; floor_e type; @@ -786,9 +786,9 @@ typedef struct fixed_t delaytimer; INT16 tag; INT32 sourceline; -} floormove_t; +}; -typedef struct +struct elevator_t { thinker_t thinker; elevator_e type; @@ -807,7 +807,7 @@ typedef struct fixed_t floorwasheight; // Height the floor WAS at fixed_t ceilingwasheight; // Height the ceiling WAS at line_t *sourceline; -} elevator_t; +}; typedef enum { @@ -816,7 +816,7 @@ typedef enum CF_REVERSE = 1<<2, // Reverse gravity } crumbleflag_t; -typedef struct +struct crumble_t { thinker_t thinker; line_t *sourceline; @@ -830,15 +830,15 @@ typedef struct fixed_t floorwasheight; // Height the floor WAS at fixed_t ceilingwasheight; // Height the ceiling WAS at UINT8 flags; -} crumble_t; +}; -typedef struct +struct noenemies_t { thinker_t thinker; line_t *sourceline; // Source line of the thinker -} noenemies_t; +}; -typedef struct +struct continuousfall_t { thinker_t thinker; sector_t *sector; @@ -847,9 +847,9 @@ typedef struct fixed_t floorstartheight; fixed_t ceilingstartheight; fixed_t destheight; -} continuousfall_t; +}; -typedef struct +struct bouncecheese_t { thinker_t thinker; line_t *sourceline; @@ -859,9 +859,9 @@ typedef struct fixed_t floorwasheight; fixed_t ceilingwasheight; boolean low; -} bouncecheese_t; +}; -typedef struct +struct mariothink_t { thinker_t thinker; sector_t *sector; @@ -870,16 +870,16 @@ typedef struct fixed_t floorstartheight; fixed_t ceilingstartheight; INT16 tag; -} mariothink_t; +}; -typedef struct +struct mariocheck_t { thinker_t thinker; line_t *sourceline; sector_t *sector; -} mariocheck_t; +}; -typedef struct +struct thwomp_t { thinker_t thinker; line_t *sourceline; @@ -893,23 +893,23 @@ typedef struct INT16 tag; UINT16 sound; INT32 initDelay; -} thwomp_t; +}; -typedef struct +struct floatthink_t { thinker_t thinker; line_t *sourceline; sector_t *sector; INT16 tag; -} floatthink_t; +}; -typedef struct +struct eachtime_t { thinker_t thinker; line_t *sourceline; // Source line of the thinker boolean playersInArea[MAXPLAYERS]; boolean triggerOnExit; -} eachtime_t; +}; typedef enum { @@ -918,7 +918,7 @@ typedef enum RF_DYNAMIC = 1<<2, //Dynamically sinking platform } raiseflag_t; -typedef struct +struct raise_t { thinker_t thinker; INT16 tag; @@ -929,7 +929,7 @@ typedef struct fixed_t extraspeed; //For dynamically sinking platform UINT8 shaketimer; //For dynamically sinking platform UINT8 flags; -} raise_t; +}; #define ELEVATORSPEED (FRACUNIT*4) #define FLOORSPEED (FRACUNIT) @@ -971,20 +971,20 @@ void T_EachTimeThinker(eachtime_t *eachtime); void T_CameraScanner(elevator_t *elevator); void T_RaiseSector(raise_t *raise); -typedef struct +struct executor_t { thinker_t thinker; // Thinker for linedef executor delay line_t *line; // Pointer to line that is waiting. mobj_t *caller; // Pointer to calling mobj sector_t *sector; // Pointer to triggering sector INT32 timer; // Delay timer -} executor_t; +}; void T_ExecutorDelay(executor_t *e); /** Generalized scroller. */ -typedef struct +struct scroll_t { thinker_t thinker; ///< Thinker structure for scrolling. fixed_t dx, dy; ///< (dx,dy) scroll speeds. @@ -1004,14 +1004,14 @@ typedef struct sc_carry, ///< Carry objects on floor. sc_carry_ceiling,///< Carry objects on ceiling (for 3Dfloor conveyors). } type; -} scroll_t; +}; void T_Scroll(scroll_t *s); void T_LaserFlash(laserthink_t *flash); /** Friction for ice/sludge effects. */ -typedef struct +struct friction_t { thinker_t thinker; ///< Thinker structure for friction. INT32 friction; ///< Friction value, 0xe800 = normal. @@ -1019,7 +1019,7 @@ typedef struct INT32 affectee; ///< Number of affected sector. INT32 referrer; ///< If roverfriction == true, then this will contain the sector # of the control sector where the effect was applied. UINT8 roverfriction; ///< flag for whether friction originated from a FOF or not -} friction_t; +}; // Friction defines. #define ORIG_FRICTION (0xF5 << (FRACBITS-8)) ///< Original value. @@ -1033,7 +1033,7 @@ typedef enum } pushertype_e; // Model for pushers for push/pull effects -typedef struct +struct pusher_t { thinker_t thinker; ///< Thinker structure for pusher effect. pushertype_e type; ///< Type of pusher effect. @@ -1045,10 +1045,10 @@ typedef struct INT32 referrer; ///< If roverpusher == true, then this will contain the sector # of the control sector where the effect was applied. INT32 exclusive; /// < Once this affect has been applied to a mobj, no other pushers may affect it. INT32 slider; /// < Should the player go into an uncontrollable slide? -} pusher_t; +}; // Model for disappearing/reappearing FOFs -typedef struct +struct disappear_t { thinker_t thinker; ///< Thinker structure for effect. tic_t appeartime; ///< Tics to be appeared for @@ -1058,12 +1058,12 @@ typedef struct INT32 affectee; ///< Number of affected line INT32 sourceline; ///< Number of source line INT32 exists; ///< Exists toggle -} disappear_t; +}; void T_Disappear(disappear_t *d); // Model for fading FOFs -typedef struct +struct fade_t { thinker_t thinker; ///< Thinker structure for effect. ffloor_t *rover; ///< Target ffloor @@ -1084,13 +1084,13 @@ typedef struct boolean docollision; ///< Handle interactive flags boolean doghostfade; ///< No interactive flags during fading boolean exactalpha; ///< Use exact alpha values (opengl) -} fade_t; +}; void T_Fade(fade_t *d); // Model for fading colormaps -typedef struct +struct fadecolormap_t { thinker_t thinker; ///< Thinker structure for effect. sector_t *sector; ///< Sector where action is taking place. @@ -1099,7 +1099,7 @@ typedef struct boolean ticbased; ///< Tic-based timing INT32 duration; ///< Total duration for tic-based logic (OR: speed increment) INT32 timer; ///< Timer for tic-based logic (OR: internal speed counter) -} fadecolormap_t; +}; void T_FadeColormap(fadecolormap_t *d); @@ -1107,7 +1107,7 @@ void T_FadeColormap(fadecolormap_t *d); void T_Pusher(pusher_t *p); // Plane displacement -typedef struct +struct planedisplace_t { thinker_t thinker; ///< Thinker structure for plane displacement effect. INT32 affectee; ///< Number of affected sector. @@ -1123,7 +1123,7 @@ typedef struct pd_ceiling, ///< Displace ceiling. pd_both, ///< Displace both floor AND ceiling. } type; -} planedisplace_t; +}; void T_PlaneDisplace(planedisplace_t *pd); diff --git a/src/r_data.h b/src/r_data.h index da3f81163..5ba30010c 100644 --- a/src/r_data.h +++ b/src/r_data.h @@ -23,12 +23,12 @@ #endif // Store lists of lumps for F_START/F_END etc. -typedef struct +struct lumplist_t { UINT16 wadfile; UINT16 firstlump; size_t numlumps; -} lumplist_t; +}; UINT32 ASTBlendPixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alpha); UINT32 ASTBlendTexturePixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alpha); diff --git a/src/r_defs.h b/src/r_defs.h index a0c557e94..1d3fa65d8 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -35,11 +35,11 @@ // Clips the given range of columns // and includes it in the new clip list. // -typedef struct +struct cliprange_t { INT32 first; INT32 last; -} cliprange_t; +}; // Silhouette, needed for clipping segs (mainly) and sprites representing things. #define SIL_NONE 0 @@ -57,7 +57,7 @@ typedef UINT8 lighttable_t; #define CMF_FOG 4 // ExtraColormap type. Use for extra_colormaps from now on. -typedef struct extracolormap_s +struct extracolormap_s { UINT8 fadestart, fadeend; UINT8 flags; @@ -76,7 +76,7 @@ typedef struct extracolormap_s struct extracolormap_s *next; struct extracolormap_s *prev; -} extracolormap_t; +}; // // INTERNAL MAP TYPES used by play and refresh @@ -84,12 +84,12 @@ typedef struct extracolormap_s /** Your plain vanilla vertex. */ -typedef struct +struct vertex_t { fixed_t x, y; boolean floorzset, ceilingzset; fixed_t floorz, ceilingz; -} vertex_t; +}; // Forward of linedefs, for sectors. struct line_s; @@ -99,13 +99,13 @@ struct line_s; * handle sound from moving objects (doppler), because position is probably * just buffered, not updated. */ -typedef struct +struct degenmobj_t { thinker_t thinker; ///< Not used for anything. fixed_t x; ///< X coordinate. fixed_t y; ///< Y coordinate. fixed_t z; ///< Z coordinate. -} degenmobj_t; +}; #include "p_polyobj.h" @@ -208,7 +208,7 @@ typedef enum BT_STRONG, } busttype_e; -typedef struct ffloor_s +struct ffloor_s { fixed_t *topheight; INT32 *toppic; @@ -258,13 +258,13 @@ typedef struct ffloor_s INT32 spawnalpha; // alpha the 3D floor spawned with void *fadingdata; // fading FOF thinker -} ffloor_t; +}; // This struct holds information for shadows casted by 3D floors. // This information is contained inside the sector_t and is used as the base // information for casted shadows. -typedef struct lightlist_s +struct lightlist_t { fixed_t height; INT16 *lightlevel; @@ -272,11 +272,11 @@ typedef struct lightlist_s INT32 flags; ffloor_t *caster; struct pslope_s *slope; // FOF_DOUBLESHADOW makes me have to store this pointer here. Bluh bluh. -} lightlist_t; +}; // This struct is used for rendering walls with shadows casted on them... -typedef struct r_lightlist_s +struct r_lightlist_s { fixed_t height; fixed_t heightstep; @@ -288,7 +288,7 @@ typedef struct r_lightlist_s lighttable_t *rcolormap; ffloortype_e flags; INT32 lightnum; -} r_lightlist_t; +}; // Slopes typedef enum { @@ -296,7 +296,7 @@ typedef enum { SL_DYNAMIC = 1<<1, /// This plane slope will be assigned a thinker to make it dynamic. } slopeflags_t; -typedef struct pslope_s +struct pslope_s { UINT16 id; // The number of the slope, mostly used for netgame syncing purposes struct pslope_s *next; // Make a linked list of dynamic slopes, for easy reference later @@ -323,7 +323,7 @@ typedef struct pslope_s #ifdef HWRENDER INT16 hwLightOffset; #endif -} pslope_t; +}; typedef enum { @@ -399,7 +399,7 @@ typedef enum // The SECTORS record, at runtime. // Stores things/mobjs. // -typedef struct sector_s +struct sector_s { fixed_t floorheight; fixed_t ceilingheight; @@ -499,7 +499,7 @@ typedef struct sector_s // colormap structure extracolormap_t *spawn_extra_colormap; -} sector_t; +}; // // Move clipping aid for linedefs. @@ -517,7 +517,7 @@ typedef enum #define NUMLINEARGS 10 #define NUMLINESTRINGARGS 2 -typedef struct line_s +struct line_s { // Vertices, from v1 to v2. vertex_t *v1; @@ -556,9 +556,9 @@ typedef struct line_s char *text; // a concatenation of all front and back texture names, for linedef specials that require a string. INT16 callcount; // no. of calls left before triggering, for the "X calls" linedef specials, defaults to 0 -} line_t; +}; -typedef struct +struct side_t { // add this to the calculated texture column fixed_t textureoffset; @@ -582,7 +582,7 @@ typedef struct char *text; // a concatenation of all top, bottom, and mid texture names, for linedef specials that require a string. extracolormap_t *colormap_data; // storage for colormaps; not applied to sectors. -} side_t; +}; // // A subsector. @@ -590,14 +590,14 @@ typedef struct // Basically, this is a list of linesegs, indicating the visible walls that define // (all or some) sides of a convex BSP leaf. // -typedef struct subsector_s +struct subsector_s { sector_t *sector; INT16 numlines; UINT16 firstline; struct polyobj_s *polyList; // haleyjd 02/19/06: list of polyobjects size_t validcount; -} subsector_t; +}; // Sector list node showing all sectors an object appears in. // @@ -613,7 +613,7 @@ typedef struct subsector_s // // For the links, NULL means top or end of list. -typedef struct msecnode_s +struct msecnode_s { sector_t *m_sector; // a sector containing this object struct mobj_s *m_thing; // this object @@ -622,9 +622,9 @@ typedef struct msecnode_s struct msecnode_s *m_thinglist_prev; // prev msecnode_t for this sector struct msecnode_s *m_thinglist_next; // next msecnode_t for this sector boolean visited; // used in search algorithms -} msecnode_t; +}; -typedef struct mprecipsecnode_s +struct mprecipsecnode_s { sector_t *m_sector; // a sector containing this object struct precipmobj_s *m_thing; // this object @@ -633,12 +633,12 @@ typedef struct mprecipsecnode_s struct mprecipsecnode_s *m_thinglist_prev; // prev msecnode_t for this sector struct mprecipsecnode_s *m_thinglist_next; // next msecnode_t for this sector boolean visited; // used in search algorithms -} mprecipsecnode_t; +}; // for now, only used in hardware mode // maybe later for software as well? // that's why it's moved here -typedef struct light_s +struct light_t { UINT16 type; // light,... (cfr #define in hwr_light.c) @@ -651,19 +651,19 @@ typedef struct light_s UINT32 dynamic_color; // color of the light for dynamic lighting float dynamic_radius; // radius of the light ball float dynamic_sqrradius; // radius^2 of the light ball -} light_t; +}; -typedef struct lightmap_s +struct lightmap_s { float s[2], t[2]; light_t *light; struct lightmap_s *next; -} lightmap_t; +}; // // The lineseg. // -typedef struct seg_s +struct seg_s { vertex_t *v1; vertex_t *v2; @@ -704,7 +704,7 @@ typedef struct seg_s #ifdef HWRENDER INT16 hwLightOffset; #endif -} seg_t; +}; // // BSP node. @@ -727,11 +727,11 @@ typedef struct #endif // posts are runs of non masked source pixels -typedef struct +struct post_t { UINT8 topdelta; // -1 is the last post in a column UINT8 length; // length data bytes follows -} ATTRPACK post_t; +} ATTRPACK; #if defined(_MSC_VER) #pragma pack() @@ -751,7 +751,7 @@ typedef post_t column_t; // // ? // -typedef struct drawseg_s +struct drawseg_t { seg_t *curline; INT32 x1; @@ -783,7 +783,7 @@ typedef struct drawseg_s fixed_t maskedtextureheight[MAXVIDWIDTH]; // For handling sloped midtextures vertex_t leftpos, rightpos; // Used for rendering FOF walls with slopes -} drawseg_t; +}; typedef enum { @@ -795,11 +795,11 @@ typedef enum } pic_mode_t; #ifdef ROTSPRITE -typedef struct +struct rotsprite_t { INT32 angles; void **patches; -} rotsprite_t; +}; #endif // Patches. @@ -807,7 +807,7 @@ typedef struct // Patches are used for sprites and all masked pictures, and we compose // textures from the TEXTURES list of patches. // -typedef struct +struct patch_t { INT16 width, height; INT16 leftoffset, topoffset; @@ -821,7 +821,7 @@ typedef struct #ifdef ROTSPRITE rotsprite_t *rotated; // Rotated patches #endif -} patch_t; +}; extern patch_t *missingpat; extern patch_t *blanklvl; @@ -830,7 +830,7 @@ extern patch_t *blanklvl; #pragma pack(1) #endif -typedef struct +struct softwarepatch_t { INT16 width; // bounding box size INT16 height; @@ -838,14 +838,14 @@ typedef struct INT16 topoffset; // pixels below the origin INT32 columnofs[8]; // only [width] used // the [0] is &columnofs[width] -} ATTRPACK softwarepatch_t; +} ATTRPACK; #ifdef _MSC_VER #pragma warning(disable : 4200) #endif // a pic is an unmasked block of pixels, stored in horizontal way -typedef struct +struct pic_t { INT16 width; UINT8 zero; // set to 0 allow autodetection of pic_t @@ -854,7 +854,7 @@ typedef struct INT16 height; INT16 reserved1; // set to 0 UINT8 data[]; -} ATTRPACK pic_t; +} ATTRPACK; #ifdef _MSC_VER #pragma warning(default : 4200) @@ -951,7 +951,7 @@ typedef enum // Or the right side: NNNNFR // Or both, mirrored: NNNNFLFR // -typedef struct +struct spriteframe_t { // If false use 0 for any position. // Note: as eight entries are available, we might as well insert the same @@ -968,15 +968,15 @@ typedef struct #ifdef ROTSPRITE rotsprite_t *rotated[2][16]; // Rotated patches #endif -} spriteframe_t; +}; // // A sprite definition: a number of animation frames. // -typedef struct +struct spritedef_t { size_t numframes; spriteframe_t *spriteframes; -} spritedef_t; +}; #endif diff --git a/src/r_draw.h b/src/r_draw.h index d01ad6e74..130c44c00 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -72,9 +72,9 @@ extern UINT8 *ds_source; extern UINT8 *ds_brightmap; extern UINT8 *ds_transmap; -typedef struct { +struct floatv3_t { float x, y, z; -} floatv3_t; +}; // Vectors for Software's tilted slope drawers extern floatv3_t *ds_su, *ds_sv, *ds_sz; diff --git a/src/r_fps.h b/src/r_fps.h index c2bc05699..8a12e1d10 100644 --- a/src/r_fps.h +++ b/src/r_fps.h @@ -40,7 +40,7 @@ extern enum viewcontext_e viewcontext; #define R_GetViewNumber() ((viewcontext - VIEWCONTEXT_PLAYER1) & 3) -typedef struct { +struct viewvars_t { fixed_t x; fixed_t y; fixed_t z; @@ -54,11 +54,11 @@ typedef struct { fixed_t cos; fixed_t sin; mobj_t *mobj; -} viewvars_t; +}; extern viewvars_t *newview; -typedef struct { +struct interpmobjstate_t { fixed_t x; fixed_t y; fixed_t z; @@ -69,7 +69,7 @@ typedef struct { fixed_t spriteyscale; fixed_t spritexoffset; fixed_t spriteyoffset; -} interpmobjstate_t; +}; // Level interpolators @@ -83,7 +83,7 @@ typedef enum { } levelinterpolator_type_e; // Tagged union of a level interpolator -typedef struct levelinterpolator_s { +struct levelinterpolator_t { levelinterpolator_type_e type; thinker_t *thinker; union { @@ -116,7 +116,7 @@ typedef struct levelinterpolator_s { fixed_t oldzdelta, bakzdelta; } dynslope; }; -} levelinterpolator_t; +}; // Interpolates the current view variables (r_state.h) against the selected view context in R_SetViewContext void R_InterpolateView(fixed_t frac); diff --git a/src/r_picformats.h b/src/r_picformats.h index 700424814..57af58100 100644 --- a/src/r_picformats.h +++ b/src/r_picformats.h @@ -92,18 +92,18 @@ typedef enum ROTAXIS_Z // Yaw } rotaxis_t; -typedef struct +struct spriteframepivot_t { INT32 x, y; rotaxis_t rotaxis; -} spriteframepivot_t; +}; -typedef struct +struct spriteinfo_t { spriteframepivot_t pivot[64 + 1]; #define SPRINFO_DEFAULT_PIVOT (64) UINT8 available[BIT_ARRAY_SIZE(64 + 1)]; // 1 extra for default_pivot -} spriteinfo_t; +}; // Portable Network Graphics #define PNG_HEADER_SIZE (8) diff --git a/src/r_plane.h b/src/r_plane.h index f0a32d969..1aa5f84e3 100644 --- a/src/r_plane.h +++ b/src/r_plane.h @@ -28,7 +28,7 @@ // Now what is a visplane, anyway? // Simple: kinda floor/ceiling polygon optimised for SRB2 rendering. // -typedef struct visplane_s +struct visplane_s { struct visplane_s *next; @@ -56,7 +56,7 @@ typedef struct visplane_s boolean noencore; boolean ripple; -} visplane_t; +}; extern visplane_t *visplanes[MAXVISPLANES]; extern visplane_t *floorplane; @@ -104,7 +104,7 @@ void R_CalculateSlopeVectors(void); // Sets the slope vector pointers for the current tilted span. void R_SetTiltedSpan(INT32 span); -typedef struct planemgr_s +struct visffloor_t { visplane_t *plane; fixed_t height; @@ -123,7 +123,7 @@ typedef struct planemgr_s struct ffloor_s *ffloor; polyobj_t *polyobj; -} visffloor_t; +}; extern visffloor_t ffloor[MAXFFLOORS]; extern INT32 numffloors; diff --git a/src/r_portal.h b/src/r_portal.h index 3e77b2ef7..556faac8e 100644 --- a/src/r_portal.h +++ b/src/r_portal.h @@ -20,7 +20,7 @@ /** Portal structure for the software renderer. */ -typedef struct portal_s +struct portal_s { struct portal_s *next; @@ -39,7 +39,7 @@ typedef struct portal_s INT16 *ceilingclip; /**< Temporary screen top clipping array. */ INT16 *floorclip; /**< Temporary screen bottom clipping array. */ fixed_t *frontscale;/**< Temporary screen bottom clipping array. */ -} portal_t; +}; extern portal_t* portal_base; extern portal_t* portal_cap; diff --git a/src/r_skins.h b/src/r_skins.h index 1cc06cca4..f9dd944c0 100644 --- a/src/r_skins.h +++ b/src/r_skins.h @@ -30,7 +30,7 @@ #define DEFAULTSKIN4 "knuckles" // fourth player /// The skin_t struct -typedef struct +struct skin_t { char name[SKINNAMESIZE+1]; // INT16 descriptive name of the skin UINT16 wadnum; @@ -61,7 +61,7 @@ typedef struct // contains super versions too spritedef_t sprites[NUMPLAYERSPRITES*2]; spriteinfo_t sprinfo[NUMPLAYERSPRITES*2]; -} skin_t; +}; enum facepatches { FACE_RANK = 0, diff --git a/src/r_splats.h b/src/r_splats.h index a26661e03..23e475c06 100644 --- a/src/r_splats.h +++ b/src/r_splats.h @@ -28,7 +28,7 @@ struct rastery_s }; extern struct rastery_s *prastertab; // for ASM code -typedef struct floorsplat_s +struct floorsplat_t { UINT16 *pic; INT32 width, height; @@ -39,7 +39,7 @@ typedef struct floorsplat_s vector3_t verts[4]; // (x,y,z) as viewed from above on map fixed_t x, y, z; // position mobj_t *mobj; // Mobj it is tied to -} floorsplat_t; +}; void R_DrawFloorSplat(vissprite_t *spr); diff --git a/src/r_state.h b/src/r_state.h index dc577448e..4807a0f92 100644 --- a/src/r_state.h +++ b/src/r_state.h @@ -28,13 +28,13 @@ // // needed for pre rendering (fracs) -typedef struct +struct sprcache_t { fixed_t width; fixed_t offset; fixed_t topoffset; fixed_t height; -} sprcache_t; +}; extern sprcache_t *spritecachedinfo; diff --git a/src/r_textures.h b/src/r_textures.h index d4c9302e5..8f39f5bd4 100644 --- a/src/r_textures.h +++ b/src/r_textures.h @@ -28,7 +28,7 @@ // A single patch from a texture definition, // basically a rectangular area within // the texture rectangle. -typedef struct +struct texpatch_t { // Block origin (always UL), which has already accounted for the internal origin of the patch. INT16 originx, originy; @@ -36,7 +36,7 @@ typedef struct UINT8 flip; // 1 = flipx, 2 = flipy, 3 = both UINT8 alpha; // Translucency value patchalphastyle_t style; -} texpatch_t; +}; // texture type enum @@ -52,7 +52,7 @@ enum // A texture_t describes a rectangular texture, // which is composed of one or more texpatch_t structures // that arrange graphic patches. -typedef struct +struct texture_t { // Keep name for switch changing, etc. char name[8]; @@ -66,7 +66,7 @@ typedef struct // All the patches[patchcount] are drawn back to front into the cached texture. INT16 patchcount; texpatch_t patches[]; -} texture_t; +}; // all loaded and prepared textures from the start of the game extern texture_t **textures; diff --git a/src/r_things.h b/src/r_things.h index 18c55629b..06965c797 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -96,13 +96,13 @@ boolean R_ThingIsFlashing(mobj_t *thing); * per portal to later group them in separate * drawnode lists. */ -typedef struct +struct maskcount_t { size_t drawsegs[2]; size_t vissprites[2]; fixed_t viewx, viewy, viewz; /**< View z stored at the time of the BSP traversal for the view/portal. Masked sorting/drawing needs it. */ sector_t* viewsector; -} maskcount_t; +}; void R_DrawMasked(maskcount_t* masks, INT32 nummasks); @@ -145,7 +145,7 @@ typedef enum // A vissprite_t is a thing that will be drawn during a refresh, // i.e. a sprite object that is partly visible. -typedef struct vissprite_s +struct vissprite_s { // Doubly linked list. struct vissprite_s *prev; @@ -219,7 +219,7 @@ typedef struct vissprite_s INT32 dispoffset; // copy of info->dispoffset, affects ordering but not drawing fixed_t floorclip; // Cut off your tires in tall grass -} vissprite_t; +}; extern UINT32 visspritecount; @@ -236,7 +236,7 @@ UINT8 *R_GetSpriteTranslation(vissprite_t *vis); // A drawnode is something that points to a 3D floor, 3D side, or masked // middle texture. This is used for sorting with sprites. -typedef struct drawnode_s +struct drawnode_s { visplane_t *plane; drawseg_t *seg; @@ -246,7 +246,7 @@ typedef struct drawnode_s struct drawnode_s *next; struct drawnode_s *prev; -} drawnode_t; +}; void R_InitDrawNodes(void); diff --git a/src/s_sound.h b/src/s_sound.h index e67868266..d1a7ba25f 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -66,12 +66,12 @@ typedef enum SF_X2AWAYSOUND = 64, // Hear it from 2x the distance away } soundflags_t; -typedef struct { +struct listener_t { fixed_t x, y, z; angle_t angle; -} listener_t; +}; -typedef struct +struct channel_t { // sound information (if null, channel avail.) sfxinfo_t *sfxinfo; @@ -85,14 +85,14 @@ typedef struct // handle of the sound being played INT32 handle; -} channel_t; +}; -typedef struct { +struct caption_t { channel_t *c; sfxinfo_t *s; UINT16 t; UINT8 b; -} caption_t; +}; #define NUMCAPTIONS 8 #define MAXCAPTIONTICS (2*TICRATE) @@ -170,14 +170,14 @@ boolean S_MusicInfo(char *mname, UINT16 *mflags, boolean *looping); boolean S_SpeedMusic(float speed); // Music credits -typedef struct musicdef_s +struct musicdef_s { char name[7]; //char usage[256]; char source[256]; int volume; struct musicdef_s *next; -} musicdef_t; +}; extern struct cursongcredit { @@ -218,7 +218,7 @@ UINT32 S_GetMusicPosition(void); // Music Stacking (Jingles) // -typedef struct musicstack_s +struct musicstack_s { char musname[7]; UINT16 musflags; @@ -231,7 +231,7 @@ typedef struct musicstack_s struct musicstack_s *prev; struct musicstack_s *next; -} musicstack_t; +}; extern char music_stack_nextmusname[7]; extern boolean music_stack_noposition; diff --git a/src/screen.h b/src/screen.h index 8abf77224..6728f3762 100644 --- a/src/screen.h +++ b/src/screen.h @@ -45,7 +45,7 @@ #define BASEVIDHEIGHT 200 // resolution of the graphics. // global video state -typedef struct viddef_s +struct viddef_t { INT32 modenum; // vidmode num indexes videomodes list @@ -74,7 +74,7 @@ typedef struct viddef_s INT32/*fixed_t*/ fmeddupx, fmeddupy; INT32 glstate; #endif -} viddef_t; +}; enum { @@ -84,14 +84,14 @@ enum }; // internal additional info for vesa modes only -typedef struct +struct vesa_extra_t { INT32 vesamode; // vesa mode number plus LINEAR_MODE bit void *plinearmem; // linear address of start of frame buffer -} vesa_extra_t; +}; // a video modes from the video modes list, // note: video mode 0 is always standard VGA320x200. -typedef struct vmode_s +struct vmode_s { struct vmode_s *pnext; char *name; @@ -107,7 +107,7 @@ typedef struct vmode_s INT32 (*setmode)(viddef_t *lvid, struct vmode_s *pcurrentmode); #endif INT32 misc; // misc for display driver (r_opengl.dll etc) -} vmode_t; +}; #define NUMSPECIALMODES 4 extern vmode_t specialmodes[NUMSPECIALMODES]; diff --git a/src/sounds.h b/src/sounds.h index fe4427048..01dfbfc2b 100644 --- a/src/sounds.h +++ b/src/sounds.h @@ -62,9 +62,8 @@ typedef enum // // SoundFX struct. // -typedef struct sfxinfo_struct sfxinfo_t; -struct sfxinfo_struct +struct sfxinfo_t { // up to 6-character name const char *name; diff --git a/src/taglist.h b/src/taglist.h index a66312425..8db78b880 100644 --- a/src/taglist.h +++ b/src/taglist.h @@ -21,11 +21,11 @@ typedef INT16 mtag_t; #define MTAG_GLOBAL -1 /// Multitag list. Each taggable element will have its own taglist. -typedef struct +struct taglist_t { mtag_t* tags; UINT16 count; -} taglist_t; +}; void Tag_Add (taglist_t* list, const mtag_t tag); void Tag_Remove (taglist_t* list, const mtag_t tag); @@ -40,12 +40,12 @@ void Tag_SectorRemove (const size_t id, const mtag_t tag); void Tag_SectorFSet (const size_t id, const mtag_t tag); /// Taggroup list. It is essentially just an element id list. -typedef struct +struct taggroup_t { size_t *elements; size_t count; size_t capacity; -} taggroup_t; +}; extern bitarray_t tags_available[]; diff --git a/src/typedef.h b/src/typedef.h new file mode 100644 index 000000000..bbfaafad4 --- /dev/null +++ b/src/typedef.h @@ -0,0 +1,397 @@ +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 2022 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 typedef.h +/// \brief Universally accessible type definitions. This +/// file exists so these types can be used anywhere +/// without needing to include specific headers. + +#define TYPEDEF2(struct_id, new_type) \ + typedef struct struct_id new_type + +#define TYPEDEF(id) TYPEDEF2 (id, id) + +// am_map.h +TYPEDEF (fpoint_t); +TYPEDEF (fline_t); + +// command.h +TYPEDEF (vsbuf_t); +TYPEDEF (CV_PossibleValue_t); +TYPEDEF2 (consvar_s, consvar_t); + +// d_netcmd.h +TYPEDEF (changeteam_packet_t); +TYPEDEF (changeteam_value_t); +TYPEDEF (scheduleTask_t); + +// discord.h +TYPEDEF2 (discordRequest_s, discordRequest_t); + +// d_player.h +TYPEDEF (respawnvars_t); +TYPEDEF (botvars_t); +TYPEDEF (skybox_t); +TYPEDEF2 (player_s, player_t); + +// d_clisrv.h +TYPEDEF (clientcmd_pak); +TYPEDEF (client2cmd_pak); +TYPEDEF (client3cmd_pak); +TYPEDEF (client4cmd_pak); +TYPEDEF (servertics_pak); +TYPEDEF (serverconfig_pak); +TYPEDEF (filetx_pak); +TYPEDEF (fileacksegment_t); +TYPEDEF (fileack_pak); +TYPEDEF (clientconfig_pak); +TYPEDEF (serverinfo_pak); +TYPEDEF (serverrefuse_pak); +TYPEDEF (askinfo_pak); +TYPEDEF (msaskinfo_pak); +TYPEDEF (plrinfo); +TYPEDEF (plrconfig); +TYPEDEF (filesneededconfig_pak); +TYPEDEF (doomdata_t); +TYPEDEF (serverelem_t); +TYPEDEF2 (rewind_s, rewind_t); + +// d_event.h +TYPEDEF (event_t); + +// d_netfil.h +TYPEDEF (fileneeded_t); +TYPEDEF (HTTP_login); +TYPEDEF2 (luafiletransfer_s, luafiletransfer_t); + +// d_think.h +TYPEDEF2 (thinker_s, thinker_t); + +// d_ticcmd.h +TYPEDEF (ticcmd_t); + +// deh_tables.h +TYPEDEF (actionpointer_t); + +// dehacked.h +TYPEDEF (MYFILE); + +// domdata.h +TYPEDEF (mapvertex_t); +TYPEDEF (mapsidedef_t); +TYPEDEF (maplinedef_t); +TYPEDEF (mapsector_t); +TYPEDEF (mapsubsector_t); +TYPEDEF (mapseg_t); +TYPEDEF (mapnode_t); +TYPEDEF (mapthing_t); + +// doomdef.h +TYPEDEF (skincolor_t); + +// doomstat.h +TYPEDEF (precipprops_t); +TYPEDEF (recorddata_t); +TYPEDEF (scene_t); +TYPEDEF (cutscene_t); +TYPEDEF (textpage_t); +TYPEDEF (textprompt_t); +TYPEDEF (mappoint_t); +TYPEDEF (customoption_t); +TYPEDEF (mapheader_t); +TYPEDEF (tolinfo_t); +TYPEDEF2 (cupheader_s, cupheader_t); + +// font.h +TYPEDEF (font_t); + +// g_demo.h +TYPEDEF (democharlist_t); +TYPEDEF (menudemo_t); +TYPEDEF (demoghost); + +// g_game.h +TYPEDEF (mapsearchfreq_t); + +// hu_stuff.h +TYPEDEF (playersort_t); + +// i_joy.h +TYPEDEF (JoyType_t); + +// i_net.h +TYPEDEF (doomcom_t); +TYPEDEF (holepunch_t); +TYPEDEF (bannednode_t); + +// i_system.h +TYPEDEF (JoyFF_t); +TYPEDEF (CPUInfoFlags); + +// i_time.h +TYPEDEF (timestate_t); + +// info.h +TYPEDEF (state_t); +TYPEDEF (mobjinfo_t); + +// k_bheap.h +TYPEDEF (bheapitem_t); +TYPEDEF2 (bheap_s, bheap_t); + +// k_boss.h +TYPEDEF (weakspot_t); + +// k_bot.h +TYPEDEF (botprediction_t); + +// k_brightmap.h +TYPEDEF (brightmapStorage_t); + +// k_follower.h +TYPEDEF (follower_t); +TYPEDEF (followercategory_t); + +// k_hud.h +TYPEDEF (trackingResult_t); + +// k_menu.h +TYPEDEF2 (menucolor_s, menucolor_t); +TYPEDEF (menuitem_t); +TYPEDEF2 (menu_s, menu_t); +TYPEDEF (menucmd_t); +TYPEDEF (setup_player_t); +TYPEDEF (modedesc_t); + +// k_pathfind.h +TYPEDEF2 (pathfindnode_s, pathfindnode_t); +TYPEDEF (path_t); +TYPEDEF (pathfindsetup_t); + +// k_profiles.h +TYPEDEF (profile_t); + +// k_terrain.h +TYPEDEF (t_splash_t); +TYPEDEF (t_footstep_t); +TYPEDEF (t_overlay_t); +TYPEDEF2 (terrain_s, terrain_t); +TYPEDEF (t_floor_t); + +// k_waypoint.h +TYPEDEF2 (waypoint_s, waypoint_t); + +// lua_hudlib_drawlist.h +typedef struct huddrawlist_s *huddrawlist_h; + +// m_aatree.h +TYPEDEF (aatree_t); + +// m_cond.h +TYPEDEF (condition_t); +TYPEDEF (conditionset_t); +TYPEDEF (emblem_t); +TYPEDEF (extraemblem_t); +TYPEDEF (unlockable_t); + +// m_dllist.h +TYPEDEF2 (mdllistitem_s, mdllistitem_t); + +// m_fixed.h +TYPEDEF (vector2_t); +TYPEDEF (vector3_t); +TYPEDEF (matrix_t); + +// m_perfstats.h +TYPEDEF (ps_hookinfo_t); +TYPEDEF (ps_botinfo_t); + +// m_queue.h +TYPEDEF2 (mqueueitem_s, mqueueitem_t); +TYPEDEF (mqueue_t); + +// mserv.h +TYPEDEF (msg_server_t); +TYPEDEF (msg_ban_t); + +// p_local.h +TYPEDEF (camera_t); +TYPEDEF (jingle_t); +TYPEDEF (tm_t); +TYPEDEF (TryMoveResult_t); +TYPEDEF (BasicFF_t); + +// p_maputl.h +TYPEDEF (divline_t); +TYPEDEF (intercept_t); + +// p_mobj.h +TYPEDEF2 (mobj_s, mobj_t); +TYPEDEF2 (precipmobj_s, precipmobj_t); +TYPEDEF2 (actioncache_s, actioncache_t); + +// p_polyobj.h +TYPEDEF2 (polyobj_s, polyobj_t); +TYPEDEF (polymaplink_t); +TYPEDEF (polyrotate_t); +TYPEDEF (polymove_t); +TYPEDEF (polywaypoint_t); +TYPEDEF (polyslidedoor_t); +TYPEDEF (polyswingdoor_t); +TYPEDEF (polydisplace_t); +TYPEDEF (polyrotdisplace_t); +TYPEDEF (polyfade_t); +TYPEDEF (polyrotdata_t); +TYPEDEF (polymovedata_t); +TYPEDEF (polywaypointdata_t); +TYPEDEF (polydoordata_t); +TYPEDEF (polydisplacedata_t); +TYPEDEF (polyrotdisplacedata_t); +TYPEDEF (polyflagdata_t); +TYPEDEF (polyfadedata_t); + +// p_saveg.h +TYPEDEF (savedata_t); + +// p_setup.h +TYPEDEF (levelflat_t); + +// p_slopes.h +TYPEDEF (dynlineplanethink_t); +TYPEDEF (dynvertexplanethink_t); + +// p_spec.h +TYPEDEF (thinkerdata_t); +TYPEDEF (fireflicker_t); +TYPEDEF (lightflash_t); +TYPEDEF (laserthink_t); +TYPEDEF (strobe_t); +TYPEDEF (glow_t); +TYPEDEF (lightlevel_t); +TYPEDEF (ceiling_t); +TYPEDEF (floormove_t); +TYPEDEF (elevator_t); +TYPEDEF (crumble_t); +TYPEDEF (noenemies_t); +TYPEDEF (continuousfall_t); +TYPEDEF (bouncecheese_t); +TYPEDEF (mariothink_t); +TYPEDEF (mariocheck_t); +TYPEDEF (thwomp_t); +TYPEDEF (floatthink_t); +TYPEDEF (eachtime_t); +TYPEDEF (raise_t); +TYPEDEF (executor_t); +TYPEDEF (scroll_t); +TYPEDEF (friction_t); +TYPEDEF (pusher_t); +TYPEDEF (disappear_t); +TYPEDEF (fade_t); +TYPEDEF (fadecolormap_t); +TYPEDEF (planedisplace_t); + +// r_data.h +TYPEDEF (lumplist_t); + +// r_defs.h +TYPEDEF (cliprange_t); +TYPEDEF (vertex_t); +TYPEDEF (degenmobj_t); +TYPEDEF (light_t); +//TYPEDEF (node_t); +TYPEDEF (post_t); +TYPEDEF (drawseg_t); +TYPEDEF (rotsprite_t); +TYPEDEF (patch_t); +TYPEDEF (softwarepatch_t); +TYPEDEF (pic_t); +TYPEDEF (spriteframe_t); +TYPEDEF (spritedef_t); +TYPEDEF2 (extracolormap_s, extracolormap_t); +TYPEDEF2 (ffloor_s, ffloor_t); +TYPEDEF (lightlist_t); +TYPEDEF2 (r_lightlist_s, r_lightlist_t); +TYPEDEF2 (pslope_s, pslope_t); +TYPEDEF2 (sector_s, sector_t); +TYPEDEF2 (line_s, line_t); +TYPEDEF (side_t); +TYPEDEF2 (subsector_s, subsector_t); +TYPEDEF2 (msecnode_s, msecnode_t); +TYPEDEF2 (mprecipsecnode_s, mprecipsecnode_t); +TYPEDEF2 (lightmap_s, lightmap_t); +TYPEDEF2 (seg_s, seg_t); + +// r_draw.h +TYPEDEF (floatv3_t); + +// r_fps.h +TYPEDEF (viewvars_t); +TYPEDEF (interpmobjstate_t); +TYPEDEF (levelinterpolator_t); + +// r_picformats.h +TYPEDEF (spriteframepivot_t); +TYPEDEF (spriteinfo_t); + +// r_plane.h +TYPEDEF2 (visplane_s, visplane_t); +TYPEDEF (visffloor_t); + +// r_portal.h +TYPEDEF2 (portal_s, portal_t); + +// r_skins.h +TYPEDEF (skin_t); + +// r_splats.h +TYPEDEF (floorsplat_t); + +// r_state.h +TYPEDEF (sprcache_t); + +// r_textures.h +TYPEDEF (texpatch_t); +TYPEDEF (texture_t); + +// r_things.h +TYPEDEF (maskcount_t); +TYPEDEF2 (vissprite_s, vissprite_t); +TYPEDEF2 (drawnode_s, drawnode_t); + +// s_sound.h +TYPEDEF (listener_t); +TYPEDEF (channel_t); +TYPEDEF (caption_t); +TYPEDEF2 (musicdef_s, musicdef_t); +TYPEDEF2 (musicstack_s, musicstack_t); + +// screen.h +TYPEDEF (viddef_t); +TYPEDEF (vesa_extra_t); +TYPEDEF2 (vmode_s, vmode_t); + +// sounds.h +TYPEDEF (sfxinfo_t); + +// taglist.h +TYPEDEF (taglist_t); +TYPEDEF (taggroup_t); + +// v_video.h +TYPEDEF (colorlookup_t); + +// w_wad.h +TYPEDEF (filelump_t); +TYPEDEF (wadinfo_t); +TYPEDEF (lumpinfo_t); +TYPEDEF (virtlump_t); +TYPEDEF (virtres_t); +TYPEDEF (wadfile_t); + +#undef TYPEDEF +#undef TYPEDEF2 diff --git a/src/v_video.h b/src/v_video.h index 1803d0818..8009035ea 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -46,12 +46,12 @@ void V_Recalc(void); // Color look-up table #define CLUTINDEX(r, g, b) (((r) >> 3) << 11) | (((g) >> 2) << 5) | ((b) >> 3) -typedef struct +struct colorlookup_t { boolean init; RGBA_t palette[256]; UINT16 table[0xFFFF]; -} colorlookup_t; +}; void InitColorLUT(colorlookup_t *lut, RGBA_t *palette, boolean makecolors); UINT8 GetColorLUT(colorlookup_t *lut, UINT8 r, UINT8 g, UINT8 b); diff --git a/src/w_wad.h b/src/w_wad.h index ec3013af7..54bc9f4da 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -27,12 +27,12 @@ #if defined(_MSC_VER) #pragma pack(1) #endif -typedef struct +struct filelump_t { UINT32 filepos; // file offset of the resource UINT32 size; // size of the resource char name[8]; // name of the resource -} ATTRPACK filelump_t; +} ATTRPACK; #if defined(_MSC_VER) #pragma pack() #endif @@ -43,12 +43,12 @@ typedef struct // ============================================================== // header of a wad file -typedef struct +struct wadinfo_t { char identification[4]; // should be "IWAD" or "PWAD" UINT32 numlumps; // how many resources UINT32 infotableofs; // the 'directory' of resources -} wadinfo_t; +}; // Available compression methods for lumps. typedef enum @@ -62,7 +62,7 @@ typedef enum } compmethod; // a memory entry of the wad directory -typedef struct +struct lumpinfo_t { unsigned long position; // filelump_t filepos unsigned long disksize; // filelump_t size @@ -72,22 +72,22 @@ typedef struct char *fullname; // e.g. "Folder/Subfolder/LongEntryName.extension" size_t size; // real (uncompressed) size compmethod compression; // lump compression method -} lumpinfo_t; +}; // ========================================================================= // 'VIRTUAL' RESOURCES // ========================================================================= -typedef struct { +struct virtlump_t { char name[9]; UINT8* data; size_t size; -} virtlump_t; +}; -typedef struct { +struct virtres_t { size_t numlumps; virtlump_t* vlumps; -} virtres_t; +}; virtres_t* vres_GetMap(lumpnum_t); void vres_Free(virtres_t*); @@ -116,7 +116,7 @@ typedef enum restype RET_UNKNOWN, } restype_t; -typedef struct wadfile_s +struct wadfile_t { char *filename; restype_t type; @@ -129,7 +129,7 @@ typedef struct wadfile_s UINT8 md5sum[16]; boolean important; // also network - !W_VerifyNMUSlumps -} wadfile_t; +}; #define WADFILENUM(lumpnum) (UINT16)((lumpnum)>>16) // wad flumpnum>>16) // wad file number in upper word #define LUMPNUM(lumpnum) (UINT16)((lumpnum)&0xFFFF) // lump number for this pwad From 0d0310a140056229496a230617651e3d50b3d953 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 27 Nov 2022 16:51:18 -0800 Subject: [PATCH 02/66] typedef.h: typedef node_t d_net.c: rename node_t to netnode_t --- src/d_net.c | 12 ++++++------ src/r_defs.h | 4 ++-- src/typedef.h | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/d_net.c b/src/d_net.c index 5978fef5d..3799ecd13 100644 --- a/src/d_net.c +++ b/src/d_net.c @@ -192,9 +192,9 @@ typedef struct UINT8 nextacknum; UINT8 flags; -} node_t; +} netnode_t; -static node_t nodes[MAXNETNODES]; +static netnode_t nodes[MAXNETNODES]; #define NODETIMEOUT 14 // return <0 if a < b (mod 256) @@ -218,7 +218,7 @@ FUNCMATH static INT32 cmpack(UINT8 a, UINT8 b) */ static boolean GetFreeAcknum(UINT8 *freeack, boolean lowtimer) { - node_t *node = &nodes[doomcom->remotenode]; + netnode_t *node = &nodes[doomcom->remotenode]; INT32 i, numfreeslot = 0; if (cmpack((UINT8)((node->remotefirstack + MAXACKTOSEND) % 256), node->nextacknum) < 0) @@ -325,7 +325,7 @@ static boolean Processackpak(void) { INT32 i; boolean goodpacket = true; - node_t *node = &nodes[doomcom->remotenode]; + netnode_t *node = &nodes[doomcom->remotenode]; // Received an ack return, so remove the ack in the list if (netbuffer->ackreturn && cmpack(node->remotefirstack, netbuffer->ackreturn) < 0) @@ -492,7 +492,7 @@ void Net_AckTicker(void) for (i = 0; i < MAXACKPACKETS; i++) { const INT32 nodei = ackpak[i].destinationnode; - node_t *node = &nodes[nodei]; + netnode_t *node = &nodes[nodei]; if (ackpak[i].acknum && ackpak[i].senttime + NODETIMEOUT < I_GetTime()) { if (ackpak[i].resentnum > 20 && (node->flags & NF_CLOSE)) @@ -612,7 +612,7 @@ void Net_WaitAllAckReceived(UINT32 timeout) } } -static void InitNode(node_t *node) +static void InitNode(netnode_t *node) { node->acktosend_head = node->acktosend_tail = 0; node->firstacktosend = 0; diff --git a/src/r_defs.h b/src/r_defs.h index 1d3fa65d8..2c1c67dc0 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -709,7 +709,7 @@ struct seg_s // // BSP node. // -typedef struct +struct node_t { // Partition line. fixed_t x, y; @@ -720,7 +720,7 @@ typedef struct // If NF_SUBSECTOR its a subsector. UINT16 children[2]; -} node_t; +}; #if defined(_MSC_VER) #pragma pack(1) diff --git a/src/typedef.h b/src/typedef.h index bbfaafad4..4bdddd18d 100644 --- a/src/typedef.h +++ b/src/typedef.h @@ -303,7 +303,7 @@ TYPEDEF (cliprange_t); TYPEDEF (vertex_t); TYPEDEF (degenmobj_t); TYPEDEF (light_t); -//TYPEDEF (node_t); +TYPEDEF (node_t); TYPEDEF (post_t); TYPEDEF (drawseg_t); TYPEDEF (rotsprite_t); From 051b4f8935e62a51698f8a30dfc056b80b5f1bb2 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 27 Nov 2022 17:20:42 -0800 Subject: [PATCH 03/66] Always use typedef name instead of struct name mobj_t instead of struct mobj_s --- src/command.h | 4 +-- src/d_clisrv.h | 4 +-- src/d_netfil.h | 4 +-- src/d_player.h | 2 +- src/d_think.h | 6 ++-- src/discord.h | 6 ++-- src/doomdata.h | 2 +- src/doomstat.h | 4 +-- src/k_bheap.h | 4 +-- src/k_menu.h | 16 +++++----- src/k_pathfind.h | 6 ++-- src/k_terrain.h | 2 +- src/k_waypoint.h | 6 ++-- src/m_dllist.h | 6 ++-- src/m_queue.h | 4 +-- src/p_local.h | 2 +- src/p_mobj.h | 62 ++++++++++++++++++------------------ src/p_polyobj.h | 16 +++++----- src/r_defs.h | 81 +++++++++++++++++++++++------------------------- src/r_draw.c | 2 +- src/r_draw.h | 2 +- src/r_plane.h | 10 +++--- src/r_portal.h | 4 +-- src/r_things.h | 14 ++++----- src/s_sound.h | 10 +++--- src/screen.h | 8 ++--- src/typedef.h | 74 +++++++++++++++++++++---------------------- 27 files changed, 179 insertions(+), 182 deletions(-) diff --git a/src/command.h b/src/command.h index 94cf2f269..6715d66a0 100644 --- a/src/command.h +++ b/src/command.h @@ -133,7 +133,7 @@ struct CV_PossibleValue_t const char *strvalue; }; -struct consvar_s //NULL, NULL, 0, NULL, NULL |, 0, NULL, NULL, 0, 0, NULL +struct consvar_t //NULL, NULL, 0, NULL, NULL |, 0, NULL, NULL, 0, 0, NULL { const char *name; const char *defaultvalue; @@ -157,7 +157,7 @@ struct consvar_s //NULL, NULL, 0, NULL, NULL |, 0, NULL, NULL, 0, 0, NULL UINT16 netid; // used internaly : netid for send end receive // used only with CV_NETVAR char changed; // has variable been changed by the user? 0 = no, 1 = yes - struct consvar_s *next; + consvar_t *next; }; /* name, defaultvalue, flags, PossibleValue, func */ diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 4effefde8..42393da1b 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -528,7 +528,7 @@ extern boolean hu_stopped; // SRB2Kart // -struct rewind_s { +struct rewind_t { UINT8 savebuffer[(768*1024)]; tic_t leveltime; size_t demopos; @@ -536,7 +536,7 @@ struct rewind_s { ticcmd_t oldcmd[MAXPLAYERS]; mobj_t oldghost[MAXPLAYERS]; - struct rewind_s *next; + rewind_t *next; }; void CL_ClearRewinds(void); diff --git a/src/d_netfil.h b/src/d_netfil.h index 2bc415406..1191e1bfa 100644 --- a/src/d_netfil.h +++ b/src/d_netfil.h @@ -110,7 +110,7 @@ typedef enum LFTNS_SENT // The node already has the file } luafiletransfernodestatus_t; -struct luafiletransfer_s +struct luafiletransfer_t { char *filename; char *realfilename; @@ -119,7 +119,7 @@ struct luafiletransfer_s boolean ongoing; luafiletransfernodestatus_t nodestatus[MAXNETNODES]; tic_t nodetimeouts[MAXNETNODES]; - struct luafiletransfer_s *next; + luafiletransfer_t *next; }; extern luafiletransfer_t *luafiletransfers; diff --git a/src/d_player.h b/src/d_player.h index cfd72df1c..a65f0235b 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -332,7 +332,7 @@ struct skybox_t { // ======================================================================== // PLAYER STRUCTURE // ======================================================================== -struct player_s +struct player_t { mobj_t *mo; diff --git a/src/d_think.h b/src/d_think.h index 8f786a4ed..719efa564 100644 --- a/src/d_think.h +++ b/src/d_think.h @@ -40,10 +40,10 @@ typedef union typedef actionf_t think_t; // Doubly linked list of actors. -struct thinker_s +struct thinker_t { - struct thinker_s *prev; - struct thinker_s *next; + thinker_t *prev; + thinker_t *next; think_t function; // killough 11/98: count of how many other objects reference diff --git a/src/discord.h b/src/discord.h index 99444b3cd..eb38a8d2c 100644 --- a/src/discord.h +++ b/src/discord.h @@ -27,7 +27,7 @@ extern struct discordInfo_s { boolean everyoneCanInvite; } discordInfo; -struct discordRequest_s { +struct discordRequest_t { char *username; // Discord user name. char *discriminator; // Discord discriminator (The little hashtag thing after the username). Separated for a "hide discriminators" cvar. char *userID; // The ID of the Discord user, gets used with Discord_Respond() @@ -38,8 +38,8 @@ struct discordRequest_s { // Hey, wanna add ImageMagick as a dependency? :dying: //patch_t *avatar; - struct discordRequest_s *next; // Next request in the list. - struct discordRequest_s *prev; // Previous request in the list. Not used normally, but just in case something funky happens, this should repair the list. + discordRequest_t *next; // Next request in the list. + discordRequest_t *prev; // Previous request in the list. Not used normally, but just in case something funky happens, this should repair the list. }; extern discordRequest_t *discordRequestList; diff --git a/src/doomdata.h b/src/doomdata.h index 0c02c17d4..5767da5ec 100644 --- a/src/doomdata.h +++ b/src/doomdata.h @@ -222,7 +222,7 @@ struct mapthing_t fixed_t scale; INT32 args[NUMMAPTHINGARGS]; char *stringargs[NUMMAPTHINGSTRINGARGS]; - struct mobj_s *mobj; + mobj_t *mobj; }; #define ZSHIFT 4 diff --git a/src/doomstat.h b/src/doomstat.h index 739c69ad2..320e29c13 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -347,7 +347,7 @@ struct customoption_t #define CUPCACHE_SPECIAL (CUPCACHE_BONUS+MAXBONUSLIST) #define CUPCACHE_MAX (CUPCACHE_SPECIAL+1) -struct cupheader_s +struct cupheader_t { UINT16 id; ///< Cup ID char name[15]; ///< Cup title (14 chars) @@ -358,7 +358,7 @@ struct cupheader_s UINT8 numbonus; ///< Number of bonus stages defined UINT8 emeraldnum; ///< ID of Emerald to use for special stage (1-7 for Chaos Emeralds, 8-14 for Super Emeralds, 0 for no emerald) SINT8 unlockrequired; ///< An unlockable is required to select this cup. -1 for no unlocking required. - struct cupheader_s *next; ///< Next cup in linked list + cupheader_t *next; ///< Next cup in linked list }; extern cupheader_t *kartcupheaders; // Start of cup linked list diff --git a/src/k_bheap.h b/src/k_bheap.h index 881a8973c..be07b40df 100644 --- a/src/k_bheap.h +++ b/src/k_bheap.h @@ -21,12 +21,12 @@ struct bheapitem_t { size_t heapindex; // The index in the heap this item is updateindexfunc indexchanged; // A callback function that is called when this item changes index to alert data - struct bheap_s *owner; // The heap that owns this item + bheap_t *owner; // The heap that owns this item void *data; // data for this heap item UINT32 value; // The value of this item, the lowest value item is first in the array }; -struct bheap_s +struct bheap_t { size_t capacity; // capacity of the heap size_t count; // number of items in the heap diff --git a/src/k_menu.h b/src/k_menu.h index 7e222d212..d8a966775 100644 --- a/src/k_menu.h +++ b/src/k_menu.h @@ -101,15 +101,15 @@ extern M_waiting_mode_t m_waiting_mode; typedef union { - struct menu_s *submenu; // IT_SUBMENU + menu_t *submenu; // IT_SUBMENU consvar_t *cvar; // IT_CVAR void (*routine)(INT32 choice); // IT_CALL, IT_KEYHANDLER, IT_ARROWS } itemaction_t; // Player Setup menu colors linked list -struct menucolor_s { - struct menucolor_s *next; - struct menucolor_s *prev; +struct menucolor_t { + menucolor_t *next; + menucolor_t *prev; UINT16 color; }; @@ -136,10 +136,10 @@ struct menuitem_t INT32 mvar2; }; -struct menu_s +struct menu_t { INT16 numitems; // # of menu items - struct menu_s *prevMenu; // previous menu + menu_t *prevMenu; // previous menu INT16 lastOn; // last item user was on in menu menuitem_t *menuitems; // menu items @@ -537,8 +537,8 @@ extern menucmd_t menucmd[MAXSPLITSCREENPLAYERS]; extern struct menutransition_s { INT16 tics; INT16 dest; - struct menu_s *startmenu; - struct menu_s *endmenu; + menu_t *startmenu; + menu_t *endmenu; boolean in; } menutransition; diff --git a/src/k_pathfind.h b/src/k_pathfind.h index c18911202..38b0b207f 100644 --- a/src/k_pathfind.h +++ b/src/k_pathfind.h @@ -35,10 +35,10 @@ typedef boolean(*getpathfindfinishedfunc)(void*, void*); // A pathfindnode contains information about a node from the pathfinding // heapindex is only used within the pathfinding algorithm itself, and is always 0 after it is completed -struct pathfindnode_s { +struct pathfindnode_t { size_t heapindex; // The index in the openset binary heap. Only valid while the node is in the openset. void *nodedata; - struct pathfindnode_s *camefrom; // should eventually be the most efficient predecessor node + pathfindnode_t *camefrom; // should eventually be the most efficient predecessor node UINT32 gscore; // The accumulated distance from the start to this node UINT32 hscore; // The heuristic from this node to the goal }; @@ -46,7 +46,7 @@ struct pathfindnode_s { // Contains the final created path after pathfinding is completed struct path_t { size_t numnodes; - struct pathfindnode_s *array; + pathfindnode_t *array; UINT32 totaldist; }; diff --git a/src/k_terrain.h b/src/k_terrain.h index 56bf7df34..349455bed 100644 --- a/src/k_terrain.h +++ b/src/k_terrain.h @@ -98,7 +98,7 @@ typedef enum TRF_TRIPWIRE = 1<<3 // Texture is a tripwire when used as a midtexture } terrain_flags_t; -struct terrain_s +struct terrain_t { // Terrain definition. // These are all of the properties that the floor gets. diff --git a/src/k_waypoint.h b/src/k_waypoint.h index 9322477e1..9239cd41c 100644 --- a/src/k_waypoint.h +++ b/src/k_waypoint.h @@ -20,12 +20,12 @@ #define DEFAULT_WAYPOINT_RADIUS (384) -struct waypoint_s +struct waypoint_t { mobj_t *mobj; boolean onaline; - struct waypoint_s **nextwaypoints; - struct waypoint_s **prevwaypoints; + waypoint_t **nextwaypoints; + waypoint_t **prevwaypoints; UINT32 *nextwaypointdistances; UINT32 *prevwaypointdistances; size_t numnextwaypoints; diff --git a/src/m_dllist.h b/src/m_dllist.h index 9b9cfca81..1a1f0a6ea 100644 --- a/src/m_dllist.h +++ b/src/m_dllist.h @@ -29,10 +29,10 @@ #pragma warning(disable : 4706) #endif -struct mdllistitem_s +struct mdllistitem_t { - struct mdllistitem_s *next; - struct mdllistitem_s **prev; + mdllistitem_t *next; + mdllistitem_t **prev; }; FUNCINLINE static ATTRINLINE void M_DLListInsert(mdllistitem_t *item, mdllistitem_t **head) diff --git a/src/m_queue.h b/src/m_queue.h index 6ba8e335c..8e0c02797 100644 --- a/src/m_queue.h +++ b/src/m_queue.h @@ -13,9 +13,9 @@ #ifndef M_QUEUE_H #define M_QUEUE_H -struct mqueueitem_s +struct mqueueitem_t { - struct mqueueitem_s *next; + mqueueitem_t *next; }; struct mqueue_t diff --git a/src/p_local.h b/src/p_local.h index 70e26f9d9..e547bc7b4 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -96,7 +96,7 @@ struct camera_t //More drawing info: to determine current sprite. angle_t angle; // orientation - struct subsector_s *subsector; + subsector_t *subsector; // The closest interval over all contacted Sectors (or Things). fixed_t floorz; diff --git a/src/p_mobj.h b/src/p_mobj.h index 50686eac9..8811c0149 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -270,7 +270,7 @@ typedef enum { } precipflag_t; // Map Object definition. -struct mobj_s +struct mobj_t { // List: thinker links. thinker_t thinker; @@ -284,8 +284,8 @@ struct mobj_s fixed_t old_x2, old_y2, old_z2; // More list: links in sector (if needed) - struct mobj_s *snext; - struct mobj_s **sprev; // killough 8/11/98: change to ptr-to-ptr + mobj_t *snext; + mobj_t **sprev; // killough 8/11/98: change to ptr-to-ptr // More drawing info: to determine current sprite. angle_t angle, pitch, roll; // orientation @@ -302,17 +302,17 @@ struct mobj_s fixed_t spritexoffset, spriteyoffset; fixed_t old_spritexscale, old_spriteyscale; fixed_t old_spritexoffset, old_spriteyoffset; - struct pslope_s *floorspriteslope; // The slope that the floorsprite is rotated by + pslope_t *floorspriteslope; // The slope that the floorsprite is rotated by - struct msecnode_s *touching_sectorlist; // a linked list of sectors where this object appears + msecnode_t *touching_sectorlist; // a linked list of sectors where this object appears - struct subsector_s *subsector; // Subsector the mobj resides in. + subsector_t *subsector; // Subsector the mobj resides in. // The closest interval over all contacted sectors (or things). fixed_t floorz; // Nearest floor below. fixed_t ceilingz; // Nearest ceiling above. - struct ffloor_s *floorrover; // FOF referred by floorz - struct ffloor_s *ceilingrover; // FOF referred by ceilingz + ffloor_t *floorrover; // FOF referred by floorz + ffloor_t *ceilingrover; // FOF referred by ceilingz fixed_t floordrop; fixed_t ceilingdrop; @@ -337,15 +337,15 @@ struct mobj_s // Interaction info, by BLOCKMAP. // Links in blocks (if needed). - struct mobj_s *bnext; - struct mobj_s **bprev; // killough 8/11/98: change to ptr-to-ptr + mobj_t *bnext; + mobj_t **bprev; // killough 8/11/98: change to ptr-to-ptr // Additional pointers for NiGHTS hoops - struct mobj_s *hnext; - struct mobj_s *hprev; + mobj_t *hnext; + mobj_t *hprev; // One last pointer for kart item lists - struct mobj_s *itnext; + mobj_t *itnext; INT32 health; // for player this is rings + 1 -- no it isn't, not any more!! @@ -353,7 +353,7 @@ struct mobj_s angle_t movedir; // dirtype_t 0-7; also used by Deton for up/down angle INT32 movecount; // when 0, select a new dir - struct mobj_s *target; // Thing being chased/attacked (or NULL), and originator for missiles. + mobj_t *target; // Thing being chased/attacked (or NULL), and originator for missiles. INT32 reactiontime; // If not 0, don't attack yet. @@ -361,13 +361,13 @@ struct mobj_s // Additional info record for player avatars only. // Only valid if type == MT_PLAYER - struct player_s *player; + player_t *player; INT32 lastlook; // Player number last looked for. mapthing_t *spawnpoint; // Used for CTF flags, objectplace, and a handful other applications. - struct mobj_s *tracer; // Thing being chased/attacked for tracers. + mobj_t *tracer; // Thing being chased/attacked for tracers. fixed_t friction; fixed_t movefactor; @@ -394,7 +394,7 @@ struct mobj_s INT32 cusval; INT32 cvmem; - struct pslope_s *standingslope; // The slope that the object is standing on (shouldn't need synced in savegames, right?) + pslope_t *standingslope; // The slope that the object is standing on (shouldn't need synced in savegames, right?) boolean resetinterp; // if true, some fields should not be interpolated (see R_InterpolateMobjState implementation) boolean colorized; // Whether the mobj uses the rainbow colormap @@ -405,8 +405,8 @@ struct mobj_s fixed_t sprxoff, spryoff, sprzoff; // Sprite offsets in real space, does NOT affect position or collision - struct terrain_s *terrain; // Terrain definition of the floor this object last hit. NULL when in the air. - struct mobj_s *terrainOverlay; // Overlay sprite object for terrain + terrain_t *terrain; // Terrain definition of the floor this object last hit. NULL when in the air. + mobj_t *terrainOverlay; // Overlay sprite object for terrain INT32 hitlag; // Sal-style hit lag, straight from Captain Fetch's jowls UINT8 waterskip; // Water skipping counter @@ -423,7 +423,7 @@ struct mobj_s // so please keep the start of the // structure the same. // -struct precipmobj_s +struct precipmobj_t { // List: thinker links. thinker_t thinker; @@ -437,8 +437,8 @@ struct precipmobj_s fixed_t old_x2, old_y2, old_z2; // More list: links in sector (if needed) - struct precipmobj_s *snext; - struct precipmobj_s **sprev; // killough 8/11/98: change to ptr-to-ptr + precipmobj_t *snext; + precipmobj_t **sprev; // killough 8/11/98: change to ptr-to-ptr // More drawing info: to determine current sprite. angle_t angle, pitch, roll; // orientation @@ -455,17 +455,17 @@ struct precipmobj_s fixed_t spritexoffset, spriteyoffset; fixed_t old_spritexscale, old_spriteyscale; fixed_t old_spritexoffset, old_spriteyoffset; - struct pslope_s *floorspriteslope; // The slope that the floorsprite is rotated by + pslope_t *floorspriteslope; // The slope that the floorsprite is rotated by - struct mprecipsecnode_s *touching_sectorlist; // a linked list of sectors where this object appears + mprecipsecnode_t *touching_sectorlist; // a linked list of sectors where this object appears - struct subsector_s *subsector; // Subsector the mobj resides in. + subsector_t *subsector; // Subsector the mobj resides in. // The closest interval over all contacted sectors (or things). fixed_t floorz; // Nearest floor below. fixed_t ceilingz; // Nearest ceiling above. - struct ffloor_s *floorrover; // FOF referred by floorz - struct ffloor_s *ceilingrover; // FOF referred by ceilingz + ffloor_t *floorrover; // FOF referred by floorz + ffloor_t *ceilingrover; // FOF referred by ceilingz fixed_t floordrop; fixed_t ceilingdrop; @@ -482,11 +482,11 @@ struct precipmobj_s UINT32 flags; // flags from mobjinfo tables }; -struct actioncache_s +struct actioncache_t { - struct actioncache_s *next; - struct actioncache_s *prev; - struct mobj_s *mobj; + actioncache_t *next; + actioncache_t *prev; + mobj_t *mobj; INT32 statenum; }; diff --git a/src/p_polyobj.h b/src/p_polyobj.h index 9cb94126b..dc5dab153 100644 --- a/src/p_polyobj.h +++ b/src/p_polyobj.h @@ -66,7 +66,7 @@ typedef enum // Polyobject Structure // -struct polyobj_s +struct polyobj_t { mdllistitem_t link; // for subsector links; must be first @@ -78,7 +78,7 @@ struct polyobj_s size_t segCount; // number of segs in polyobject size_t numSegsAlloc; // number of segs allocated - struct seg_s **segs; // the segs, a reallocating array. + seg_t **segs; // the segs, a reallocating array. size_t numVertices; // number of vertices (generally == segCount) size_t numVerticesAlloc; // number of vertices allocated @@ -88,7 +88,7 @@ struct polyobj_s size_t numLines; // number of linedefs (generally <= segCount) size_t numLinesAlloc; // number of linedefs allocated - struct line_s **lines; // linedefs this polyobject must move + line_t **lines; // linedefs this polyobject must move degenmobj_t spawnSpot; // location of spawn spot vertex_t centerPt; // center point @@ -109,7 +109,7 @@ struct polyobj_s INT32 translucency; // index to translucency tables INT16 triggertag; // Tag of linedef executor to trigger on touch - struct visplane_s *visplane; // polyobject's visplane, for ease of putting into the list later + visplane_t *visplane; // polyobject's visplane, for ease of putting into the list later // these are saved for netgames, so do not let Lua touch these! INT32 spawnflags; // Flags the polyobject originally spawned with @@ -212,7 +212,7 @@ struct polydisplace_t thinker_t thinker; // must be first INT32 polyObjNum; - struct sector_s *controlSector; + sector_t *controlSector; fixed_t dx; fixed_t dy; fixed_t oldHeights; @@ -223,7 +223,7 @@ struct polyrotdisplace_t thinker_t thinker; // must be first INT32 polyObjNum; - struct sector_s *controlSector; + sector_t *controlSector; fixed_t rotscale; UINT8 turnobjs; fixed_t oldHeights; @@ -328,7 +328,7 @@ struct polydoordata_t struct polydisplacedata_t { INT32 polyObjNum; - struct sector_s *controlSector; + sector_t *controlSector; fixed_t dx; fixed_t dy; }; @@ -336,7 +336,7 @@ struct polydisplacedata_t struct polyrotdisplacedata_t { INT32 polyObjNum; - struct sector_s *controlSector; + sector_t *controlSector; fixed_t rotscale; UINT8 turnobjs; }; diff --git a/src/r_defs.h b/src/r_defs.h index 2c1c67dc0..59faac3c0 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -57,7 +57,7 @@ typedef UINT8 lighttable_t; #define CMF_FOG 4 // ExtraColormap type. Use for extra_colormaps from now on. -struct extracolormap_s +struct extracolormap_t { UINT8 fadestart, fadeend; UINT8 flags; @@ -74,8 +74,8 @@ struct extracolormap_s char lumpname[9]; // for netsyncing #endif - struct extracolormap_s *next; - struct extracolormap_s *prev; + extracolormap_t *next; + extracolormap_t *prev; }; // @@ -91,9 +91,6 @@ struct vertex_t fixed_t floorz, ceilingz; }; -// Forward of linedefs, for sectors. -struct line_s; - /** Degenerate version of ::mobj_t, storing only a location. * Used for sound origins in sectors, hoop centers, and the like. Does not * handle sound from moving objects (doppler), because position is probably @@ -208,7 +205,7 @@ typedef enum BT_STRONG, } busttype_e; -struct ffloor_s +struct ffloor_t { fixed_t *topheight; INT32 *toppic; @@ -224,17 +221,17 @@ struct ffloor_s angle_t *bottomangle; // Pointers to pointers. Yup. - struct pslope_s **t_slope; - struct pslope_s **b_slope; + pslope_t **t_slope; + pslope_t **b_slope; size_t secnum; ffloortype_e fofflags; - struct line_s *master; + line_t *master; - struct sector_s *target; + sector_t *target; - struct ffloor_s *next; - struct ffloor_s *prev; + ffloor_t *next; + ffloor_t *prev; INT32 lastlight; INT32 alpha; @@ -271,12 +268,12 @@ struct lightlist_t extracolormap_t **extra_colormap; // pointer-to-a-pointer, so we can react to colormap changes INT32 flags; ffloor_t *caster; - struct pslope_s *slope; // FOF_DOUBLESHADOW makes me have to store this pointer here. Bluh bluh. + pslope_t *slope; // FOF_DOUBLESHADOW makes me have to store this pointer here. Bluh bluh. }; // This struct is used for rendering walls with shadows casted on them... -struct r_lightlist_s +struct r_lightlist_t { fixed_t height; fixed_t heightstep; @@ -296,10 +293,10 @@ typedef enum { SL_DYNAMIC = 1<<1, /// This plane slope will be assigned a thinker to make it dynamic. } slopeflags_t; -struct pslope_s +struct pslope_t { UINT16 id; // The number of the slope, mostly used for netgame syncing purposes - struct pslope_s *next; // Make a linked list of dynamic slopes, for easy reference later + pslope_t *next; // Make a linked list of dynamic slopes, for easy reference later // The plane's definition. vector3_t o; /// Plane origin. @@ -399,7 +396,7 @@ typedef enum // The SECTORS record, at runtime. // Stores things/mobjs. // -struct sector_s +struct sector_t { fixed_t floorheight; fixed_t ceilingheight; @@ -445,10 +442,10 @@ struct sector_s // list of mobjs that are at least partially in the sector // thinglist is a subset of touching_thinglist - struct msecnode_s *touching_thinglist; + msecnode_t *touching_thinglist; size_t linecount; - struct line_s **lines; // [linecount] size + line_t **lines; // [linecount] size // Improved fake floor hack ffloor_t *ffloors; @@ -480,14 +477,14 @@ struct sector_s fixed_t friction; // Sprite culling feature - struct line_s *cullheight; + line_t *cullheight; // Current speed of ceiling/floor. For Knuckles to hold onto stuff. fixed_t floorspeed, ceilspeed; // list of precipitation mobjs in sector precipmobj_t *preciplist; - struct mprecipsecnode_s *touching_preciplist; + mprecipsecnode_t *touching_preciplist; // Eternity engine slope pslope_t *f_slope; // floor slope @@ -517,7 +514,7 @@ typedef enum #define NUMLINEARGS 10 #define NUMLINESTRINGARGS 2 -struct line_s +struct line_t { // Vertices, from v1 to v2. vertex_t *v1; @@ -590,12 +587,12 @@ struct side_t // Basically, this is a list of linesegs, indicating the visible walls that define // (all or some) sides of a convex BSP leaf. // -struct subsector_s +struct subsector_t { sector_t *sector; INT16 numlines; UINT16 firstline; - struct polyobj_s *polyList; // haleyjd 02/19/06: list of polyobjects + polyobj_t *polyList; // haleyjd 02/19/06: list of polyobjects size_t validcount; }; @@ -613,25 +610,25 @@ struct subsector_s // // For the links, NULL means top or end of list. -struct msecnode_s +struct msecnode_t { sector_t *m_sector; // a sector containing this object - struct mobj_s *m_thing; // this object - struct msecnode_s *m_sectorlist_prev; // prev msecnode_t for this thing - struct msecnode_s *m_sectorlist_next; // next msecnode_t for this thing - struct msecnode_s *m_thinglist_prev; // prev msecnode_t for this sector - struct msecnode_s *m_thinglist_next; // next msecnode_t for this sector + mobj_t *m_thing; // this object + msecnode_t *m_sectorlist_prev; // prev msecnode_t for this thing + msecnode_t *m_sectorlist_next; // next msecnode_t for this thing + msecnode_t *m_thinglist_prev; // prev msecnode_t for this sector + msecnode_t *m_thinglist_next; // next msecnode_t for this sector boolean visited; // used in search algorithms }; -struct mprecipsecnode_s +struct mprecipsecnode_t { sector_t *m_sector; // a sector containing this object - struct precipmobj_s *m_thing; // this object - struct mprecipsecnode_s *m_sectorlist_prev; // prev msecnode_t for this thing - struct mprecipsecnode_s *m_sectorlist_next; // next msecnode_t for this thing - struct mprecipsecnode_s *m_thinglist_prev; // prev msecnode_t for this sector - struct mprecipsecnode_s *m_thinglist_next; // next msecnode_t for this sector + precipmobj_t *m_thing; // this object + mprecipsecnode_t *m_sectorlist_prev; // prev msecnode_t for this thing + mprecipsecnode_t *m_sectorlist_next; // next msecnode_t for this thing + mprecipsecnode_t *m_thinglist_prev; // prev msecnode_t for this sector + mprecipsecnode_t *m_thinglist_next; // next msecnode_t for this sector boolean visited; // used in search algorithms }; @@ -653,17 +650,17 @@ struct light_t float dynamic_sqrradius; // radius^2 of the light ball }; -struct lightmap_s +struct lightmap_t { float s[2], t[2]; light_t *light; - struct lightmap_s *next; + lightmap_t *next; }; // // The lineseg. // -struct seg_s +struct seg_t { vertex_t *v1; vertex_t *v2; @@ -771,9 +768,9 @@ struct drawseg_t INT16 *sprbottomclip; INT16 *maskedtexturecol; - struct visplane_s *ffloorplanes[MAXFFLOORS]; + visplane_t *ffloorplanes[MAXFFLOORS]; INT32 numffloorplanes; - struct ffloor_s *thicksides[MAXFFLOORS]; + ffloor_t *thicksides[MAXFFLOORS]; INT16 *thicksidecol; INT32 numthicksides; fixed_t frontscale[MAXVIDWIDTH]; diff --git a/src/r_draw.c b/src/r_draw.c index 4b8eaf715..6eb5d6cfb 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -103,7 +103,7 @@ UINT8 *dc_transmap; // one of the translucency tables */ UINT8 *dc_translation; -struct r_lightlist_s *dc_lightlist = NULL; +struct r_lightlist_t *dc_lightlist = NULL; INT32 dc_numlights = 0, dc_maxlights, dc_texheight; // ========================================================================= diff --git a/src/r_draw.h b/src/r_draw.h index 130c44c00..aee8ecc5f 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -47,7 +47,7 @@ extern UINT8 *dc_transmap; extern UINT8 *dc_translation; -extern struct r_lightlist_s *dc_lightlist; +extern struct r_lightlist_t *dc_lightlist; extern INT32 dc_numlights, dc_maxlights; //Fix TUTIFRUTI diff --git a/src/r_plane.h b/src/r_plane.h index 1aa5f84e3..782691af6 100644 --- a/src/r_plane.h +++ b/src/r_plane.h @@ -28,9 +28,9 @@ // Now what is a visplane, anyway? // Simple: kinda floor/ceiling polygon optimised for SRB2 rendering. // -struct visplane_s +struct visplane_t { - struct visplane_s *next; + visplane_t *next; fixed_t height; fixed_t viewx, viewy, viewz; @@ -50,7 +50,7 @@ struct visplane_s fixed_t xoffs, yoffs; // Scrolling flats. - struct ffloor_s *ffloor; + ffloor_t *ffloor; polyobj_t *polyobj; pslope_t *slope; @@ -119,9 +119,9 @@ struct visffloor_t fixed_t f_pos_slope; fixed_t b_pos_slope; - struct pslope_s *slope; + pslope_t *slope; - struct ffloor_s *ffloor; + ffloor_t *ffloor; polyobj_t *polyobj; }; diff --git a/src/r_portal.h b/src/r_portal.h index 556faac8e..4f665f90b 100644 --- a/src/r_portal.h +++ b/src/r_portal.h @@ -20,9 +20,9 @@ /** Portal structure for the software renderer. */ -struct portal_s +struct portal_t { - struct portal_s *next; + portal_t *next; // Viewport. fixed_t viewx; diff --git a/src/r_things.h b/src/r_things.h index 06965c797..f27f3a7c9 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -145,14 +145,14 @@ typedef enum // A vissprite_t is a thing that will be drawn during a refresh, // i.e. a sprite object that is partly visible. -struct vissprite_s +struct vissprite_t { // Doubly linked list. - struct vissprite_s *prev; - struct vissprite_s *next; + vissprite_t *prev; + vissprite_t *next; // Bonus linkdraw pointer. - struct vissprite_s *linkdraw; + vissprite_t *linkdraw; mobj_t *mobj; // for easy access @@ -236,7 +236,7 @@ UINT8 *R_GetSpriteTranslation(vissprite_t *vis); // A drawnode is something that points to a 3D floor, 3D side, or masked // middle texture. This is used for sorting with sprites. -struct drawnode_s +struct drawnode_t { visplane_t *plane; drawseg_t *seg; @@ -244,8 +244,8 @@ struct drawnode_s ffloor_t *ffloor; vissprite_t *sprite; - struct drawnode_s *next; - struct drawnode_s *prev; + drawnode_t *next; + drawnode_t *prev; }; void R_InitDrawNodes(void); diff --git a/src/s_sound.h b/src/s_sound.h index d1a7ba25f..a3ad44750 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -170,13 +170,13 @@ boolean S_MusicInfo(char *mname, UINT16 *mflags, boolean *looping); boolean S_SpeedMusic(float speed); // Music credits -struct musicdef_s +struct musicdef_t { char name[7]; //char usage[256]; char source[256]; int volume; - struct musicdef_s *next; + musicdef_t *next; }; extern struct cursongcredit @@ -218,7 +218,7 @@ UINT32 S_GetMusicPosition(void); // Music Stacking (Jingles) // -struct musicstack_s +struct musicstack_t { char musname[7]; UINT16 musflags; @@ -229,8 +229,8 @@ struct musicstack_s lumpnum_t mlumpnum; boolean noposition; // force music stack resuming from zero (like music_stack_noposition) - struct musicstack_s *prev; - struct musicstack_s *next; + musicstack_t *prev; + musicstack_t *next; }; extern char music_stack_nextmusname[7]; diff --git a/src/screen.h b/src/screen.h index 6728f3762..d49f4aee2 100644 --- a/src/screen.h +++ b/src/screen.h @@ -91,9 +91,9 @@ struct vesa_extra_t }; // a video modes from the video modes list, // note: video mode 0 is always standard VGA320x200. -struct vmode_s +struct vmode_t { - struct vmode_s *pnext; + vmode_t *pnext; char *name; UINT32 width, height; UINT32 rowbytes; // bytes per scanline @@ -102,9 +102,9 @@ struct vmode_s INT32 numpages; vesa_extra_t *pextradata; // vesa mode extra data #ifdef _WIN32 - INT32 (WINAPI *setmode)(viddef_t *lvid, struct vmode_s *pcurrentmode); + INT32 (WINAPI *setmode)(viddef_t *lvid, vmode_t *pcurrentmode); #else - INT32 (*setmode)(viddef_t *lvid, struct vmode_s *pcurrentmode); + INT32 (*setmode)(viddef_t *lvid, vmode_t *pcurrentmode); #endif INT32 misc; // misc for display driver (r_opengl.dll etc) }; diff --git a/src/typedef.h b/src/typedef.h index 4bdddd18d..db751340c 100644 --- a/src/typedef.h +++ b/src/typedef.h @@ -23,7 +23,7 @@ TYPEDEF (fline_t); // command.h TYPEDEF (vsbuf_t); TYPEDEF (CV_PossibleValue_t); -TYPEDEF2 (consvar_s, consvar_t); +TYPEDEF (consvar_t); // d_netcmd.h TYPEDEF (changeteam_packet_t); @@ -31,13 +31,13 @@ TYPEDEF (changeteam_value_t); TYPEDEF (scheduleTask_t); // discord.h -TYPEDEF2 (discordRequest_s, discordRequest_t); +TYPEDEF (discordRequest_t); // d_player.h TYPEDEF (respawnvars_t); TYPEDEF (botvars_t); TYPEDEF (skybox_t); -TYPEDEF2 (player_s, player_t); +TYPEDEF (player_t); // d_clisrv.h TYPEDEF (clientcmd_pak); @@ -59,7 +59,7 @@ TYPEDEF (plrconfig); TYPEDEF (filesneededconfig_pak); TYPEDEF (doomdata_t); TYPEDEF (serverelem_t); -TYPEDEF2 (rewind_s, rewind_t); +TYPEDEF (rewind_t); // d_event.h TYPEDEF (event_t); @@ -67,10 +67,10 @@ TYPEDEF (event_t); // d_netfil.h TYPEDEF (fileneeded_t); TYPEDEF (HTTP_login); -TYPEDEF2 (luafiletransfer_s, luafiletransfer_t); +TYPEDEF (luafiletransfer_t); // d_think.h -TYPEDEF2 (thinker_s, thinker_t); +TYPEDEF (thinker_t); // d_ticcmd.h TYPEDEF (ticcmd_t); @@ -105,7 +105,7 @@ TYPEDEF (mappoint_t); TYPEDEF (customoption_t); TYPEDEF (mapheader_t); TYPEDEF (tolinfo_t); -TYPEDEF2 (cupheader_s, cupheader_t); +TYPEDEF (cupheader_t); // font.h TYPEDEF (font_t); @@ -142,7 +142,7 @@ TYPEDEF (mobjinfo_t); // k_bheap.h TYPEDEF (bheapitem_t); -TYPEDEF2 (bheap_s, bheap_t); +TYPEDEF (bheap_t); // k_boss.h TYPEDEF (weakspot_t); @@ -161,15 +161,15 @@ TYPEDEF (followercategory_t); TYPEDEF (trackingResult_t); // k_menu.h -TYPEDEF2 (menucolor_s, menucolor_t); +TYPEDEF (menucolor_t); TYPEDEF (menuitem_t); -TYPEDEF2 (menu_s, menu_t); +TYPEDEF (menu_t); TYPEDEF (menucmd_t); TYPEDEF (setup_player_t); TYPEDEF (modedesc_t); // k_pathfind.h -TYPEDEF2 (pathfindnode_s, pathfindnode_t); +TYPEDEF (pathfindnode_t); TYPEDEF (path_t); TYPEDEF (pathfindsetup_t); @@ -180,11 +180,11 @@ TYPEDEF (profile_t); TYPEDEF (t_splash_t); TYPEDEF (t_footstep_t); TYPEDEF (t_overlay_t); -TYPEDEF2 (terrain_s, terrain_t); +TYPEDEF (terrain_t); TYPEDEF (t_floor_t); // k_waypoint.h -TYPEDEF2 (waypoint_s, waypoint_t); +TYPEDEF (waypoint_t); // lua_hudlib_drawlist.h typedef struct huddrawlist_s *huddrawlist_h; @@ -200,7 +200,7 @@ TYPEDEF (extraemblem_t); TYPEDEF (unlockable_t); // m_dllist.h -TYPEDEF2 (mdllistitem_s, mdllistitem_t); +TYPEDEF (mdllistitem_t); // m_fixed.h TYPEDEF (vector2_t); @@ -212,7 +212,7 @@ TYPEDEF (ps_hookinfo_t); TYPEDEF (ps_botinfo_t); // m_queue.h -TYPEDEF2 (mqueueitem_s, mqueueitem_t); +TYPEDEF (mqueueitem_t); TYPEDEF (mqueue_t); // mserv.h @@ -231,12 +231,12 @@ TYPEDEF (divline_t); TYPEDEF (intercept_t); // p_mobj.h -TYPEDEF2 (mobj_s, mobj_t); -TYPEDEF2 (precipmobj_s, precipmobj_t); -TYPEDEF2 (actioncache_s, actioncache_t); +TYPEDEF (mobj_t); +TYPEDEF (precipmobj_t); +TYPEDEF (actioncache_t); // p_polyobj.h -TYPEDEF2 (polyobj_s, polyobj_t); +TYPEDEF (polyobj_t); TYPEDEF (polymaplink_t); TYPEDEF (polyrotate_t); TYPEDEF (polymove_t); @@ -312,19 +312,19 @@ TYPEDEF (softwarepatch_t); TYPEDEF (pic_t); TYPEDEF (spriteframe_t); TYPEDEF (spritedef_t); -TYPEDEF2 (extracolormap_s, extracolormap_t); -TYPEDEF2 (ffloor_s, ffloor_t); +TYPEDEF (extracolormap_t); +TYPEDEF (ffloor_t); TYPEDEF (lightlist_t); -TYPEDEF2 (r_lightlist_s, r_lightlist_t); -TYPEDEF2 (pslope_s, pslope_t); -TYPEDEF2 (sector_s, sector_t); -TYPEDEF2 (line_s, line_t); +TYPEDEF (r_lightlist_t); +TYPEDEF (pslope_t); +TYPEDEF (sector_t); +TYPEDEF (line_t); TYPEDEF (side_t); -TYPEDEF2 (subsector_s, subsector_t); -TYPEDEF2 (msecnode_s, msecnode_t); -TYPEDEF2 (mprecipsecnode_s, mprecipsecnode_t); -TYPEDEF2 (lightmap_s, lightmap_t); -TYPEDEF2 (seg_s, seg_t); +TYPEDEF (subsector_t); +TYPEDEF (msecnode_t); +TYPEDEF (mprecipsecnode_t); +TYPEDEF (lightmap_t); +TYPEDEF (seg_t); // r_draw.h TYPEDEF (floatv3_t); @@ -339,11 +339,11 @@ TYPEDEF (spriteframepivot_t); TYPEDEF (spriteinfo_t); // r_plane.h -TYPEDEF2 (visplane_s, visplane_t); +TYPEDEF (visplane_t); TYPEDEF (visffloor_t); // r_portal.h -TYPEDEF2 (portal_s, portal_t); +TYPEDEF (portal_t); // r_skins.h TYPEDEF (skin_t); @@ -360,20 +360,20 @@ TYPEDEF (texture_t); // r_things.h TYPEDEF (maskcount_t); -TYPEDEF2 (vissprite_s, vissprite_t); -TYPEDEF2 (drawnode_s, drawnode_t); +TYPEDEF (vissprite_t); +TYPEDEF (drawnode_t); // s_sound.h TYPEDEF (listener_t); TYPEDEF (channel_t); TYPEDEF (caption_t); -TYPEDEF2 (musicdef_s, musicdef_t); -TYPEDEF2 (musicstack_s, musicstack_t); +TYPEDEF (musicdef_t); +TYPEDEF (musicstack_t); // screen.h TYPEDEF (viddef_t); TYPEDEF (vesa_extra_t); -TYPEDEF2 (vmode_s, vmode_t); +TYPEDEF (vmode_t); // sounds.h TYPEDEF (sfxinfo_t); From 479f9e4d57b87d8c4529f11908dbe34d5fc314ae Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 27 Nov 2022 17:27:22 -0800 Subject: [PATCH 04/66] S_ReducedVFXSoundAtVolume: use player_t* --- src/s_sound.c | 4 ++-- src/s_sound.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/s_sound.c b/src/s_sound.c index a36b14bf6..fb21cc190 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -732,7 +732,7 @@ void S_StartSound(const void *origin, sfxenum_t sfx_id) S_StartSoundAtVolume(origin, sfx_id, 255); } -void S_ReducedVFXSoundAtVolume(const void *origin, sfxenum_t sfx_id, INT32 volume, void *owner) +void S_ReducedVFXSoundAtVolume(const void *origin, sfxenum_t sfx_id, INT32 volume, player_t *owner) { if (S_SoundDisabled()) return; @@ -744,7 +744,7 @@ void S_ReducedVFXSoundAtVolume(const void *origin, sfxenum_t sfx_id, INT32 volum return; } - if (P_IsDisplayPlayer((player_t *)owner) == false) + if (P_IsDisplayPlayer(owner) == false) { return; } diff --git a/src/s_sound.h b/src/s_sound.h index a3ad44750..adbf92533 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -140,7 +140,7 @@ void S_StartSound(const void *origin, sfxenum_t sound_id); void S_StartSoundAtVolume(const void *origin, sfxenum_t sound_id, INT32 volume); // Will start a sound, but only if VFX reduce is off or the owner isn't a display player. -void S_ReducedVFXSoundAtVolume(const void *origin, sfxenum_t sfx_id, INT32 volume, void *owner); +void S_ReducedVFXSoundAtVolume(const void *origin, sfxenum_t sfx_id, INT32 volume, player_t *owner); #define S_ReducedVFXSound(a, b, c) S_ReducedVFXSoundAtVolume(a, b, 255, c) // Stop sound for thing at From 7b0361a6f25f33dbd7cb226a4218c4952dc9e2ad Mon Sep 17 00:00:00 2001 From: SteelT Date: Mon, 28 Nov 2022 23:05:54 -0500 Subject: [PATCH 05/66] Make vsync default to off --- src/sdl/i_video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 5e97694ad..5cea8c65a 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -108,7 +108,7 @@ boolean highcolor = false; // synchronize page flipping with screen refresh -consvar_t cv_vidwait = CVAR_INIT ("vid_wait", "On", CV_SAVE, CV_OnOff, NULL); +consvar_t cv_vidwait = CVAR_INIT ("vid_wait", "Off", CV_SAVE, CV_OnOff, NULL); static consvar_t cv_stretch = CVAR_INIT ("stretch", "Off", CV_SAVE|CV_NOSHOWHELP, CV_OnOff, NULL); static consvar_t cv_alwaysgrabmouse = CVAR_INIT ("alwaysgrabmouse", "Off", CV_SAVE, CV_OnOff, NULL); From ef442e06b7085de75f67a88f0635de6dc2027dd4 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 28 Nov 2022 22:02:33 -0800 Subject: [PATCH 06/66] cmake: let SRB2_SDL2_EXE_NAME override git branch SRB2_SDL2_EXE_NAME is now "" by default. Internally defaults to ringracers. --- CMakeLists.txt | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c6cd6c3d4..10c65a167 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -150,7 +150,7 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin") set(CMAKE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin") # Set EXE names so the assets CMakeLists can refer to its target -set(SRB2_SDL2_EXE_NAME ringracers CACHE STRING "Executable binary output name") +set(SRB2_SDL2_EXE_NAME "" CACHE STRING "Override executable binary output name") set(SRB2_SDL2_EXE_SUFFIX "" CACHE STRING "Optional executable suffix, separated by an underscore") include_directories(${CMAKE_CURRENT_BINARY_DIR}/src) @@ -170,10 +170,16 @@ set(SRB2_COMP_REVISION "${SRB2_COMP_COMMIT}") configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/src/config.h) -list(APPEND EXE_NAME_PARTS ${SRB2_SDL2_EXE_NAME}) -if(NOT "${SRB2_GIT_BRANCH}" STREQUAL "master") - list(APPEND EXE_NAME_PARTS ${SRB2_GIT_BRANCH}) +if("${SRB2_SDL2_EXE_NAME}" STREQUAL "") + list(APPEND EXE_NAME_PARTS "ringracers") + + if(NOT "${SRB2_GIT_BRANCH}" STREQUAL "master") + list(APPEND EXE_NAME_PARTS ${SRB2_GIT_BRANCH}) + endif() +else() + list(APPEND EXE_NAME_PARTS ${SRB2_SDL2_EXE_NAME}) endif() + list(APPEND EXE_NAME_PARTS ${SRB2_SDL2_EXE_SUFFIX}) list(JOIN EXE_NAME_PARTS "_" EXE_NAME) From 3d500148cd3ac455bc213f9edd219ff269b50336 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 29 Nov 2022 16:54:31 -0800 Subject: [PATCH 07/66] Make Test Run the default map in DEVELOP builds This makes testing easy by starting the game with -server --- src/d_main.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/d_main.c b/src/d_main.c index bd63cd874..e3230d81e 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1203,7 +1203,11 @@ D_ConvertVersionNumbers (void) void D_SRB2Main(void) { INT32 i, p; - INT32 pstartmap = 0; +#ifdef DEVELOP + INT32 pstartmap = 1; // default to first loaded map (Test Run) +#else + INT32 pstartmap = 0; // default to random map (0 is not a valid map number) +#endif boolean autostart = false; /* break the version string into version numbers, for netplay */ From 7794f0956e5787255e30445f0b7b8bbe31f1c148 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 2 Dec 2022 00:27:34 -0500 Subject: [PATCH 08/66] Reset pitch/roll on springs + trick panels --- src/k_kart.c | 3 +++ src/p_user.c | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/src/k_kart.c b/src/k_kart.c index 15cd34b9a..8297317f2 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -6658,6 +6658,9 @@ void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, UINT8 sound) mo->momz = FixedDiv(mo->momz, FixedSqrt(3*FRACUNIT)); } + mo->pitch = 0; + mo->roll = 0; + if (sound) { S_StartSound(mo, (sound == 1 ? sfx_kc2f : sfx_kpogos)); diff --git a/src/p_user.c b/src/p_user.c index 7d21578dd..57f4b2af9 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -478,6 +478,12 @@ void P_ResetPlayer(player_t *player) player->trickpanel = 0; player->glanceDir = 0; player->fastfall = 0; + + if (player->mo != NULL && P_MobjWasRemoved(player->mo) == false) + { + player->mo->pitch = 0; + player->mo->roll = 0; + } } // From dbedd662590446e13016996ed53b142d2f97fe43 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 2 Dec 2022 02:01:02 -0500 Subject: [PATCH 09/66] Fix solid midtextures UDMF's ML_MIDPEG == Binary's (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_MIDPEG)). This is converted in P_ConvertBinaryLinedefFlags --- src/p_maputl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_maputl.c b/src/p_maputl.c index 7eb4a7e19..e1ceeb0fe 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -534,7 +534,7 @@ P_GetMidtextureTopBottom texbottom = back->floorheight + side->rowoffset; textop = back->ceilingheight + side->rowoffset; } - else if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_MIDPEG)) + else if (linedef->flags & ML_MIDPEG) { texbottom = back->floorheight + side->rowoffset; textop = texbottom + texheight*(side->repeatcnt+1); @@ -553,7 +553,7 @@ P_GetMidtextureTopBottom texbottom += side->rowoffset; textop += side->rowoffset; } - else if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_MIDPEG)) + else if (linedef->flags & ML_MIDPEG) { texbottom += side->rowoffset; textop = texbottom + texheight*(side->repeatcnt+1); From b62ed336551aaa6fe2e444be0164e944123ac723 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 2 Dec 2022 03:56:15 -0500 Subject: [PATCH 10/66] Fix Battle mode Egg Capsules bumping Old vanilla-ass code for platform-like objects that is conflicting super hard with bumping / horizontal momentum. If we ever have a moving platform object this code should be brought back only for that object, and not solid objects as a whole. --- src/p_map.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/p_map.c b/src/p_map.c index cb5d030a2..c7047bcde 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1464,6 +1464,11 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing) } } + // This code is causing conflicts for Ring Racers, + // as solid objects cause bumping. If you need to + // bring back this code for a moving platform-style + // object, separate it properly. +#if 0 if ((tm.thing->flags & MF_SPRING || tm.thing->type == MT_STEAM || tm.thing->type == MT_SPIKE || tm.thing->type == MT_WALLSPIKE) && (thing->player)) ; // springs, gas jets and springs should never be able to step up onto a player // z checking at last @@ -1562,6 +1567,7 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing) } } } +#endif // not solid not blocked return BMIT_CONTINUE; From bdbd79dd4109772694acd4eeeed90d5c629a1bb9 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 2 Dec 2022 04:12:04 -0500 Subject: [PATCH 11/66] Fix Egg Capsule interp --- src/p_mobj.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 0613d816c..91fbbfa52 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9156,9 +9156,9 @@ static boolean P_MobjRegularThink(mobj_t *mobj) // Move each piece to the proper position while (cur && !P_MobjWasRemoved(cur)) { - fixed_t newx = mobj->x; - fixed_t newy = mobj->y; - fixed_t newz = bottom; + fixed_t newx = mobj->x + mobj->momx; + fixed_t newy = mobj->y + mobj->momy; + fixed_t newz = bottom + mobj->momz; statenum_t state = (statenum_t)(cur->state-states); cur->scale = mobj->scale; @@ -9202,7 +9202,9 @@ static boolean P_MobjRegularThink(mobj_t *mobj) cur->angle = angle + ANGLE_90; } - P_MoveOrigin(cur, newx, newy, newz); + cur->momx = newx - cur->x; + cur->momy = newy - cur->y; + cur->momz = newz - cur->z; cur = cur->hnext; } From e8e02058ef1aee030335b45c2f26435d04aad6bc Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 2 Dec 2022 04:21:23 -0500 Subject: [PATCH 12/66] Bigger Egg Capsule hitbox --- src/info.c | 4 ++-- src/p_mobj.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/info.c b/src/info.c index 3824731d1..dcf6a9f65 100644 --- a/src/info.c +++ b/src/info.c @@ -28661,8 +28661,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 28<radius; - fixed_t offy = mobj->radius; + fixed_t offx = 28 * mobj->scale; + fixed_t offy = 28 * mobj->scale; if (cur->extravalue1 & 1) offx = -offx; From d6bd869b9212a51cef3280f0d295f767eada70ca Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 3 Dec 2022 03:08:44 -0500 Subject: [PATCH 13/66] Give Egg Capsules drop shadows --- src/info.c | 2 +- src/p_mobj.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/info.c b/src/info.c index dcf6a9f65..61af1efeb 100644 --- a/src/info.c +++ b/src/info.c @@ -28646,7 +28646,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = { // MT_BATTLECAPSULE 2333, // doomednum - S_INVISIBLE, // spawnstate + S_SHADOW, // spawnstate 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound diff --git a/src/p_mobj.c b/src/p_mobj.c index caf725e26..78d27e96a 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9998,6 +9998,7 @@ static void P_DefaultMobjShadowScale(mobj_t *thing) { case MT_PLAYER: case MT_KART_LEFTOVER: + case MT_BATTLECAPSULE: thing->shadowscale = FRACUNIT; break; case MT_SMALLMACE: From 226cb7d736b6a4b134feddb93da16a26ecd47a8f Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 3 Dec 2022 04:25:34 -0500 Subject: [PATCH 14/66] Update capsule parts - The pieces do the positioning, instead of the capsule itself. This makes it so that the parts update after the capsule has applied its momentum. - Use proper inradius instead, so the sides line up. - Because of the above change, the capsule as a whole is bigger. This means... - Increased hitbox again - Changed a few of the sprites --- src/info.c | 2 +- src/p_mobj.c | 171 +++++++++++++++++++++++++++++++-------------------- 2 files changed, 107 insertions(+), 66 deletions(-) diff --git a/src/info.c b/src/info.c index 61af1efeb..ae5bce736 100644 --- a/src/info.c +++ b/src/info.c @@ -28661,7 +28661,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 56<extravalue2) + { mobj->frame |= FF_VERTICALFLIP; + } else + { mobj->frame &= ~FF_VERTICALFLIP; + } if (mobj->flags2 & MF2_OBJECTFLIP) + { mobj->eflags |= MFE_VERTICALFLIP; + } if (mobj->tics > 0) + { + // Despawning. mobj->renderflags ^= RF_DONTDRAW; + } + else + { + statenum_t state = (statenum_t)(mobj->state - states); + mobj_t *owner = mobj->target; + fixed_t newx, newy, newz; + SINT8 flip; + + if (owner == NULL || P_MobjWasRemoved(owner) == true) + { + // Exit early. + break; + } + + newx = owner->x; + newy = owner->y; + newz = P_GetMobjFeet(owner); + + flip = P_MobjFlip(owner); // Flying capsules needs flipped sprites, but not flipped gravity + if (owner->extravalue1) + { + flip = -flip; + newz += owner->height; + } + + mobj->scale = owner->scale; + mobj->destscale = owner->destscale; + mobj->scalespeed = owner->scalespeed; + + mobj->extravalue2 = owner->extravalue1; + + mobj->flags2 = (mobj->flags2 & ~MF2_OBJECTFLIP) | (owner->flags2 & MF2_OBJECTFLIP); + + switch (state) + { + case S_BATTLECAPSULE_TOP: + { + newz += (80 * owner->scale * flip); + break; + } + + case S_BATTLECAPSULE_BUTTON: + { + newz += (120 * owner->scale * flip); + break; + } + + case S_BATTLECAPSULE_SUPPORT: + case S_BATTLECAPSULE_SUPPORTFLY: + case S_KARMAWHEEL: + { + fixed_t offx = 36 * owner->scale; + fixed_t offy = 36 * owner->scale; + + if (mobj->extravalue1 & 1) + { + offx = -offx; + } + + if (mobj->extravalue1 > 1) + { + offy = -offy; + } + + newx += offx; + newy += offy; + break; + } + + case S_BATTLECAPSULE_SIDE1: + case S_BATTLECAPSULE_SIDE2: + { +#define inradius 3797355 // Precalculated +#ifndef inradius + fixed_t inradius = FixedDiv(48 << FRACBITS, 2 * FINETANGENT((((ANGLE_180 / 8) + ANGLE_90) >> ANGLETOFINESHIFT) & 4095)); +#endif + fixed_t offset = FixedMul(inradius, owner->scale); + angle_t angle = (ANGLE_45 * mobj->extravalue1); + + newx += FixedMul(offset, FINECOSINE(angle >> ANGLETOFINESHIFT)); + newy += FixedMul(offset, FINESINE(angle >> ANGLETOFINESHIFT)); + newz += (12 * owner->scale * flip); + + mobj->angle = angle + ANGLE_90; + break; +#undef inradius + } + + default: + { + break; + } + } + + mobj->momx = newx - mobj->x; + mobj->momy = newy - mobj->y; + mobj->momz = newz - mobj->z; + } break; case MT_SPINDASHWIND: case MT_DRIFTELECTRICSPARK: @@ -9039,8 +9145,6 @@ static boolean P_MobjRegularThink(mobj_t *mobj) { SINT8 realflip = P_MobjFlip(mobj); SINT8 flip = realflip; // Flying capsules needs flipped sprites, but not flipped gravity - fixed_t bottom; - mobj_t *cur; if (mobj->extravalue1) { @@ -9145,69 +9249,6 @@ static boolean P_MobjRegularThink(mobj_t *mobj) } } } - - if (flip == -1) - bottom = mobj->z + mobj->height; - else - bottom = mobj->z; - - cur = mobj->hnext; - - // Move each piece to the proper position - while (cur && !P_MobjWasRemoved(cur)) - { - fixed_t newx = mobj->x + mobj->momx; - fixed_t newy = mobj->y + mobj->momy; - fixed_t newz = bottom + mobj->momz; - statenum_t state = (statenum_t)(cur->state-states); - - cur->scale = mobj->scale; - cur->destscale = mobj->destscale; - cur->scalespeed = mobj->scalespeed; - - cur->extravalue2 = mobj->extravalue1; - - cur->flags2 = (cur->flags2 & ~MF2_OBJECTFLIP)|(mobj->flags2 & MF2_OBJECTFLIP); - - if (state == S_BATTLECAPSULE_TOP) - newz += (80 * mobj->scale * flip); - else if (state == S_BATTLECAPSULE_BUTTON) - newz += (108 * mobj->scale * flip); - else if (state == S_BATTLECAPSULE_SUPPORT - || state == S_BATTLECAPSULE_SUPPORTFLY - || state == S_KARMAWHEEL) - { - fixed_t offx = 28 * mobj->scale; - fixed_t offy = 28 * mobj->scale; - - if (cur->extravalue1 & 1) - offx = -offx; - - if (cur->extravalue1 > 1) - offy = -offy; - - newx += offx; - newy += offy; - } - else if (state == S_BATTLECAPSULE_SIDE1 - || state == S_BATTLECAPSULE_SIDE2) - { - fixed_t offset = 48 * mobj->scale; - angle_t angle = (ANGLE_45 * cur->extravalue1); - - newx += FixedMul(offset, FINECOSINE(angle >> ANGLETOFINESHIFT)); - newy += FixedMul(offset, FINESINE(angle >> ANGLETOFINESHIFT)); - newz += (12 * mobj->scale * flip); - - cur->angle = angle + ANGLE_90; - } - - cur->momx = newx - cur->x; - cur->momy = newy - cur->y; - cur->momz = newz - cur->z; - - cur = cur->hnext; - } } break; case MT_RANDOMITEM: From 2140c2f6162d42aa75be8ed8f764d7a68f4ec998 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 3 Dec 2022 04:45:59 -0500 Subject: [PATCH 15/66] Use P1-4 starts in Capsules Attack / Bonus Stage Rather than randomized Battle starts. --- src/g_game.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/g_game.c b/src/g_game.c index fe73d8ae6..5cde2d270 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2824,6 +2824,11 @@ mapthing_t *G_FindMapStart(INT32 playernum) spawnpoint = G_FindRaceStartOrFallback(playernum); } + // -- Grand Prix / Time Attack -- + // Order: Race->DM->CTF + else if (grandprixinfo.gp || modeattacking) + spawnpoint = G_FindRaceStartOrFallback(playernum); + // -- CTF -- // Order: CTF->DM->Race else if ((gametyperules & GTR_TEAMSTARTS) && players[playernum].ctfteam) From 7b2095f6a5f40bc7dc1833372a89a9a6cdc2feb6 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 29 Nov 2022 01:59:17 -0800 Subject: [PATCH 16/66] Scale player weight buff from speed to mobjscale --- src/k_kart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/k_kart.c b/src/k_kart.c index 15cd34b9a..42ee7af53 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -1508,7 +1508,7 @@ static fixed_t K_PlayerWeight(mobj_t *mobj, mobj_t *against) weight = (mobj->player->kartweight) * FRACUNIT; if (mobj->player->speed > spd) - weight += (mobj->player->speed - spd) / 8; + weight += FixedDiv((mobj->player->speed - spd), 8 * mapobjectscale); if (mobj->player->itemtype == KITEM_BUBBLESHIELD) weight += 9*FRACUNIT; From abdb2e3ac38a30807c8d13dcbdc3fa2049b1e29f Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 1 Dec 2022 20:39:53 -0800 Subject: [PATCH 17/66] Set Lightning Shield attack to DMG_VOLTAGE --- src/deh_tables.c | 1 + src/k_collide.c | 2 +- src/p_inter.c | 1 + src/p_local.h | 1 + 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/deh_tables.c b/src/deh_tables.c index a36b7af9d..ab0ef138b 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -6369,6 +6369,7 @@ struct int_const_s const INT_CONST[] = { {"DMG_TUMBLE",DMG_TUMBLE}, {"DMG_STING",DMG_STING}, {"DMG_KARMA",DMG_KARMA}, + {"DMG_VOLTAGE",DMG_VOLTAGE}, //// Death types {"DMG_INSTAKILL",DMG_INSTAKILL}, {"DMG_DEATHPIT",DMG_DEATHPIT}, diff --git a/src/k_collide.c b/src/k_collide.c index 6a67e5a04..dac44b5f7 100644 --- a/src/k_collide.c +++ b/src/k_collide.c @@ -625,7 +625,7 @@ static inline BlockItReturn_t PIT_LightningShieldAttack(mobj_t *thing) } #endif - P_DamageMobj(thing, lightningSource, lightningSource, 1, DMG_NORMAL|DMG_CANTHURTSELF|DMG_WOMBO); + P_DamageMobj(thing, lightningSource, lightningSource, 1, DMG_VOLTAGE|DMG_CANTHURTSELF|DMG_WOMBO); return BMIT_CONTINUE; } diff --git a/src/p_inter.c b/src/p_inter.c index e77a5d8ff..76757f193 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2180,6 +2180,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da K_SpinPlayer(player, inflictor, source, KSPIN_WIPEOUT); K_KartPainEnergyFling(player); break; + case DMG_VOLTAGE: case DMG_NORMAL: default: K_SpinPlayer(player, inflictor, source, KSPIN_SPINOUT); diff --git a/src/p_local.h b/src/p_local.h index e547bc7b4..d9486e8b7 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -516,6 +516,7 @@ struct BasicFF_t #define DMG_TUMBLE 0x03 #define DMG_STING 0x04 #define DMG_KARMA 0x05 // Karma Bomb explosion -- works like DMG_EXPLODE, but steals half of their bumpers & deletes the rest +#define DMG_VOLTAGE 0x06 //// Death types - cannot be combined with damage types #define DMG_INSTAKILL 0x80 #define DMG_DEATHPIT 0x81 From 3bc359e29865252f9d7c20ddd2b5230b9ca97f69 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 1 Dec 2022 21:00:49 -0800 Subject: [PATCH 18/66] Mobj scale explosions smoldering rising momentum --- src/p_mobj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 0613d816c..ace1a7c22 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -5886,7 +5886,7 @@ static void P_MobjSceneryThink(mobj_t *mobj) K_MatchGenericExtraFlags(smoke, mobj); smoke->scale = mobj->scale * 2; smoke->destscale = mobj->scale * 6; - smoke->momz = P_RandomRange(PR_SMOLDERING, 4, 9)*FRACUNIT*P_MobjFlip(smoke); + smoke->momz = P_RandomRange(PR_SMOLDERING, 4, 9)*mobj->scale*P_MobjFlip(smoke); } break; case MT_BOOMPARTICLE: From cbb1f3c714a8c3b929ac81f6a33e70ce3d30781a Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 3 Dec 2022 03:33:49 -0800 Subject: [PATCH 19/66] Fix NULL lump name guard for W_CheckNumForName --- src/w_wad.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/w_wad.c b/src/w_wad.c index fb828cf81..cef5615cc 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -1202,7 +1202,7 @@ UINT16 W_CheckNumForFullNamePK3(const char *name, UINT16 wad, UINT16 startlump) lumpnum_t W_CheckNumForName(const char *name) { lumpnum_t check = INT16_MAX; - UINT32 hash = quickncasehash(name, 8); + UINT32 hash = name ? quickncasehash(name, 8) : 0; INT32 i; if (name == NULL) @@ -1258,7 +1258,7 @@ lumpnum_t W_CheckNumForName(const char *name) lumpnum_t W_CheckNumForLongName(const char *name) { lumpnum_t check = INT16_MAX; - UINT32 hash = quickncasehash(name, LUMPNUMCACHENAME); + UINT32 hash = name ? quickncasehash(name, LUMPNUMCACHENAME) : 0; INT32 i; if (name == NULL) From 90a4159acd00cb8b625b5accd12c18ff830cafeb Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 5 Dec 2022 13:45:26 -0800 Subject: [PATCH 20/66] Add IMON sprite definition --- src/info.c | 1 + src/info.h | 1 + 2 files changed, 2 insertions(+) diff --git a/src/info.c b/src/info.c index 3824731d1..f4a17b28b 100644 --- a/src/info.c +++ b/src/info.c @@ -543,6 +543,7 @@ char sprnames[NUMSPRITES + 1][5] = "KINF", // Invincibility flash "INVI", // Invincibility speedlines "ICAP", // Item capsules + "IMON", // Item Monitor "MGBX", // Heavy Magician transform box "MGBT", // Heavy Magician transform box top "MGBB", // Heavy Magician transform box bottom diff --git a/src/info.h b/src/info.h index 4425b4dc8..35a050011 100644 --- a/src/info.h +++ b/src/info.h @@ -1089,6 +1089,7 @@ typedef enum sprite SPR_KINF, // Invincibility flash SPR_INVI, // Invincibility speedlines SPR_ICAP, // Item capsules + SPR_IMON, // Item Monitor SPR_MGBX, // Heavy Magician transform box SPR_MGBT, // Heavy Magician transform box top SPR_MGBB, // Heavy Magician transform box bottom From b95a18676ff83a3b334bb838122bd63880f3071b Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 11 Dec 2022 13:53:51 -0500 Subject: [PATCH 21/66] Clipping rectangle Instead of the absolute insanity that is V_DrawCroppedPatch, which makes you specify the number of pixels to crop off the top/left and then the number of pixels to show after the crop ... you just use V_SetClipRect to create a rectangle for any future draws to be cropped down to, and V_ClearClipRect afterwards to clear it. Currently only supported by V_DrawStretchyFixedPatch. Ideally other drawing functions should also receive clipping rectangle support too. --- src/hardware/hw_draw.c | 6 +- src/k_hud.c | 115 +------------ src/k_hud.h | 2 - src/typedef.h | 1 + src/v_video.c | 381 ++++++++++++++++++++++++++++------------- src/v_video.h | 13 ++ 6 files changed, 286 insertions(+), 232 deletions(-) diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index b5268986b..56890382f 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -207,7 +207,7 @@ void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t p INT32 intx, inty; intx = (INT32)cx; inty = (INT32)cy; - K_AdjustXYWithSnap(&intx, &inty, option, dupx, dupy); + V_AdjustXYWithSnap(&intx, &inty, option, dupx, dupy); cx = (float)intx; cy = (float)inty; } @@ -1011,7 +1011,7 @@ void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color, UINT32 intx = (INT32)fx; inty = (INT32)fy; - K_AdjustXYWithSnap(&intx, &inty, color, dupx, dupy); + V_AdjustXYWithSnap(&intx, &inty, color, dupx, dupy); fx = (float)intx; fy = (float)inty; } @@ -1102,7 +1102,7 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color) intx = (INT32)fx; inty = (INT32)fy; - K_AdjustXYWithSnap(&intx, &inty, color, dupx, dupy); + V_AdjustXYWithSnap(&intx, &inty, color, dupx, dupy); fx = (float)intx; fy = (float)inty; } diff --git a/src/k_hud.c b/src/k_hud.c index 5325f07eb..543a7a9e7 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -762,117 +762,6 @@ INT32 POSI2_X, POSI2_Y; // trick "cool" INT32 TCOOL_X, TCOOL_Y; - -void K_AdjustXYWithSnap(INT32 *x, INT32 *y, UINT32 options, INT32 dupx, INT32 dupy) -{ - // dupx adjustments pretend that screen width is BASEVIDWIDTH * dupx - INT32 screenwidth = vid.width; - INT32 screenheight = vid.height; - INT32 basewidth = BASEVIDWIDTH * dupx; - INT32 baseheight = BASEVIDHEIGHT * dupy; - SINT8 player = -1; - UINT8 i; - - if (options & V_SPLITSCREEN) - { - if (r_splitscreen > 0) - { - screenheight /= 2; - baseheight /= 2; - } - - if (r_splitscreen > 1) - { - screenwidth /= 2; - basewidth /= 2; - } - } - - for (i = 0; i <= r_splitscreen; i++) - { - if (stplyr == &players[displayplayers[i]]) - { - player = i; - break; - } - } - - if (vid.width != (BASEVIDWIDTH * dupx)) - { - if (options & V_SNAPTORIGHT) - *x += (screenwidth - basewidth); - else if (!(options & V_SNAPTOLEFT)) - *x += (screenwidth - basewidth) / 2; - } - - if (vid.height != (BASEVIDHEIGHT * dupy)) - { - if (options & V_SNAPTOBOTTOM) - *y += (screenheight - baseheight); - else if (!(options & V_SNAPTOTOP)) - *y += (screenheight - baseheight) / 2; - } - - if (options & V_SPLITSCREEN) - { - if (r_splitscreen == 1) - { - if (player == 1) - *y += screenheight; - } - else if (r_splitscreen > 1) - { - if (player == 1 || player == 3) - *x += screenwidth; - - if (player == 2 || player == 3) - *y += screenheight; - } - } - - if (options & V_SLIDEIN) - { - const tic_t length = TICRATE/4; - tic_t timer = lt_exitticker; - if (bossinfo.boss == true) - { - if (leveltime <= 3) - timer = 0; - else - timer = leveltime-3; - } - - if (timer < length) - { - boolean slidefromright = false; - - const INT32 offsetAmount = (screenwidth * FRACUNIT/2) / length; - fixed_t offset = (screenwidth * FRACUNIT/2) - (timer * offsetAmount); - - offset += FixedMul(offsetAmount, renderdeltatics); - offset /= FRACUNIT; - - if (r_splitscreen > 1) - { - if (stplyr == &players[displayplayers[1]] || stplyr == &players[displayplayers[3]]) - slidefromright = true; - } - - if (options & V_SNAPTORIGHT) - slidefromright = true; - else if (options & V_SNAPTOLEFT) - slidefromright = false; - - if (slidefromright == true) - { - offset = -offset; - } - - *x -= offset; - } - } -} - // This version of the function was prototyped in Lua by Nev3r ... a HUGE thank you goes out to them! void K_ObjectTracking(trackingResult_t *result, vector3_t *point, boolean reverse) { @@ -1301,6 +1190,8 @@ static void K_drawKartItem(void) V_DrawScaledPatch(fx, fy, V_HUDTRANS|V_SLIDEIN|fflags, localbg); + V_SetClipRect((fx + 10) << FRACBITS, (fy + 10) << FRACBITS, 30 << FRACBITS, 30 << FRACBITS, V_HUDTRANS|V_SLIDEIN|fflags); + // Then, the numbers: if (stplyr->itemamount >= numberdisplaymin && !stplyr->itemroulette) { @@ -1320,6 +1211,8 @@ static void K_drawKartItem(void) else V_DrawFixedPatch(fx< 0) + { + screenheight /= 2; + baseheight /= 2; + } + + if (r_splitscreen > 1) + { + screenwidth /= 2; + basewidth /= 2; + } + } + + for (i = 0; i <= r_splitscreen; i++) + { + if (stplyr == &players[displayplayers[i]]) + { + player = i; + break; + } + } + + if (vid.width != (BASEVIDWIDTH * dupx)) + { + if (options & V_SNAPTORIGHT) + *x += (screenwidth - basewidth); + else if (!(options & V_SNAPTOLEFT)) + *x += (screenwidth - basewidth) / 2; + } + + if (vid.height != (BASEVIDHEIGHT * dupy)) + { + if (options & V_SNAPTOBOTTOM) + *y += (screenheight - baseheight); + else if (!(options & V_SNAPTOTOP)) + *y += (screenheight - baseheight) / 2; + } + + if (options & V_SPLITSCREEN) + { + if (r_splitscreen == 1) + { + if (player == 1) + *y += screenheight; + } + else if (r_splitscreen > 1) + { + if (player == 1 || player == 3) + *x += screenwidth; + + if (player == 2 || player == 3) + *y += screenheight; + } + } + + if (options & V_SLIDEIN) + { + const tic_t length = TICRATE/4; + tic_t timer = lt_exitticker; + if (bossinfo.boss == true) + { + if (leveltime <= 3) + timer = 0; + else + timer = leveltime-3; + } + + if (timer < length) + { + boolean slidefromright = false; + + const INT32 offsetAmount = (screenwidth * FRACUNIT/2) / length; + fixed_t offset = (screenwidth * FRACUNIT/2) - (timer * offsetAmount); + + offset += FixedMul(offsetAmount, renderdeltatics); + offset /= FRACUNIT; + + if (r_splitscreen > 1) + { + if (stplyr == &players[displayplayers[1]] || stplyr == &players[displayplayers[3]]) + slidefromright = true; + } + + if (options & V_SNAPTORIGHT) + slidefromright = true; + else if (options & V_SNAPTOLEFT) + slidefromright = false; + + if (slidefromright == true) + { + offset = -offset; + } + + *x -= offset; + } + } +} + +static cliprect_t cliprect; + +cliprect_t *V_GetClipRect(void) +{ + if (cliprect.enabled == false) + { + return NULL; + } + + return &cliprect; +} + +void V_SetClipRect(fixed_t x, fixed_t y, fixed_t w, fixed_t h, INT32 flags) +{ + // Adjust position. + if (!(flags & V_NOSCALESTART)) + { + fixed_t dupx = vid.dupx; + fixed_t dupy = vid.dupy; + + if (flags & V_SCALEPATCHMASK) + { + switch ((flags & V_SCALEPATCHMASK) >> V_SCALEPATCHSHIFT) + { + case 1: // V_NOSCALEPATCH + dupx = dupy = 1; + break; + case 2: // V_SMALLSCALEPATCH + dupx = vid.smalldupx; + dupy = vid.smalldupy; + break; + case 3: // V_MEDSCALEPATCH + dupx = vid.meddupx; + dupy = vid.meddupy; + break; + default: + break; + } + } + + dupx = dupy = (dupx < dupy ? dupx : dupy); + + x = FixedMul(x, dupx); + y = FixedMul(y, dupy); + w = FixedMul(w, dupx); + h = FixedMul(h, dupy); + + if (!(flags & V_SCALEPATCHMASK)) + { + V_AdjustXYWithSnap(&x, &y, flags, dupx, dupy); + } + } + + if (x < 0) + { + w += x; + x = 0; + } + + if (y < 0) + { + h += y; + y = 0; + } + + if (x > vid.width) + { + x = vid.width; + w = 0; + } + + if (y > vid.height) + { + y = vid.height; + h = 0; + } + + cliprect.l = x; + cliprect.t = y; + cliprect.r = x + w; + cliprect.b = y + h; + cliprect.flags = flags; + cliprect.enabled = true; + + /* + V_DrawFill(cliprect.l, cliprect.t, cliprect.r - cliprect.l, cliprect.b - cliprect.t, V_NOSCALESTART); + CONS_Printf("[(%d, %d), (%d, %d)]\n", cliprect.l, cliprect.t, cliprect.r, cliprect.b); + */ +} + +void V_ClearClipRect(void) +{ + cliprect.enabled = false; +} + static UINT8 hudplusalpha[11] = { 10, 8, 6, 4, 2, 0, 0, 0, 0, 0, 0}; static UINT8 hudminusalpha[11] = { 10, 9, 9, 8, 8, 7, 7, 6, 6, 5, 5}; @@ -554,6 +760,8 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca fixed_t pwidth; // patch width fixed_t offx = 0; // x offset + cliprect_t *const clip = V_GetClipRect(); + if (rendermode == render_none) return; @@ -662,7 +870,7 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca // Center it if necessary if (!(scrn & V_SCALEPATCHMASK)) { - K_AdjustXYWithSnap(&x, &y, scrn, dupx, dupy); + V_AdjustXYWithSnap(&x, &y, scrn, dupx, dupy); } desttop += (y*vid.width) + x; @@ -684,18 +892,19 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca for (col = 0; (col>>FRACBITS) < patch->width; col += colfrac, ++offx, desttop++) { INT32 topdelta, prevdelta = -1; + if (scrn & V_FLIP) // offx is measured from right edge instead of left { - if (x+pwidth-offx < 0) // don't draw off the left of the screen (WRAP PREVENTION) + if (x+pwidth-offx < (clip ? clip->l : 0)) // don't draw off the left of the screen (WRAP PREVENTION) break; - if (x+pwidth-offx >= vid.width) // don't draw off the right of the screen (WRAP PREVENTION) + if (x+pwidth-offx >= (clip ? clip->r : vid.width)) // don't draw off the right of the screen (WRAP PREVENTION) continue; } else { - if (x+offx < 0) // don't draw off the left of the screen (WRAP PREVENTION) + if (x+offx < (clip ? clip->l : 0)) // don't draw off the left of the screen (WRAP PREVENTION) continue; - if (x+offx >= vid.width) // don't draw off the right of the screen (WRAP PREVENTION) + if (x+offx >= (clip ? clip->r : vid.width)) // don't draw off the right of the screen (WRAP PREVENTION) break; } @@ -703,6 +912,8 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca while (column->topdelta != 0xff) { + fixed_t offy = 0; + topdelta = column->topdelta; if (topdelta <= prevdelta) topdelta += prevdelta; @@ -712,23 +923,60 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca dest = desttop; if (scrn & V_FLIP) dest = deststart + (destend - dest); - dest += FixedInt(FixedMul(topdelta<length << FRACBITS)-1; dest < deststop && ofs >= 0; ofs -= rowfrac) + for (ofs = (column->length << FRACBITS)-1; dest < deststop && ofs >= 0; ofs -= rowfrac, ++offy) { + if (clip != NULL) + { + const INT32 cy = y + topdelta - offy; + + if (cy < clip->t) // don't draw off the top of the clip rect + { + dest += vid.width; + continue; + } + + if (cy > clip->b) // don't draw off the bottom of the clip rect + { + dest += vid.width; + continue; + } + } + if (dest >= screens[scrn&V_SCREENMASK]) // don't draw off the top of the screen (CRASH PREVENTION) *dest = patchdrawfunc(dest, source, ofs); + dest += vid.width; } } else { - for (ofs = 0; dest < deststop && ofs < (column->length << FRACBITS); ofs += rowfrac) + for (ofs = 0; dest < deststop && ofs < (column->length << FRACBITS); ofs += rowfrac, ++offy) { + if (clip != NULL) + { + const INT32 cy = y + topdelta + offy; + + if (cy < clip->t) // don't draw off the top of the clip rect + { + dest += vid.width; + continue; + } + + if (cy > clip->b) // don't draw off the bottom of the clip rect + { + dest += vid.width; + continue; + } + } + if (dest >= screens[scrn&V_SCREENMASK]) // don't draw off the top of the screen (CRASH PREVENTION) *dest = patchdrawfunc(dest, source, ofs); + dest += vid.width; } } @@ -741,115 +989,16 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca // Draws a patch cropped and scaled to arbitrary size. void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t *patch, fixed_t sx, fixed_t sy, fixed_t w, fixed_t h) { - UINT8 (*patchdrawfunc)(const UINT8*, const UINT8*, fixed_t); - UINT32 alphalevel, blendmode; - // boolean flip = false; + cliprect_t oldClip = cliprect; - fixed_t col, ofs, colfrac, rowfrac, fdup; - INT32 dupx, dupy; - const column_t *column; - UINT8 *desttop, *dest; - const UINT8 *source, *deststop; + V_SetClipRect(x, y, w, h, scrn); - if (rendermode == render_none) - return; + x -= sx; + y -= sy; -#ifdef HWRENDER - //if (rendermode != render_soft && !con_startup) // Not this again - if (rendermode == render_opengl) - { - HWR_DrawCroppedPatch(patch,x,y,pscale,scrn,sx,sy,w,h); - return; - } -#endif + V_DrawStretchyFixedPatch(x, y, pscale, pscale, scrn, patch, NULL); - patchdrawfunc = standardpdraw; - - if ((blendmode = ((scrn & V_BLENDMASK) >> V_BLENDSHIFT))) - blendmode++; // realign to constants - if ((alphalevel = ((scrn & V_ALPHAMASK) >> V_ALPHASHIFT))) - { - if (alphalevel == 10) // V_HUDTRANSHALF - alphalevel = hudminusalpha[st_translucency]; - else if (alphalevel == 11) // V_HUDTRANS - alphalevel = 10 - st_translucency; - else if (alphalevel == 12) // V_HUDTRANSDOUBLE - alphalevel = hudplusalpha[st_translucency]; - - if (alphalevel >= 10) // Still inelegible to render? - return; - } - if ((v_translevel = R_GetBlendTable(blendmode, alphalevel))) - patchdrawfunc = translucentpdraw; - - // only use one dup, to avoid stretching (har har) - dupx = dupy = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy); - fdup = FixedMul(dupx<topoffset<leftoffset<>= FRACBITS; - y >>= FRACBITS; - desttop += (y*vid.width) + x; - } - else - { - x = FixedMul(x,dupx<>= FRACBITS; - y >>= FRACBITS; - - // Center it if necessary - // adjustxy - - desttop += (y*vid.width) + x; - } - - for (col = sx<>FRACBITS) < patch->width && ((col>>FRACBITS) - sx) < w; col += colfrac, ++x, desttop++) - { - INT32 topdelta, prevdelta = -1; - if (x < 0) // don't draw off the left of the screen (WRAP PREVENTION) - continue; - if (x >= vid.width) // don't draw off the right of the screen (WRAP PREVENTION) - break; - column = (const column_t *)((const UINT8 *)(patch->columns) + (patch->columnofs[col>>FRACBITS])); - - while (column->topdelta != 0xff) - { - topdelta = column->topdelta; - if (topdelta <= prevdelta) - topdelta += prevdelta; - prevdelta = topdelta; - source = (const UINT8 *)(column) + 3; - dest = desttop; - if (topdelta-sy > 0) - { - dest += FixedInt(FixedMul((topdelta-sy)<>FRACBITS) < column->length && (((ofs>>FRACBITS) - sy) + topdelta) < h; ofs += rowfrac) - { - if (dest >= screens[scrn&V_SCREENMASK]) // don't draw off the top of the screen (CRASH PREVENTION) - *dest = patchdrawfunc(dest, source, ofs); - dest += vid.width; - } - column = (const column_t *)((const UINT8 *)column + column->length + 4); - } - } + cliprect = oldClip; } // @@ -927,7 +1076,7 @@ void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c) h *= dupy; // Center it if necessary - K_AdjustXYWithSnap(&x, &y, c, dupx, dupy); + V_AdjustXYWithSnap(&x, &y, c, dupx, dupy); } if (x >= vid.width || y >= vid.height) @@ -1039,7 +1188,7 @@ void V_DrawFillConsoleMap(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c) h *= dupy; // Center it if necessary - K_AdjustXYWithSnap(&x, &y, c, dupx, dupy); + V_AdjustXYWithSnap(&x, &y, c, dupx, dupy); } if (x >= vid.width || y >= vid.height) @@ -1126,7 +1275,7 @@ void V_DrawDiag(INT32 x, INT32 y, INT32 wh, INT32 c) wh *= dupx; // Center it if necessary - K_AdjustXYWithSnap(&x, &y, c, dupx, dupy); + V_AdjustXYWithSnap(&x, &y, c, dupx, dupy); } if (x >= vid.width || y >= vid.height) diff --git a/src/v_video.h b/src/v_video.h index 8009035ea..666abcc68 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -168,6 +168,19 @@ void V_CubeApply(RGBA_t *input); #define V_NOSCALESTART 0x40000000 // don't scale x, y, start coords #define V_SPLITSCREEN 0x80000000 // Add half of screen width or height automatically depending on player number +void V_AdjustXYWithSnap(INT32 *x, INT32 *y, UINT32 options, INT32 dupx, INT32 dupy); + +struct cliprect_t +{ + fixed_t l, r, t, b; + INT32 flags; + boolean enabled; +}; + +cliprect_t *V_GetClipRect(void); +void V_SetClipRect(fixed_t x, fixed_t y, fixed_t w, fixed_t h, INT32 flags); +void V_ClearClipRect(void); + // defines for old functions #define V_DrawPatch(x,y,s,p) V_DrawFixedPatch((x)< Date: Sun, 11 Dec 2022 14:02:48 -0500 Subject: [PATCH 22/66] Comment out test case --- src/k_hud.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/k_hud.c b/src/k_hud.c index 543a7a9e7..9822f1706 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -1190,7 +1190,7 @@ static void K_drawKartItem(void) V_DrawScaledPatch(fx, fy, V_HUDTRANS|V_SLIDEIN|fflags, localbg); - V_SetClipRect((fx + 10) << FRACBITS, (fy + 10) << FRACBITS, 30 << FRACBITS, 30 << FRACBITS, V_HUDTRANS|V_SLIDEIN|fflags); + //V_SetClipRect((fx + 10) << FRACBITS, (fy + 10) << FRACBITS, 30 << FRACBITS, 30 << FRACBITS, V_HUDTRANS|V_SLIDEIN|fflags); // Then, the numbers: if (stplyr->itemamount >= numberdisplaymin && !stplyr->itemroulette) @@ -1211,7 +1211,7 @@ static void K_drawKartItem(void) else V_DrawFixedPatch(fx< Date: Sun, 11 Dec 2022 14:14:12 -0500 Subject: [PATCH 23/66] Clear clipping rectangle before each hook call Prevents Lua from being able to make a mess. --- src/d_main.c | 3 +++ src/lua_hooklib.c | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/src/d_main.c b/src/d_main.c index e3230d81e..fe5046585 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -373,6 +373,9 @@ static void D_Display(void) if (dedicated) //bail out after wipe logic return; + // Catch runaway clipping rectangles. + V_ClearClipRect(); + // do buffered drawing switch (gamestate) { diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index b797f669c..142d01490 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -27,6 +27,8 @@ #include "d_netcmd.h" // for cv_perfstats #include "i_system.h" // I_GetPreciseTime +#include "v_video.h" // V_ClearClipRect + /* ========================================================================= ABSTRACTION ========================================================================= */ @@ -641,8 +643,13 @@ void LUA_HookHUD(huddrawlist_h list, int hook_type) LUA_SetHudHook(hook_type, list); hud_running = true; // local hook + + // Catch runaway clipping rectangles. + V_ClearClipRect(); + init_hook_call(&hook, 0, res_none); call_mapped(&hook, map); + hud_running = false; } } From 8cdfcea3192f3c3f3871d6013ed9cebbda601e83 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 11 Dec 2022 16:47:25 -0500 Subject: [PATCH 24/66] Prevent modifying cliprect, wordier vars --- src/v_video.c | 28 ++++++++++++++-------------- src/v_video.h | 4 ++-- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/v_video.c b/src/v_video.c index a3feb21d0..66be9bf30 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -630,7 +630,7 @@ void V_AdjustXYWithSnap(INT32 *x, INT32 *y, UINT32 options, INT32 dupx, INT32 du static cliprect_t cliprect; -cliprect_t *V_GetClipRect(void) +const cliprect_t *V_GetClipRect(void) { if (cliprect.enabled == false) { @@ -705,10 +705,10 @@ void V_SetClipRect(fixed_t x, fixed_t y, fixed_t w, fixed_t h, INT32 flags) h = 0; } - cliprect.l = x; - cliprect.t = y; - cliprect.r = x + w; - cliprect.b = y + h; + cliprect.left = x; + cliprect.top = y; + cliprect.right = x + w; + cliprect.bottom = y + h; cliprect.flags = flags; cliprect.enabled = true; @@ -760,7 +760,7 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca fixed_t pwidth; // patch width fixed_t offx = 0; // x offset - cliprect_t *const clip = V_GetClipRect(); + const cliprect_t *clip = V_GetClipRect(); if (rendermode == render_none) return; @@ -895,16 +895,16 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca if (scrn & V_FLIP) // offx is measured from right edge instead of left { - if (x+pwidth-offx < (clip ? clip->l : 0)) // don't draw off the left of the screen (WRAP PREVENTION) + if (x+pwidth-offx < (clip ? clip->left : 0)) // don't draw off the left of the screen (WRAP PREVENTION) break; - if (x+pwidth-offx >= (clip ? clip->r : vid.width)) // don't draw off the right of the screen (WRAP PREVENTION) + if (x+pwidth-offx >= (clip ? clip->right : vid.width)) // don't draw off the right of the screen (WRAP PREVENTION) continue; } else { - if (x+offx < (clip ? clip->l : 0)) // don't draw off the left of the screen (WRAP PREVENTION) + if (x+offx < (clip ? clip->left : 0)) // don't draw off the left of the screen (WRAP PREVENTION) continue; - if (x+offx >= (clip ? clip->r : vid.width)) // don't draw off the right of the screen (WRAP PREVENTION) + if (x+offx >= (clip ? clip->right : vid.width)) // don't draw off the right of the screen (WRAP PREVENTION) break; } @@ -934,13 +934,13 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca { const INT32 cy = y + topdelta - offy; - if (cy < clip->t) // don't draw off the top of the clip rect + if (cy < clip->top) // don't draw off the top of the clip rect { dest += vid.width; continue; } - if (cy > clip->b) // don't draw off the bottom of the clip rect + if (cy > clip->bottom) // don't draw off the bottom of the clip rect { dest += vid.width; continue; @@ -961,13 +961,13 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca { const INT32 cy = y + topdelta + offy; - if (cy < clip->t) // don't draw off the top of the clip rect + if (cy < clip->top) // don't draw off the top of the clip rect { dest += vid.width; continue; } - if (cy > clip->b) // don't draw off the bottom of the clip rect + if (cy > clip->bottom) // don't draw off the bottom of the clip rect { dest += vid.width; continue; diff --git a/src/v_video.h b/src/v_video.h index 666abcc68..ddf5bb89e 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -172,12 +172,12 @@ void V_AdjustXYWithSnap(INT32 *x, INT32 *y, UINT32 options, INT32 dupx, INT32 du struct cliprect_t { - fixed_t l, r, t, b; + fixed_t left, right, top, bottom; INT32 flags; boolean enabled; }; -cliprect_t *V_GetClipRect(void); +const cliprect_t *V_GetClipRect(void); void V_SetClipRect(fixed_t x, fixed_t y, fixed_t w, fixed_t h, INT32 flags); void V_ClearClipRect(void); From 09c55858b759a6f5518b305e2bb1a821bf268ea1 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 11 Dec 2022 17:43:11 -0800 Subject: [PATCH 25/66] Fix off-by-one when clipping rectangle bottom --- src/v_video.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/v_video.c b/src/v_video.c index 66be9bf30..d65b34cea 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -940,7 +940,7 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca continue; } - if (cy > clip->bottom) // don't draw off the bottom of the clip rect + if (cy >= clip->bottom) // don't draw off the bottom of the clip rect { dest += vid.width; continue; @@ -967,7 +967,7 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca continue; } - if (cy > clip->bottom) // don't draw off the bottom of the clip rect + if (cy >= clip->bottom) // don't draw off the bottom of the clip rect { dest += vid.width; continue; From db062fd0bbbcc0a589d8c84fc7f69f35ca9ad391 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 11 Dec 2022 17:44:49 -0800 Subject: [PATCH 26/66] OpenGL: clipping support for HWR_DrawStretchyFixedPatch --- src/hardware/hw_draw.c | 56 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 48 insertions(+), 8 deletions(-) diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index 56890382f..d8eac4a44 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -145,6 +145,11 @@ void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t p // 0--1 float dupx, dupy, fscalew, fscaleh, fwidth, fheight; + const cliprect_t *clip = V_GetClipRect(); + + float s_min, s_max; + float t_min, t_max; + // make patch ready in hardware cache if (!colormap) HWR_GetPatch(gpatch); @@ -224,6 +229,41 @@ void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t p fheight = (float)(gpatch->height) * dupy; } + s_min = t_min = 0.0f; + s_max = hwrPatch->max_s; + t_max = hwrPatch->max_t; + + if (clip) + { + if (cx < clip->left) + { + s_min = ((clip->left - cx) / fwidth) * s_max; + cx = clip->left; + } + + if (cy < clip->top) + { + t_min = ((clip->top - cy) / fheight) * t_max; + cy = clip->top; + } + + if ((cx + fwidth) > clip->right) + { + const float n = (clip->right - clip->left); + + s_max = (s_min + ((n / fwidth) * s_max)); + fwidth = n; + } + + if ((cy + fheight) > clip->bottom) + { + const float n = (clip->bottom - clip->top); + + t_max = (t_min + ((n / fheight) * t_max)); + fheight = n; + } + } + // positions of the cx, cy, are between 0 and vid.width/vid.height now, we need them to be between -1 and 1 cx = -1 + (cx / (vid.width/2)); cy = 1 - (cy / (vid.height/2)); @@ -243,24 +283,24 @@ void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t p if (option & V_FLIP) { - v[0].s = v[3].s = hwrPatch->max_s; - v[2].s = v[1].s = 0.0f; + v[0].s = v[3].s = s_max; + v[2].s = v[1].s = s_min; } else { - v[0].s = v[3].s = 0.0f; - v[2].s = v[1].s = hwrPatch->max_s; + v[0].s = v[3].s = s_min; + v[2].s = v[1].s = s_max; } if (option & V_VFLIP) { - v[0].t = v[1].t = hwrPatch->max_t; - v[2].t = v[3].t = 0.0f; + v[0].t = v[1].t = t_max; + v[2].t = v[3].t = t_min; } else { - v[0].t = v[1].t = 0.0f; - v[2].t = v[3].t = hwrPatch->max_t; + v[0].t = v[1].t = t_min; + v[2].t = v[3].t = t_max; } flags = PF_NoDepthTest; From a481e4b34b3e237362d7018ff57baf759ece16fc Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 11 Dec 2022 23:58:11 -0500 Subject: [PATCH 27/66] Deterministic roulette The roulette contains NO (non-seeded) RNG anymore. You manually stop it at any time. Still needs the visual of the items scrolling, to make it not blind. --- src/Sourcefile | 1 + src/d_netcmd.c | 61 +-- src/d_netcmd.h | 33 +- src/d_player.h | 23 +- src/g_game.c | 13 +- src/k_botitem.c | 7 +- src/k_collide.c | 6 +- src/k_hud.c | 21 +- src/k_kart.c | 998 +----------------------------------------- src/k_kart.h | 8 - src/k_menudraw.c | 4 +- src/k_menufunc.c | 8 +- src/k_roulette.c | 1001 +++++++++++++++++++++++++++++++++++++++++++ src/k_roulette.h | 35 ++ src/lua_playerlib.c | 8 +- src/p_enemy.c | 7 +- src/p_inter.c | 11 +- src/p_mobj.c | 8 +- src/p_saveg.c | 52 ++- src/typedef.h | 1 + 20 files changed, 1199 insertions(+), 1107 deletions(-) create mode 100644 src/k_roulette.c create mode 100644 src/k_roulette.h diff --git a/src/Sourcefile b/src/Sourcefile index f2aa652b1..4da925828 100644 --- a/src/Sourcefile +++ b/src/Sourcefile @@ -125,3 +125,4 @@ k_director.c k_follower.c k_profiles.c k_specialstage.c +k_roulette.c diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 086c4cbfa..9820eeed3 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -360,35 +360,36 @@ consvar_t cv_joyscale[MAXSPLITSCREENPLAYERS] = { //Alam: Dummy for save #endif // SRB2kart -consvar_t cv_sneaker = CVAR_INIT ("sneaker", "On", CV_NETVAR, CV_OnOff, NULL); -consvar_t cv_rocketsneaker = CVAR_INIT ("rocketsneaker", "On", CV_NETVAR, CV_OnOff, NULL); -consvar_t cv_invincibility = CVAR_INIT ("invincibility", "On", CV_NETVAR, CV_OnOff, NULL); -consvar_t cv_banana = CVAR_INIT ("banana", "On", CV_NETVAR, CV_OnOff, NULL); -consvar_t cv_eggmanmonitor = CVAR_INIT ("eggmanmonitor", "On", CV_NETVAR, CV_OnOff, NULL); -consvar_t cv_orbinaut = CVAR_INIT ("orbinaut", "On", CV_NETVAR, CV_OnOff, NULL); -consvar_t cv_jawz = CVAR_INIT ("jawz", "On", CV_NETVAR, CV_OnOff, NULL); -consvar_t cv_mine = CVAR_INIT ("mine", "On", CV_NETVAR, CV_OnOff, NULL); -consvar_t cv_landmine = CVAR_INIT ("landmine", "On", CV_NETVAR, CV_OnOff, NULL); -consvar_t cv_ballhog = CVAR_INIT ("ballhog", "On", CV_NETVAR, CV_OnOff, NULL); -consvar_t cv_selfpropelledbomb = CVAR_INIT ("selfpropelledbomb", "On", CV_NETVAR, CV_OnOff, NULL); -consvar_t cv_grow = CVAR_INIT ("grow", "On", CV_NETVAR, CV_OnOff, NULL); -consvar_t cv_shrink = CVAR_INIT ("shrink", "On", CV_NETVAR, CV_OnOff, NULL); -consvar_t cv_lightningshield = CVAR_INIT ("lightningshield", "On", CV_NETVAR, CV_OnOff, NULL); -consvar_t cv_bubbleshield = CVAR_INIT ("bubbleshield", "On", CV_NETVAR, CV_OnOff, NULL); -consvar_t cv_flameshield = CVAR_INIT ("flameshield", "On", CV_NETVAR, CV_OnOff, NULL); -consvar_t cv_hyudoro = CVAR_INIT ("hyudoro", "On", CV_NETVAR, CV_OnOff, NULL); -consvar_t cv_pogospring = CVAR_INIT ("pogospring", "On", CV_NETVAR, CV_OnOff, NULL); -consvar_t cv_superring = CVAR_INIT ("superring", "On", CV_NETVAR, CV_OnOff, NULL); -consvar_t cv_kitchensink = CVAR_INIT ("kitchensink", "On", CV_NETVAR, CV_OnOff, NULL); -consvar_t cv_droptarget = CVAR_INIT ("droptarget", "On", CV_NETVAR, CV_OnOff, NULL); -consvar_t cv_gardentop = CVAR_INIT ("gardentop", "On", CV_NETVAR, CV_OnOff, NULL); - -consvar_t cv_dualsneaker = CVAR_INIT ("dualsneaker", "On", CV_NETVAR, CV_OnOff, NULL); -consvar_t cv_triplesneaker = CVAR_INIT ("triplesneaker", "On", CV_NETVAR, CV_OnOff, NULL); -consvar_t cv_triplebanana = CVAR_INIT ("triplebanana", "On", CV_NETVAR, CV_OnOff, NULL); -consvar_t cv_tripleorbinaut = CVAR_INIT ("tripleorbinaut", "On", CV_NETVAR, CV_OnOff, NULL); -consvar_t cv_quadorbinaut = CVAR_INIT ("quadorbinaut", "On", CV_NETVAR, CV_OnOff, NULL); -consvar_t cv_dualjawz = CVAR_INIT ("dualjawz", "On", CV_NETVAR, CV_OnOff, NULL); +consvar_t cv_items[NUMKARTRESULTS-1] = { + CVAR_INIT ("sneaker", "On", CV_NETVAR, CV_OnOff, NULL), + CVAR_INIT ("rocketsneaker", "On", CV_NETVAR, CV_OnOff, NULL), + CVAR_INIT ("invincibility", "On", CV_NETVAR, CV_OnOff, NULL), + CVAR_INIT ("banana", "On", CV_NETVAR, CV_OnOff, NULL), + CVAR_INIT ("eggmanmonitor", "On", CV_NETVAR, CV_OnOff, NULL), + CVAR_INIT ("orbinaut", "On", CV_NETVAR, CV_OnOff, NULL), + CVAR_INIT ("jawz", "On", CV_NETVAR, CV_OnOff, NULL), + CVAR_INIT ("mine", "On", CV_NETVAR, CV_OnOff, NULL), + CVAR_INIT ("landmine", "On", CV_NETVAR, CV_OnOff, NULL), + CVAR_INIT ("ballhog", "On", CV_NETVAR, CV_OnOff, NULL), + CVAR_INIT ("selfpropelledbomb", "On", CV_NETVAR, CV_OnOff, NULL), + CVAR_INIT ("grow", "On", CV_NETVAR, CV_OnOff, NULL), + CVAR_INIT ("shrink", "On", CV_NETVAR, CV_OnOff, NULL), + CVAR_INIT ("lightningshield", "On", CV_NETVAR, CV_OnOff, NULL), + CVAR_INIT ("bubbleshield", "On", CV_NETVAR, CV_OnOff, NULL), + CVAR_INIT ("flameshield", "On", CV_NETVAR, CV_OnOff, NULL), + CVAR_INIT ("hyudoro", "On", CV_NETVAR, CV_OnOff, NULL), + CVAR_INIT ("pogospring", "On", CV_NETVAR, CV_OnOff, NULL), + CVAR_INIT ("superring", "On", CV_NETVAR, CV_OnOff, NULL), + CVAR_INIT ("kitchensink", "On", CV_NETVAR, CV_OnOff, NULL), + CVAR_INIT ("droptarget", "On", CV_NETVAR, CV_OnOff, NULL), + CVAR_INIT ("gardentop", "On", CV_NETVAR, CV_OnOff, NULL), + CVAR_INIT ("dualsneaker", "On", CV_NETVAR, CV_OnOff, NULL), + CVAR_INIT ("triplesneaker", "On", CV_NETVAR, CV_OnOff, NULL), + CVAR_INIT ("triplebanana", "On", CV_NETVAR, CV_OnOff, NULL), + CVAR_INIT ("tripleorbinaut", "On", CV_NETVAR, CV_OnOff, NULL), + CVAR_INIT ("quadorbinaut", "On", CV_NETVAR, CV_OnOff, NULL), + CVAR_INIT ("dualjawz", "On", CV_NETVAR, CV_OnOff, NULL) +}; consvar_t cv_kartspeed = CVAR_INIT ("gamespeed", "Auto", CV_NETVAR|CV_CALL|CV_NOINIT, kartspeed_cons_t, KartSpeed_OnChange); static CV_PossibleValue_t kartbumpers_cons_t[] = {{1, "MIN"}, {12, "MAX"}, {0, NULL}}; @@ -5659,7 +5660,7 @@ static void Got_Cheat(UINT8 **cp, INT32 playernum) K_StripItems(player); // Cancel roulette if rolling - player->itemroulette = 0; + player->itemRoulette.active = false; player->itemtype = item; player->itemamount = amt; diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 3f4d00645..e0b969ffd 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -16,6 +16,7 @@ #define __D_NETCMD__ #include "command.h" +#include "d_player.h" // console vars extern consvar_t cv_playername[MAXSPLITSCREENPLAYERS]; @@ -72,37 +73,7 @@ extern consvar_t cv_pause; extern consvar_t cv_restrictskinchange, cv_allowteamchange, cv_maxplayers, cv_respawntime; // SRB2kart items -extern consvar_t - cv_sneaker, - cv_rocketsneaker, - cv_invincibility, - cv_banana, - cv_eggmanmonitor, - cv_orbinaut, - cv_jawz, - cv_mine, - cv_landmine, - cv_ballhog, - cv_selfpropelledbomb, - cv_grow, - cv_shrink, - cv_lightningshield, - cv_bubbleshield, - cv_flameshield, - cv_hyudoro, - cv_pogospring, - cv_superring, - cv_kitchensink, - cv_droptarget, - cv_gardentop; - -extern consvar_t - cv_dualsneaker, - cv_triplesneaker, - cv_triplebanana, - cv_tripleorbinaut, - cv_quadorbinaut, - cv_dualjawz; +extern consvar_t cv_items[NUMKARTRESULTS-1]; extern consvar_t cv_kartspeed; extern consvar_t cv_kartbumpers; diff --git a/src/d_player.h b/src/d_player.h index a65f0235b..fdcb5bdc4 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -131,6 +131,7 @@ Do with it whatever you want. Run this macro, then #undef FOREACH afterward */ #define KART_ITEM_ITERATOR \ + FOREACH (EGGEXPLODE, -2),\ FOREACH (SAD, -1),\ FOREACH (NONE, 0),\ FOREACH (SNEAKER, 1),\ @@ -329,6 +330,25 @@ struct skybox_t { mobj_t * centerpoint; }; +// player_t struct for item roulette variables +struct itemroulette_t +{ + boolean active; + + size_t itemListCap; + size_t itemListLen; + SINT8 *itemList; + + size_t index; + UINT8 sound; + + tic_t speed; + tic_t tics; + tic_t elapsed; + + boolean eggman; +}; + // ======================================================================== // PLAYER STRUCTURE // ======================================================================== @@ -477,8 +497,7 @@ struct player_t UINT8 tripwirePass; // see tripwirepass_t UINT16 tripwireLeniency; // When reaching a state that lets you go thru tripwire, you get an extra second leniency after it ends to still go through it. - UINT16 itemroulette; // Used for the roulette when deciding what item to give you (was "pw_kartitem") - UINT8 roulettetype; // Used for the roulette, for deciding type (0 = normal, 1 = better, 2 = eggman mark) + itemroulette_t itemRoulette; // Item roulette data // Item held stuff SINT8 itemtype; // KITEM_ constant for item number diff --git a/src/g_game.c b/src/g_game.c index 5cde2d270..91d309638 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2260,11 +2260,10 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) SINT8 xtralife; // SRB2kart + itemroulette_t itemRoulette; respawnvars_t respawn; INT32 itemtype; INT32 itemamount; - INT32 itemroulette; - INT32 roulettetype; INT32 growshrinktimer; INT32 bumper; boolean songcredit = false; @@ -2325,8 +2324,6 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) // SRB2kart if (betweenmaps || leveltime < introtime) { - itemroulette = 0; - roulettetype = 0; itemtype = 0; itemamount = 0; growshrinktimer = 0; @@ -2348,9 +2345,6 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) } else { - itemroulette = (players[player].itemroulette > 0 ? 1 : 0); - roulettetype = players[player].roulettetype; - if (players[player].pflags & PF_ITEMOUT) { itemtype = 0; @@ -2406,6 +2400,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) P_SetTarget(&players[player].follower, NULL); } + memcpy(&itemRoulette, &players[player].itemRoulette, sizeof (itemRoulette)); memcpy(&respawn, &players[player].respawn, sizeof (respawn)); p = &players[player]; @@ -2453,8 +2448,6 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) p->xtralife = xtralife; // SRB2kart - p->itemroulette = itemroulette; - p->roulettetype = roulettetype; p->itemtype = itemtype; p->itemamount = itemamount; p->growshrinktimer = growshrinktimer; @@ -2470,6 +2463,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) p->botvars.rubberband = FRACUNIT; p->botvars.controller = UINT16_MAX; + memcpy(&p->itemRoulette, &itemRoulette, sizeof (p->itemRoulette)); memcpy(&p->respawn, &respawn, sizeof (p->respawn)); if (follower) @@ -2481,7 +2475,6 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) //p->follower = NULL; // respawn a new one with you, it looks better. // ^ Not necessary anyway since it will be respawned regardless considering it doesn't exist anymore. - p->playerstate = PST_LIVE; p->panim = PA_STILL; // standing animation diff --git a/src/k_botitem.c b/src/k_botitem.c index 6c8b9ece4..e3054aa69 100644 --- a/src/k_botitem.c +++ b/src/k_botitem.c @@ -26,6 +26,7 @@ #include "d_ticcmd.h" #include "m_random.h" #include "r_things.h" // numskins +#include "k_roulette.h" /*-------------------------------------------------- static inline boolean K_ItemButtonWasDown(player_t *player) @@ -739,7 +740,7 @@ static void K_BotItemEggman(player_t *player, ticcmd_t *cmd) tryLookback = true; } - if (stealth > 1 || player->itemroulette > 0) + if (stealth > 1 || player->itemRoulette.active == true) { player->botvars.itemconfirm += player->botvars.difficulty * 4; throwdir = -1; @@ -1400,7 +1401,7 @@ static void K_BotItemRouletteMash(player_t *player, ticcmd_t *cmd) return; } - if (player->rings < 0 && cv_superring.value) + if (player->rings < 0 && K_ItemEnabled(KITEM_SUPERRING) == true) { // Uh oh, we need a loan! // It'll be better in the long run for bots to lose an item set for 10 free rings. @@ -1441,7 +1442,7 @@ void K_BotItemUsage(player_t *player, ticcmd_t *cmd, INT16 turnamt) return; } - if (player->itemroulette) + if (player->itemRoulette.active == true) { // Mashing behaviors K_BotItemRouletteMash(player, cmd); diff --git a/src/k_collide.c b/src/k_collide.c index dac44b5f7..d9ab58e1c 100644 --- a/src/k_collide.c +++ b/src/k_collide.c @@ -12,6 +12,7 @@ #include "doomdef.h" // Sink snipe print #include "g_game.h" // Sink snipe print #include "k_objects.h" +#include "k_roulette.h" angle_t K_GetCollideAngle(mobj_t *t1, mobj_t *t2) { @@ -158,10 +159,7 @@ boolean K_EggItemCollide(mobj_t *t1, mobj_t *t2) } else { - K_DropItems(t2->player); //K_StripItems(t2->player); - //K_StripOther(t2->player); - t2->player->itemroulette = 1; - t2->player->roulettetype = 2; + K_StartEggmanRoulette(t2->player); } if (t2->player->flamedash && t2->player->itemtype == KITEM_FLAMESHIELD) diff --git a/src/k_hud.c b/src/k_hud.c index 5325f07eb..25a869c13 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -36,6 +36,7 @@ #include "r_things.h" #include "r_fps.h" #include "m_random.h" +#include "k_roulette.h" //{ Patch Definitions static patch_t *kp_nodraw; @@ -1146,12 +1147,14 @@ static void K_drawKartItem(void) UINT8 *colmap = NULL; boolean flipamount = false; // Used for 3P/4P splitscreen to flip item amount stuff - if (stplyr->itemroulette) + if (stplyr->itemRoulette.active == true) { - const INT32 item = K_GetRollingRouletteItem(stplyr); + const SINT8 item = K_ItemResultToType(stplyr->itemRoulette.itemList[ stplyr->itemRoulette.index ]); if (stplyr->skincolor) + { localcolor = stplyr->skincolor; + } switch (item) { @@ -1165,6 +1168,7 @@ static void K_drawKartItem(void) default: localpatch = K_GetCachedItemPatch(item, offset); + break; } } else @@ -1223,7 +1227,7 @@ static void K_drawKartItem(void) if (stplyr->itemamount <= 0) return; - switch(stplyr->itemtype) + switch (stplyr->itemtype) { case KITEM_INVINCIBILITY: localpatch = localinv; @@ -1302,7 +1306,7 @@ static void K_drawKartItem(void) V_DrawScaledPatch(fx, fy, V_HUDTRANS|V_SLIDEIN|fflags, localbg); // Then, the numbers: - if (stplyr->itemamount >= numberdisplaymin && !stplyr->itemroulette) + if (stplyr->itemamount >= numberdisplaymin && stplyr->itemRoulette.active == false) { V_DrawScaledPatch(fx + (flipamount ? 48 : 0), fy, V_HUDTRANS|V_SLIDEIN|fflags|(flipamount ? V_FLIP : 0), kp_itemmulsticker[offset]); // flip this graphic for p2 and p4 in split and shift it. V_DrawFixedPatch(fx<botvars.itemdelay = TICRATE; - player->botvars.itemconfirm = 0; - - player->itemtype = K_ItemResultToType(getitem); - player->itemamount = K_ItemResultToAmount(getitem); -} - -fixed_t K_ItemOddsScale(UINT8 playerCount) -{ - const UINT8 basePlayer = 8; // The player count we design most of the game around. - fixed_t playerScaling = 0; - - if (playerCount < 2) - { - // Cap to 1v1 scaling - playerCount = 2; - } - - // Then, it multiplies it further if the player count isn't equal to basePlayer. - // This is done to make low player count races more interesting and high player count rates more fair. - if (playerCount < basePlayer) - { - // Less than basePlayer: increase odds significantly. - // 2P: x2.5 - playerScaling = (basePlayer - playerCount) * (FRACUNIT / 4); - } - else if (playerCount > basePlayer) - { - // More than basePlayer: reduce odds slightly. - // 16P: x0.75 - playerScaling = (basePlayer - playerCount) * (FRACUNIT / 32); - } - - return playerScaling; -} - -UINT32 K_ScaleItemDistance(UINT32 distance, UINT8 numPlayers) -{ - if (mapobjectscale != FRACUNIT) - { - // Bring back to normal scale. - distance = FixedDiv(distance, mapobjectscale); - } - - if (franticitems == true) - { - // Frantic items pretends everyone's farther apart, for crazier items. - distance = (15 * distance) / 14; - } - - // Items get crazier with the fewer players that you have. - distance = FixedMul( - distance, - FRACUNIT + (K_ItemOddsScale(numPlayers) / 2) - ); - - return distance; -} - -/** \brief Item Roulette for Kart - - \param player player object passed from P_KartPlayerThink - - \return void -*/ - -INT32 K_KartGetItemOdds( - UINT8 pos, SINT8 item, - UINT32 ourDist, - fixed_t mashed, - boolean bot, boolean rival) -{ - INT32 newodds; - INT32 i; - - UINT8 pingame = 0, pexiting = 0; - - player_t *first = NULL; - player_t *second = NULL; - - UINT32 firstDist = UINT32_MAX; - UINT32 secondDist = UINT32_MAX; - UINT32 secondToFirst = 0; - boolean isFirst = false; - - boolean powerItem = false; - boolean cooldownOnStart = false; - boolean notNearEnd = false; - - INT32 shieldtype = KSHIELD_NONE; - - I_Assert(item > KITEM_NONE); // too many off by one scenarioes. - I_Assert(KartItemCVars[NUMKARTRESULTS-2] != NULL); // Make sure this exists - - if (!KartItemCVars[item-1]->value && !modeattacking) - { - return 0; - } - - if (K_GetItemCooldown(item) > 0) - { - // Cooldown is still running, don't give another. - return 0; - } - - /* - if (bot) - { - // TODO: Item use on bots should all be passed-in functions. - // Instead of manually inserting these, it should return 0 - // for any items without an item use function supplied - - switch (item) - { - case KITEM_SNEAKER: - break; - default: - return 0; - } - } - */ - (void)bot; - - if (gametype == GT_BATTLE) - { - I_Assert(pos < 2); // DO NOT allow positions past the bounds of the table - newodds = K_KartItemOddsBattle[item-1][pos]; - } - else - { - I_Assert(pos < 8); // Ditto - newodds = K_KartItemOddsRace[item-1][pos]; - } - - // Base multiplication to ALL item odds to simulate fractional precision - newodds *= 4; - - shieldtype = K_GetShieldFromItem(item); - - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i] || players[i].spectator) - continue; - - if (!(gametyperules & GTR_BUMPERS) || players[i].bumpers) - pingame++; - - if (players[i].exiting) - pexiting++; - - switch (shieldtype) - { - case KSHIELD_NONE: - /* Marble Garden Top is not REALLY - a Sonic 3 shield */ - case KSHIELD_TOP: - break; - - default: - if (shieldtype == K_GetShieldFromItem(players[i].itemtype)) - { - // Don't allow more than one of each shield type at a time - return 0; - } - } - - if (players[i].position == 1) - { - first = &players[i]; - } - - if (players[i].position == 2) - { - second = &players[i]; - } - } - - if (first != NULL) // calculate 2nd's distance from 1st, for SPB - { - firstDist = first->distancetofinish; - isFirst = (ourDist <= firstDist); - } - - if (second != NULL) - { - secondDist = second->distancetofinish; - } - - if (first != NULL && second != NULL) - { - secondToFirst = secondDist - firstDist; - secondToFirst = K_ScaleItemDistance(secondToFirst, 16 - pingame); // Reversed scaling, so 16P is like 1v1, and 1v1 is like 16P - } - - switch (item) - { - case KITEM_BANANA: - case KITEM_EGGMAN: - case KITEM_SUPERRING: - notNearEnd = true; - break; - - case KITEM_ROCKETSNEAKER: - case KITEM_JAWZ: - case KITEM_LANDMINE: - case KITEM_DROPTARGET: - case KITEM_BALLHOG: - case KITEM_HYUDORO: - case KRITEM_TRIPLESNEAKER: - case KRITEM_TRIPLEORBINAUT: - case KRITEM_QUADORBINAUT: - case KRITEM_DUALJAWZ: - powerItem = true; - break; - - case KRITEM_TRIPLEBANANA: - powerItem = true; - notNearEnd = true; - break; - - case KITEM_INVINCIBILITY: - case KITEM_MINE: - case KITEM_GROW: - case KITEM_BUBBLESHIELD: - case KITEM_FLAMESHIELD: - cooldownOnStart = true; - powerItem = true; - break; - - case KITEM_SPB: - cooldownOnStart = true; - notNearEnd = true; - - if (firstDist < ENDDIST*2 // No SPB when 1st is almost done - || isFirst == true) // No SPB for 1st ever - { - newodds = 0; - } - else - { - const UINT32 dist = max(0, ((signed)secondToFirst) - SPBSTARTDIST); - const UINT32 distRange = SPBFORCEDIST - SPBSTARTDIST; - const UINT8 maxOdds = 20; - fixed_t multiplier = (dist * FRACUNIT) / distRange; - - if (multiplier < 0) - { - multiplier = 0; - } - - if (multiplier > FRACUNIT) - { - multiplier = FRACUNIT; - } - - newodds = FixedMul(maxOdds * 4, multiplier); - } - break; - - case KITEM_SHRINK: - cooldownOnStart = true; - powerItem = true; - notNearEnd = true; - - if (pingame-1 <= pexiting) - newodds = 0; - break; - - case KITEM_LIGHTNINGSHIELD: - cooldownOnStart = true; - powerItem = true; - - if (spbplace != -1) - newodds = 0; - break; - - default: - break; - } - - if (newodds == 0) - { - // Nothing else we want to do with odds matters at this point :p - return newodds; - } - - - if ((cooldownOnStart == true) && (leveltime < (30*TICRATE)+starttime)) - { - // This item should not appear at the beginning of a race. (Usually really powerful crowd-breaking items) - newodds = 0; - } - else if ((notNearEnd == true) && (ourDist < ENDDIST)) - { - // This item should not appear at the end of a race. (Usually trap items that lose their effectiveness) - newodds = 0; - } - else if (powerItem == true) - { - // This item is a "power item". This activates "frantic item" toggle related functionality. - fixed_t fracOdds = newodds * FRACUNIT; - - if (franticitems == true) - { - // First, power items multiply their odds by 2 if frantic items are on; easy-peasy. - fracOdds *= 2; - } - - if (rival == true) - { - // The Rival bot gets frantic-like items, also :p - fracOdds *= 2; - } - - fracOdds = FixedMul(fracOdds, FRACUNIT + K_ItemOddsScale(pingame)); - - if (mashed > 0) - { - // Lastly, it *divides* it based on your mashed value, so that power items are less likely when you mash. - fracOdds = FixedDiv(fracOdds, FRACUNIT + mashed); - } - - newodds = fracOdds / FRACUNIT; - } - - return newodds; -} - -//{ SRB2kart Roulette Code - Distance Based, yes waypoints - -UINT8 K_FindUseodds(player_t *player, fixed_t mashed, UINT32 pdis, UINT8 bestbumper) -{ - UINT8 i; - UINT8 useodds = 0; - UINT8 disttable[14]; - UINT8 distlen = 0; - boolean oddsvalid[8]; - - // Unused now, oops :V - (void)bestbumper; - - for (i = 0; i < 8; i++) - { - UINT8 j; - boolean available = false; - - if (gametype == GT_BATTLE && i > 1) - { - oddsvalid[i] = false; - break; - } - - for (j = 1; j < NUMKARTRESULTS; j++) - { - if (K_KartGetItemOdds( - i, j, - player->distancetofinish, - mashed, - player->bot, (player->bot && player->botvars.rival) - ) > 0) - { - available = true; - break; - } - } - - oddsvalid[i] = available; - } - -#define SETUPDISTTABLE(odds, num) \ - if (oddsvalid[odds]) \ - for (i = num; i; --i) \ - disttable[distlen++] = odds; - - if (gametype == GT_BATTLE) // Battle Mode - { - if (player->roulettetype == 1 && oddsvalid[1] == true) - { - // 1 is the extreme odds of player-controlled "Karma" items - useodds = 1; - } - else - { - useodds = 0; - - if (oddsvalid[0] == false && oddsvalid[1] == true) - { - // try to use karma odds as a fallback - useodds = 1; - } - } - } - else - { - SETUPDISTTABLE(0,1); - SETUPDISTTABLE(1,1); - SETUPDISTTABLE(2,1); - SETUPDISTTABLE(3,2); - SETUPDISTTABLE(4,2); - SETUPDISTTABLE(5,3); - SETUPDISTTABLE(6,3); - SETUPDISTTABLE(7,1); - - if (pdis == 0) - useodds = disttable[0]; - else if (pdis > DISTVAR * ((12 * distlen) / 14)) - useodds = disttable[distlen-1]; - else - { - for (i = 1; i < 13; i++) - { - if (pdis <= DISTVAR * ((i * distlen) / 14)) - { - useodds = disttable[((i * distlen) / 14)]; - break; - } - } - } - } - -#undef SETUPDISTTABLE - - return useodds; -} - -INT32 K_GetRollingRouletteItem(player_t *player) -{ - static UINT8 translation[NUMKARTITEMS-1]; - static UINT16 roulette_size; - - static INT16 odds_cached = -1; - - // Race odds have more columns than Battle - const UINT8 EMPTYODDS[sizeof K_KartItemOddsRace[0]] = {0}; - - if (odds_cached != gametype) - { - UINT8 *odds_row; - size_t odds_row_size; - - UINT8 i; - - roulette_size = 0; - - if (gametype == GT_BATTLE) - { - odds_row = K_KartItemOddsBattle[0]; - odds_row_size = sizeof K_KartItemOddsBattle[0]; - } - else - { - odds_row = K_KartItemOddsRace[0]; - odds_row_size = sizeof K_KartItemOddsRace[0]; - } - - for (i = 1; i < NUMKARTITEMS; ++i) - { - if (memcmp(odds_row, EMPTYODDS, odds_row_size)) - { - translation[roulette_size] = i; - roulette_size++; - } - - odds_row += odds_row_size; - } - - roulette_size *= 3; - odds_cached = gametype; - } - - return translation[(player->itemroulette % roulette_size) / 3]; -} - -boolean K_ForcedSPB(player_t *player) -{ - player_t *first = NULL; - player_t *second = NULL; - UINT32 secondToFirst = UINT32_MAX; - UINT8 pingame = 0; - UINT8 i; - - if (!cv_selfpropelledbomb.value) - { - return false; - } - - if (!(gametyperules & GTR_CIRCUIT)) - { - return false; - } - - if (player->position <= 1) - { - return false; - } - - if (spbplace != -1) - { - return false; - } - - if (itemCooldowns[KITEM_SPB - 1] > 0) - { - return false; - } - - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i] || players[i].spectator) - { - continue; - } - - if (players[i].exiting) - { - return false; - } - - pingame++; - - if (players[i].position == 1) - { - first = &players[i]; - } - - if (players[i].position == 2) - { - second = &players[i]; - } - } - -#if 0 - if (pingame <= 2) - { - return false; - } -#endif - - if (first != NULL && second != NULL) - { - secondToFirst = second->distancetofinish - first->distancetofinish; - secondToFirst = K_ScaleItemDistance(secondToFirst, 16 - pingame); - } - - return (secondToFirst >= SPBFORCEDIST); -} - -static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) -{ - INT32 i; - UINT8 pingame = 0; - UINT8 roulettestop; - UINT32 pdis = 0; - UINT8 useodds = 0; - INT32 spawnchance[NUMKARTRESULTS]; - INT32 totalspawnchance = 0; - UINT8 bestbumper = 0; - fixed_t mashed = 0; - - // This makes the roulette cycle through items - if this is 0, you shouldn't be here. - if (!player->itemroulette) - return; - player->itemroulette++; - - // Gotta check how many players are active at this moment. - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i] || players[i].spectator) - continue; - - pingame++; - - if (players[i].bumpers > bestbumper) - bestbumper = players[i].bumpers; - } - - // This makes the roulette produce the random noises. - if ((player->itemroulette % 3) == 1 && P_IsDisplayPlayer(player) && !demo.freecam) - { -#define PLAYROULETTESND S_StartSound(NULL, sfx_itrol1 + ((player->itemroulette / 3) % 8)) - for (i = 0; i <= r_splitscreen; i++) - { - if (player == &players[displayplayers[i]] && players[displayplayers[i]].itemroulette) - PLAYROULETTESND; - } -#undef PLAYROULETTESND - } - - roulettestop = TICRATE + (3*(pingame - player->position)); - - // If the roulette finishes or the player presses BT_ATTACK, stop the roulette and calculate the item. - // I'm returning via the exact opposite, however, to forgo having another bracket embed. Same result either way, I think. - // Finally, if you get past this check, now you can actually start calculating what item you get. - if ((cmd->buttons & BT_ATTACK) && (player->itemroulette >= roulettestop) - && !(player->pflags & (PF_ITEMOUT|PF_EGGMANOUT|PF_USERINGS))) - { - // Mashing reduces your chances for the good items - mashed = FixedDiv((player->itemroulette)*FRACUNIT, ((TICRATE*3)+roulettestop)*FRACUNIT) - FRACUNIT; - } - else if (!(player->itemroulette >= (TICRATE*3))) - return; - - for (i = 0; i < MAXPLAYERS; i++) - { - if (playeringame[i] && !players[i].spectator - && players[i].position == 1) - { - // This player is first! Yay! - - if (player->distancetofinish <= players[i].distancetofinish) - { - // Guess you're in first / tied for first? - pdis = 0; - } - else - { - // Subtract 1st's distance from your distance, to get your distance from 1st! - pdis = player->distancetofinish - players[i].distancetofinish; - } - break; - } - } - - pdis = K_ScaleItemDistance(pdis, pingame); - - if (player->bot && player->botvars.rival) - { - // Rival has better odds :) - pdis = (15 * pdis) / 14; - } - - // SPECIAL CASE No. 1: - // Fake Eggman items - if (player->roulettetype == 2) - { - player->eggmanexplode = 4*TICRATE; - //player->karthud[khud_itemblink] = TICRATE; - //player->karthud[khud_itemblinkmode] = 1; - player->itemroulette = 0; - player->roulettetype = 0; - if (P_IsDisplayPlayer(player) && !demo.freecam) - S_StartSound(NULL, sfx_itrole); - return; - } - - // SPECIAL CASE No. 2: - // Give a debug item instead if specified - if (cv_kartdebugitem.value != 0 && !modeattacking) - { - K_KartGetItemResult(player, cv_kartdebugitem.value); - player->itemamount = cv_kartdebugamount.value; - player->karthud[khud_itemblink] = TICRATE; - player->karthud[khud_itemblinkmode] = 2; - player->itemroulette = 0; - player->roulettetype = 0; - if (P_IsDisplayPlayer(player) && !demo.freecam) - S_StartSound(NULL, sfx_dbgsal); - return; - } - - // SPECIAL CASE No. 3: - // Record Attack / alone mashing behavior - if (modeattacking || pingame == 1) - { - if (gametype == GT_RACE) - { - if (mashed && (modeattacking || cv_superring.value)) // ANY mashed value? You get rings. - { - K_KartGetItemResult(player, KITEM_SUPERRING); - player->karthud[khud_itemblinkmode] = 1; - if (P_IsDisplayPlayer(player)) - S_StartSound(NULL, sfx_itrolm); - } - else - { - if (modeattacking || cv_sneaker.value) // Waited patiently? You get a sneaker! - K_KartGetItemResult(player, KITEM_SNEAKER); - else // Default to sad if nothing's enabled... - K_KartGetItemResult(player, KITEM_SAD); - player->karthud[khud_itemblinkmode] = 0; - if (P_IsDisplayPlayer(player)) - S_StartSound(NULL, sfx_itrolf); - } - } - else if (gametype == GT_BATTLE) - { - if (mashed && (modeattacking || bossinfo.boss || cv_banana.value)) // ANY mashed value? You get a banana. - { - K_KartGetItemResult(player, KITEM_BANANA); - player->karthud[khud_itemblinkmode] = 1; - if (P_IsDisplayPlayer(player)) - S_StartSound(NULL, sfx_itrolm); - } - else if (bossinfo.boss) - { - K_KartGetItemResult(player, KITEM_ORBINAUT); - player->karthud[khud_itemblinkmode] = 0; - if (P_IsDisplayPlayer(player)) - S_StartSound(NULL, sfx_itrolf); - } - else - { - if (modeattacking || cv_tripleorbinaut.value) // Waited patiently? You get Orbinaut x3! - K_KartGetItemResult(player, KRITEM_TRIPLEORBINAUT); - else // Default to sad if nothing's enabled... - K_KartGetItemResult(player, KITEM_SAD); - player->karthud[khud_itemblinkmode] = 0; - if (P_IsDisplayPlayer(player)) - S_StartSound(NULL, sfx_itrolf); - } - } - - player->karthud[khud_itemblink] = TICRATE; - player->itemroulette = 0; - player->roulettetype = 0; - return; - } - - // SPECIAL CASE No. 4: - // Being in ring debt occasionally forces Super Ring on you if you mashed - if (!(gametyperules & GTR_SPHERES) && mashed && player->rings < 0 && cv_superring.value) - { - INT32 debtamount = min(20, abs(player->rings)); - if (P_RandomChance(PR_ITEM_ROULETTE, (debtamount*FRACUNIT)/20)) - { - K_KartGetItemResult(player, KITEM_SUPERRING); - player->karthud[khud_itemblink] = TICRATE; - player->karthud[khud_itemblinkmode] = 1; - player->itemroulette = 0; - player->roulettetype = 0; - if (P_IsDisplayPlayer(player)) - S_StartSound(NULL, sfx_itrolm); - return; - } - } - - // SPECIAL CASE No. 5: - // Force SPB if 2nd is way too far behind - if (K_ForcedSPB(player) == true) - { - K_KartGetItemResult(player, KITEM_SPB); - player->karthud[khud_itemblink] = TICRATE; - player->karthud[khud_itemblinkmode] = 2; - player->itemroulette = 0; - player->roulettetype = 0; - if (P_IsDisplayPlayer(player)) - S_StartSound(NULL, sfx_itrolk); - return; - } - - // NOW that we're done with all of those specialized cases, we can move onto the REAL item roulette tables. - // Initializes existing spawnchance values - for (i = 0; i < NUMKARTRESULTS; i++) - spawnchance[i] = 0; - - // Split into another function for a debug function below - useodds = K_FindUseodds(player, mashed, pdis, bestbumper); - - for (i = 1; i < NUMKARTRESULTS; i++) - { - spawnchance[i] = (totalspawnchance += K_KartGetItemOdds( - useodds, i, - player->distancetofinish, - mashed, - player->bot, (player->bot && player->botvars.rival)) - ); - } - - // Award the player whatever power is rolled - if (totalspawnchance > 0) - { - totalspawnchance = P_RandomKey(PR_ITEM_ROULETTE, totalspawnchance); - for (i = 0; i < NUMKARTRESULTS && spawnchance[i] <= totalspawnchance; i++); - - K_KartGetItemResult(player, i); - } - else - { - player->itemtype = KITEM_SAD; - player->itemamount = 1; - } - - if (P_IsDisplayPlayer(player) && !demo.freecam) - S_StartSound(NULL, ((player->roulettetype == 1) ? sfx_itrolk : (mashed ? sfx_itrolm : sfx_itrolf))); - - player->karthud[khud_itemblink] = TICRATE; - player->karthud[khud_itemblinkmode] = ((player->roulettetype == 1) ? 2 : (mashed ? 1 : 0)); - - player->itemroulette = 0; // Since we're done, clear the roulette number - player->roulettetype = 0; // This too -} - //} //{ SRB2kart p_user.c Stuff @@ -7040,7 +6067,6 @@ mobj_t *K_CreatePaperItem(fixed_t x, fixed_t y, fixed_t z, angle_t angle, SINT8 spawnchance[i] = (totalspawnchance += K_KartGetItemOdds( useodds, i, UINT32_MAX, - 0, false, false) ); } @@ -10046,10 +9072,9 @@ void K_StripItems(player_t *player) player->itemamount = 0; player->pflags &= ~(PF_ITEMOUT|PF_EGGMANOUT); - if (!player->itemroulette || player->roulettetype != 2) + if (player->itemRoulette.eggman == false) { - player->itemroulette = 0; - player->roulettetype = 0; + player->itemRoulette.active = false; } player->hyudorotimer = 0; @@ -10065,8 +9090,7 @@ void K_StripItems(player_t *player) void K_StripOther(player_t *player) { - player->itemroulette = 0; - player->roulettetype = 0; + player->itemRoulette.active = false; player->invincibilitytimer = 0; if (player->growshrinktimer) @@ -10086,7 +9110,7 @@ void K_StripOther(player_t *player) static INT32 K_FlameShieldMax(player_t *player) { UINT32 disttofinish = 0; - UINT32 distv = DISTVAR; + UINT32 distv = 2048; UINT8 numplayers = 0; UINT8 i; @@ -10758,7 +9782,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) if (player->itemtype == KITEM_NONE && NO_HYUDORO && !(HOLDING_ITEM || player->itemamount - || player->itemroulette + || player->itemRoulette.active == true || player->rocketsneakertimer || player->eggmanexplode)) player->pflags |= PF_USERINGS; diff --git a/src/k_kart.h b/src/k_kart.h index cddf3d503..83d54b898 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -50,14 +50,6 @@ void K_ReduceVFX(mobj_t *mo, player_t *owner); boolean K_IsPlayerLosing(player_t *player); fixed_t K_GetKartGameSpeedScalar(SINT8 value); -extern consvar_t *KartItemCVars[NUMKARTRESULTS-1]; - -UINT8 K_FindUseodds(player_t *player, fixed_t mashed, UINT32 pdis, UINT8 bestbumper); -fixed_t K_ItemOddsScale(UINT8 numPlayers); -UINT32 K_ScaleItemDistance(UINT32 distance, UINT8 numPlayers); -INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, UINT32 ourDist, fixed_t mashed, boolean bot, boolean rival); -INT32 K_GetRollingRouletteItem(player_t *player); -boolean K_ForcedSPB(player_t *player); INT32 K_GetShieldFromItem(INT32 item); SINT8 K_ItemResultToType(SINT8 getitem); UINT8 K_ItemResultToAmount(SINT8 getitem); diff --git a/src/k_menudraw.c b/src/k_menudraw.c index 8bfec4716..71f8b4242 100644 --- a/src/k_menudraw.c +++ b/src/k_menudraw.c @@ -3455,7 +3455,7 @@ void M_DrawItemToggles(void) continue; } - cv = KartItemCVars[currentMenu->menuitems[thisitem].mvar1-1]; + cv = &cv_items[currentMenu->menuitems[thisitem].mvar1-1]; translucent = (cv->value ? 0 : V_TRANSLUCENT); drawnum = K_ItemResultToAmount(currentMenu->menuitems[thisitem].mvar1); @@ -3502,7 +3502,7 @@ void M_DrawItemToggles(void) } else { - cv = KartItemCVars[currentMenu->menuitems[itemOn].mvar1-1]; + cv = &cv_items[currentMenu->menuitems[itemOn].mvar1-1]; translucent = (cv->value ? 0 : V_TRANSLUCENT); drawnum = K_ItemResultToAmount(currentMenu->menuitems[itemOn].mvar1); diff --git a/src/k_menufunc.c b/src/k_menufunc.c index ab43217ff..384905f71 100644 --- a/src/k_menufunc.c +++ b/src/k_menufunc.c @@ -5632,12 +5632,12 @@ void M_HandleItemToggles(INT32 choice) else if (currentMenu->menuitems[itemOn].mvar1 == 0) { - INT32 v = cv_sneaker.value; + INT32 v = cv_items[0].value; S_StartSound(NULL, sfx_s1b4); for (i = 0; i < NUMKARTRESULTS-1; i++) { - if (KartItemCVars[i]->value == v) - CV_AddValue(KartItemCVars[i], 1); + if (cv_items[i].value == v) + CV_AddValue(&cv_items[i], 1); } } else @@ -5650,7 +5650,7 @@ void M_HandleItemToggles(INT32 choice) { S_StartSound(NULL, sfx_s1ba); } - CV_AddValue(KartItemCVars[currentMenu->menuitems[itemOn].mvar1-1], 1); + CV_AddValue(&cv_items[currentMenu->menuitems[itemOn].mvar1-1], 1); } } diff --git a/src/k_roulette.c b/src/k_roulette.c new file mode 100644 index 000000000..df16eba5f --- /dev/null +++ b/src/k_roulette.c @@ -0,0 +1,1001 @@ +// DR. ROBOTNIK'S RING RACERS +//----------------------------------------------------------------------------- +// Copyright (C) 2022 by Kart Krew +// Copyright (C) 2022 by Sally "TehRealSalt" Cochenour +// +// 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_roulette.c +/// \brief Item roulette code. + +#include "k_roulette.h" + +#include "d_player.h" +#include "doomdef.h" +#include "hu_stuff.h" +#include "g_game.h" +#include "m_random.h" +#include "p_local.h" +#include "p_slopes.h" +#include "p_setup.h" +#include "r_draw.h" +#include "r_local.h" +#include "r_things.h" +#include "s_sound.h" +#include "st_stuff.h" +#include "v_video.h" +#include "z_zone.h" +#include "m_misc.h" +#include "m_cond.h" +#include "f_finale.h" +#include "lua_hud.h" // For Lua hud checks +#include "lua_hook.h" // For MobjDamage and ShouldDamage +#include "m_cheat.h" // objectplacing +#include "p_spec.h" + +#include "k_kart.h" +#include "k_battle.h" +#include "k_boss.h" +#include "k_pwrlv.h" +#include "k_color.h" +#include "k_respawn.h" +#include "k_waypoint.h" +#include "k_bot.h" +#include "k_hud.h" +#include "k_terrain.h" +#include "k_director.h" +#include "k_collide.h" +#include "k_follower.h" +#include "k_objects.h" +#include "k_grandprix.h" +#include "k_specialstage.h" + +// Magic number distance for use with item roulette tiers +#define DISTVAR (2048) + +// Distance when SPB can start appearing +#define SPBSTARTDIST (8*DISTVAR) + +// Distance when SPB is forced onto the next person who rolls an item +#define SPBFORCEDIST (14*DISTVAR) + +// Distance when the game stops giving you bananas +#define ENDDIST (12*DISTVAR) + +// Consistent seed used for item reels +#define ITEM_REEL_SEED (0x22D5FAA8) + +static UINT8 K_KartItemOddsRace[NUMKARTRESULTS-1][8] = +{ + { 0, 0, 2, 3, 4, 0, 0, 0 }, // Sneaker + { 0, 0, 0, 0, 0, 3, 4, 5 }, // Rocket Sneaker + { 0, 0, 0, 0, 2, 5, 5, 7 }, // Invincibility + { 2, 3, 1, 0, 0, 0, 0, 0 }, // Banana + { 1, 2, 0, 0, 0, 0, 0, 0 }, // Eggman Monitor + { 5, 5, 2, 2, 0, 0, 0, 0 }, // Orbinaut + { 0, 4, 2, 1, 0, 0, 0, 0 }, // Jawz + { 0, 3, 3, 2, 0, 0, 0, 0 }, // Mine + { 3, 0, 0, 0, 0, 0, 0, 0 }, // Land Mine + { 0, 0, 2, 2, 0, 0, 0, 0 }, // Ballhog + { 0, 0, 0, 0, 0, 2, 4, 0 }, // Self-Propelled Bomb + { 0, 0, 0, 0, 2, 5, 0, 0 }, // Grow + { 0, 0, 0, 0, 0, 2, 4, 2 }, // Shrink + { 1, 0, 0, 0, 0, 0, 0, 0 }, // Lightning Shield + { 0, 1, 2, 1, 0, 0, 0, 0 }, // Bubble Shield + { 0, 0, 0, 0, 0, 1, 3, 5 }, // Flame Shield + { 3, 0, 0, 0, 0, 0, 0, 0 }, // Hyudoro + { 0, 0, 0, 0, 0, 0, 0, 0 }, // Pogo Spring + { 2, 1, 1, 0, 0, 0, 0, 0 }, // Super Ring + { 0, 0, 0, 0, 0, 0, 0, 0 }, // Kitchen Sink + { 3, 0, 0, 0, 0, 0, 0, 0 }, // Drop Target + { 0, 0, 0, 3, 5, 0, 0, 0 }, // Garden Top + { 0, 0, 2, 2, 2, 0, 0, 0 }, // Sneaker x2 + { 0, 0, 0, 0, 4, 4, 4, 0 }, // Sneaker x3 + { 0, 1, 1, 0, 0, 0, 0, 0 }, // Banana x3 + { 0, 0, 1, 0, 0, 0, 0, 0 }, // Orbinaut x3 + { 0, 0, 0, 2, 0, 0, 0, 0 }, // Orbinaut x4 + { 0, 0, 1, 2, 1, 0, 0, 0 } // Jawz x2 +}; + +static UINT8 K_KartItemOddsBattle[NUMKARTRESULTS][2] = +{ + //K L + { 2, 1 }, // Sneaker + { 0, 0 }, // Rocket Sneaker + { 4, 1 }, // Invincibility + { 0, 0 }, // Banana + { 1, 0 }, // Eggman Monitor + { 8, 0 }, // Orbinaut + { 8, 1 }, // Jawz + { 6, 1 }, // Mine + { 2, 0 }, // Land Mine + { 2, 1 }, // Ballhog + { 0, 0 }, // Self-Propelled Bomb + { 2, 1 }, // Grow + { 0, 0 }, // Shrink + { 4, 0 }, // Lightning Shield + { 1, 0 }, // Bubble Shield + { 1, 0 }, // Flame Shield + { 2, 0 }, // Hyudoro + { 3, 0 }, // Pogo Spring + { 0, 0 }, // Super Ring + { 0, 0 }, // Kitchen Sink + { 2, 0 }, // Drop Target + { 4, 0 }, // Garden Top + { 0, 0 }, // Sneaker x2 + { 0, 1 }, // Sneaker x3 + { 0, 0 }, // Banana x3 + { 2, 0 }, // Orbinaut x3 + { 1, 1 }, // Orbinaut x4 + { 5, 1 } // Jawz x2 +}; + +static kartitems_t K_KartItemReelTimeAttack[] = +{ + KITEM_SNEAKER, + KITEM_SUPERRING, + KITEM_NONE +}; + +static kartitems_t K_KartItemReelBreakTheCapsules[] = +{ + KRITEM_TRIPLEORBINAUT, + KITEM_BANANA, + KITEM_NONE +}; + +#if 0 +static kartitems_t K_KartItemReelBoss[] = +{ + KITEM_ORBINAUT, + KITEM_BANANA, + KITEM_NONE +}; +#endif + +boolean K_ItemEnabled(SINT8 item) +{ + if (item < 1 || item >= NUMKARTRESULTS) + { + // Not a real item. + return false; + } + + if (K_CanChangeRules(true) == false) + { + // Force all items to be enabled. + return true; + } + + // Allow the user preference. + return cv_items[item - 1].value; +} + +fixed_t K_ItemOddsScale(UINT8 playerCount) +{ + const UINT8 basePlayer = 8; // The player count we design most of the game around. + fixed_t playerScaling = 0; + + if (playerCount < 2) + { + // Cap to 1v1 scaling + playerCount = 2; + } + + // Then, it multiplies it further if the player count isn't equal to basePlayer. + // This is done to make low player count races more interesting and high player count rates more fair. + if (playerCount < basePlayer) + { + // Less than basePlayer: increase odds significantly. + // 2P: x2.5 + playerScaling = (basePlayer - playerCount) * (FRACUNIT / 4); + } + else if (playerCount > basePlayer) + { + // More than basePlayer: reduce odds slightly. + // 16P: x0.75 + playerScaling = (basePlayer - playerCount) * (FRACUNIT / 32); + } + + return playerScaling; +} + +UINT32 K_ScaleItemDistance(UINT32 distance, UINT8 numPlayers) +{ + if (mapobjectscale != FRACUNIT) + { + // Bring back to normal scale. + distance = FixedDiv(distance, mapobjectscale); + } + + if (franticitems == true) + { + // Frantic items pretends everyone's farther apart, for crazier items. + distance = (15 * distance) / 14; + } + + // Items get crazier with the fewer players that you have. + distance = FixedMul( + distance, + FRACUNIT + (K_ItemOddsScale(numPlayers) / 2) + ); + + return distance; +} + +UINT32 K_GetItemRouletteDistance(player_t *const player, UINT8 pingame) +{ + UINT32 pdis = 0; + +#if 0 + if (specialStage.active == true) + { + UINT32 ufoDis = K_GetSpecialUFODistance(); + + if (player->distancetofinish <= ufoDis) + { + // You're ahead of the UFO. + pdis = 0; + } + else + { + // Subtract the UFO's distance from your distance! + pdis = player->distancetofinish - ufoDis; + } + } + else +#endif + { + UINT8 i; + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i] && !players[i].spectator + && players[i].position == 1) + { + // This player is first! Yay! + + if (player->distancetofinish <= players[i].distancetofinish) + { + // Guess you're in first / tied for first? + pdis = 0; + } + else + { + // Subtract 1st's distance from your distance, to get your distance from 1st! + pdis = player->distancetofinish - players[i].distancetofinish; + } + break; + } + } + } + + pdis = K_ScaleItemDistance(pdis, pingame); + + if (player->bot && player->botvars.rival) + { + // Rival has better odds :) + pdis = (15 * pdis) / 14; + } + + return pdis; +} + +/** \brief Item Roulette for Kart + + \param player player object passed from P_KartPlayerThink + + \return void +*/ + +INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, UINT32 ourDist, boolean bot, boolean rival) +{ + fixed_t newOdds; + INT32 i; + + UINT8 pingame = 0, pexiting = 0; + + player_t *first = NULL; + player_t *second = NULL; + + UINT32 firstDist = UINT32_MAX; + UINT32 secondDist = UINT32_MAX; + UINT32 secondToFirst = 0; + boolean isFirst = false; + + boolean powerItem = false; + boolean cooldownOnStart = false; + boolean notNearEnd = false; + + INT32 shieldType = KSHIELD_NONE; + + I_Assert(item > KITEM_NONE); // too many off by one scenarioes. + I_Assert(cv_items[NUMKARTRESULTS-2] != NULL); // Make sure this exists + + if (K_ItemEnabled(item) == false) + { + return 0; + } + + if (K_GetItemCooldown(item) > 0) + { + // Cooldown is still running, don't give another. + return 0; + } + + /* + if (bot) + { + // TODO: Item use on bots should all be passed-in functions. + // Instead of manually inserting these, it should return 0 + // for any items without an item use function supplied + + switch (item) + { + case KITEM_SNEAKER: + break; + default: + return 0; + } + } + */ + (void)bot; + + if (gametype == GT_BATTLE) + { + I_Assert(pos < 2); // DO NOT allow positions past the bounds of the table + newOdds = K_KartItemOddsBattle[item-1][pos]; + } + else + { + I_Assert(pos < 8); // Ditto + newOdds = K_KartItemOddsRace[item-1][pos]; + } + + newOdds <<= FRACBITS; + + shieldType = K_GetShieldFromItem(item); + + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i] || players[i].spectator) + { + continue; + } + + if (!(gametyperules & GTR_BUMPERS) || players[i].bumpers) + { + pingame++; + } + + if (players[i].exiting) + { + pexiting++; + } + + switch (shieldType) + { + case KSHIELD_NONE: + /* Marble Garden Top is not REALLY + a Sonic 3 shield */ + case KSHIELD_TOP: + { + break; + } + + default: + { + if (shieldType == K_GetShieldFromItem(players[i].itemtype)) + { + // Don't allow more than one of each shield type at a time + return 0; + } + } + } + + if (players[i].position == 1) + { + first = &players[i]; + } + + if (players[i].position == 2) + { + second = &players[i]; + } + } + + if (first != NULL) // calculate 2nd's distance from 1st, for SPB + { + firstDist = first->distancetofinish; + isFirst = (ourDist <= firstDist); + } + + if (second != NULL) + { + secondDist = second->distancetofinish; + } + + if (first != NULL && second != NULL) + { + secondToFirst = secondDist - firstDist; + secondToFirst = K_ScaleItemDistance(secondToFirst, 16 - pingame); // Reversed scaling, so 16P is like 1v1, and 1v1 is like 16P + } + + switch (item) + { + case KITEM_BANANA: + case KITEM_EGGMAN: + case KITEM_SUPERRING: + { + notNearEnd = true; + break; + } + + case KITEM_ROCKETSNEAKER: + case KITEM_JAWZ: + case KITEM_LANDMINE: + case KITEM_DROPTARGET: + case KITEM_BALLHOG: + case KITEM_HYUDORO: + case KRITEM_TRIPLESNEAKER: + case KRITEM_TRIPLEORBINAUT: + case KRITEM_QUADORBINAUT: + case KRITEM_DUALJAWZ: + { + powerItem = true; + break; + } + + case KRITEM_TRIPLEBANANA: + { + powerItem = true; + notNearEnd = true; + break; + } + + case KITEM_INVINCIBILITY: + case KITEM_MINE: + case KITEM_GROW: + case KITEM_BUBBLESHIELD: + case KITEM_FLAMESHIELD: + { + cooldownOnStart = true; + powerItem = true; + break; + } + + case KITEM_SPB: + { + cooldownOnStart = true; + notNearEnd = true; + + if (firstDist < ENDDIST*2 // No SPB when 1st is almost done + || isFirst == true) // No SPB for 1st ever + { + newOdds = 0; + } + else + { + const UINT32 dist = max(0, ((signed)secondToFirst) - SPBSTARTDIST); + const UINT32 distRange = SPBFORCEDIST - SPBSTARTDIST; + const UINT8 maxOdds = 20; + fixed_t multiplier = (dist * FRACUNIT) / distRange; + + if (multiplier < 0) + { + multiplier = 0; + } + + if (multiplier > FRACUNIT) + { + multiplier = FRACUNIT; + } + + newOdds = FixedMul(maxOdds << FRACBITS, multiplier); + } + break; + } + + case KITEM_SHRINK: + cooldownOnStart = true; + powerItem = true; + notNearEnd = true; + + if (pingame-1 <= pexiting) + { + newOdds = 0; + } + break; + + case KITEM_LIGHTNINGSHIELD: + cooldownOnStart = true; + powerItem = true; + + if (spbplace != -1) + { + newOdds = 0; + } + break; + + default: + break; + } + + if (newOdds == 0) + { + // Nothing else we want to do with odds matters at this point :p + return newOdds; + } + + if ((cooldownOnStart == true) && (leveltime < (30*TICRATE)+starttime)) + { + // This item should not appear at the beginning of a race. (Usually really powerful crowd-breaking items) + newOdds = 0; + } + else if ((notNearEnd == true) && (ourDist < ENDDIST)) + { + // This item should not appear at the end of a race. (Usually trap items that lose their effectiveness) + newOdds = 0; + } + else if (powerItem == true) + { + // This item is a "power item". This activates "frantic item" toggle related functionality. + if (franticitems == true) + { + // First, power items multiply their odds by 2 if frantic items are on; easy-peasy. + newOdds *= 2; + } + + if (rival == true) + { + // The Rival bot gets frantic-like items, also :p + newOdds *= 2; + } + + newOdds = FixedMul(newOdds, FRACUNIT + K_ItemOddsScale(pingame)); + } + + return FixedInt(FixedRound(newOdds)); +} + +//{ SRB2kart Roulette Code - Distance Based, yes waypoints + +UINT8 K_FindUseodds(player_t *const player, UINT32 playerDist) +{ + UINT8 i; + UINT8 useOdds = 0; + UINT8 distTable[14]; + UINT8 distLen = 0; + UINT8 totalSize = 0; + boolean oddsValid[8]; + + for (i = 0; i < 8; i++) + { + UINT8 j; + + if (gametype == GT_BATTLE && i > 1) + { + oddsValid[i] = false; + break; + } + + for (j = 1; j < NUMKARTRESULTS; j++) + { + if (K_KartGetItemOdds( + i, j, + player->distancetofinish, + player->bot, (player->bot && player->botvars.rival) + ) > 0) + { + break; + } + } + + oddsValid[i] = (j < NUMKARTRESULTS); + } + +#define SETUPDISTTABLE(odds, num) \ + totalSize += num; \ + if (oddsValid[odds]) \ + for (i = num; i; --i) \ + distTable[distLen++] = odds; + + if (gametype == GT_BATTLE) // Battle Mode + { + useOdds = 0; + } + else + { + SETUPDISTTABLE(0,1); + SETUPDISTTABLE(1,1); + SETUPDISTTABLE(2,1); + SETUPDISTTABLE(3,2); + SETUPDISTTABLE(4,2); + SETUPDISTTABLE(5,3); + SETUPDISTTABLE(6,3); + SETUPDISTTABLE(7,1); + + for (i = 0; i < totalSize; i++) + { + fixed_t pos = 0; + fixed_t dist = 0; + UINT8 index = 0; + + if (i == totalSize-1) + { + useOdds = distTable[distLen - 1]; + break; + } + + pos = ((i << FRACBITS) * distLen) / totalSize; + dist = FixedMul(DISTVAR << FRACBITS, pos) >> FRACBITS; + index = FixedInt(FixedRound(pos)); + + if (playerDist <= (unsigned)dist) + { + useOdds = distTable[index]; + break; + } + } + } + +#undef SETUPDISTTABLE + + return useOdds; +} + +boolean K_ForcedSPB(player_t *const player) +{ + player_t *first = NULL; + player_t *second = NULL; + UINT32 secondToFirst = UINT32_MAX; + UINT8 pingame = 0; + UINT8 i; + + if (K_ItemEnabled(KITEM_SPB) == false) + { + return false; + } + + if (!(gametyperules & GTR_CIRCUIT)) + { + return false; + } + + if (player->position <= 1) + { + return false; + } + + if (spbplace != -1) + { + return false; + } + + if (itemCooldowns[KITEM_SPB - 1] > 0) + { + return false; + } + + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i] || players[i].spectator) + { + continue; + } + + if (players[i].exiting) + { + return false; + } + + pingame++; + + if (players[i].position == 1) + { + first = &players[i]; + } + + if (players[i].position == 2) + { + second = &players[i]; + } + } + +#if 0 + if (pingame <= 2) + { + return false; + } +#endif + + if (first != NULL && second != NULL) + { + secondToFirst = second->distancetofinish - first->distancetofinish; + secondToFirst = K_ScaleItemDistance(secondToFirst, 16 - pingame); + } + + return (secondToFirst >= SPBFORCEDIST); +} + +static void K_InitRoulette(itemroulette_t *const roulette) +{ + if (roulette->itemList == NULL) + { + roulette->itemListCap = 8; + roulette->itemList = Z_Calloc( + sizeof(SINT8) * roulette->itemListCap, + PU_LEVEL, + &roulette->itemList + ); + } + + memset(roulette->itemList, KITEM_NONE, sizeof(SINT8) * roulette->itemListCap); + roulette->itemListLen = 0; + + roulette->index = 0; + roulette->elapsed = 0; + roulette->tics = roulette->speed = 3; // Some default speed + roulette->active = true; +} + +static void K_PushToRouletteItemList(itemroulette_t *const roulette, kartitems_t item) +{ + I_Assert(roulette->itemList != NULL); + + if (roulette->itemListLen >= roulette->itemListCap) + { + roulette->itemListCap *= 2; + roulette->itemList = Z_Realloc( + roulette->itemList, + sizeof(SINT8) * roulette->itemListCap, + PU_LEVEL, + &roulette->itemList + ); + } + + roulette->itemList[ roulette->itemListLen ] = item; + roulette->itemListLen++; +} + +static void K_CalculateRouletteSpeed(player_t *const player, itemroulette_t *const roulette, UINT8 playing) +{ + // TODO: Change speed based on two factors: + // - Get faster when your distancetofinish is closer to 1st place's distancetofinish. (winning) + // - Get faster based on overall distancetofinish (race progress) + // Slowest speed should be 12 tics, fastest should be 3 tics. + + (void)player; + (void)playing; + + roulette->tics = roulette->speed = 7; +} + +void K_StartItemRoulette(player_t *const player, itemroulette_t *const roulette) +{ + UINT8 playing = 0; + UINT32 playerDist = UINT32_MAX; + + UINT8 useOdds = 0; + UINT32 spawnChance[NUMKARTRESULTS] = {0}; + UINT32 totalSpawnChance = 0; + size_t rngRoll = 0; + + size_t i; + + K_InitRoulette(roulette); + + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i] == false || players[i].spectator == true) + { + continue; + } + + playing++; + } + + K_CalculateRouletteSpeed(player, roulette, playing); + + // SPECIAL CASE No. 1: + // Give only the debug item if specified + if (cv_kartdebugitem.value != KITEM_NONE) + { + K_PushToRouletteItemList(roulette, cv_kartdebugitem.value); + return; + } + + // SPECIAL CASE No. 2: + // Use a special, pre-determined item reel for Time Attack / Free Play + if (modeattacking || playing <= 1) + { + switch (gametype) + { + case GT_RACE: + default: + { + for (i = 0; K_KartItemReelTimeAttack[i] != KITEM_NONE; i++) + { + K_PushToRouletteItemList(roulette, K_KartItemReelTimeAttack[i]); + CONS_Printf("Added %d\n", K_KartItemReelTimeAttack[i]); + } + break; + } + case GT_BATTLE: + { + for (i = 0; K_KartItemReelBreakTheCapsules[i] != KITEM_NONE; i++) + { + K_PushToRouletteItemList(roulette, K_KartItemReelBreakTheCapsules[i]); + CONS_Printf("Added %d\n", K_KartItemReelBreakTheCapsules[i]); + } + break; + } + } + + return; + } + + // SPECIAL CASE No. 3: + // Only give the SPB if conditions are right + if (K_ForcedSPB(player) == true) + { + K_PushToRouletteItemList(roulette, KITEM_SPB); + return; + } + + playerDist = K_GetItemRouletteDistance(player, playing); + + useOdds = K_FindUseodds(player, playerDist); + + for (i = 1; i < NUMKARTRESULTS; i++) + { + UINT8 thisItemsOdds = K_KartGetItemOdds( + useOdds, i, + player->distancetofinish, + player->bot, (player->bot && player->botvars.rival) + ); + + spawnChance[i] = (totalSpawnChance += thisItemsOdds); + } + + // SPECIAL CASE No. 4: + // All items are off, so give a placeholder item + if (totalSpawnChance == 0) + { + K_PushToRouletteItemList(roulette, KITEM_SAD); + return; + } + + // We always want the same result when making the same item reel. + P_SetRandSeed(PR_ITEM_ROULETTE, ITEM_REEL_SEED); + + while (totalSpawnChance > 0) + { + rngRoll = P_RandomKey(PR_ITEM_ROULETTE, totalSpawnChance); + + for (i = 0; i < NUMKARTRESULTS && spawnChance[i] <= rngRoll; i++) + { + continue; + } + + K_PushToRouletteItemList(roulette, i); + + // If we're in ring debt, pad out the reel with + // a BUNCH of Super Rings. + if (K_ItemEnabled(KITEM_SUPERRING) + && player->rings < 0 + && !(gametyperules & GTR_SPHERES)) + { + K_PushToRouletteItemList(roulette, KITEM_SUPERRING); + } + + spawnChance[i]--; + totalSpawnChance--; + } +} + +void K_StartEggmanRoulette(player_t *const player) +{ + itemroulette_t *const roulette = &player->itemRoulette; + + K_InitRoulette(roulette); + K_PushToRouletteItemList(roulette, KITEM_EGGEXPLODE); + roulette->eggman = true; +} + +/** \brief Item Roulette for Kart + + \param player player + \param getitem what item we're looking for + + \return void +*/ +static void K_KartGetItemResult(player_t *const player, kartitems_t getitem) +{ + if (getitem == KITEM_SPB || getitem == KITEM_SHRINK) + { + K_SetItemCooldown(getitem, 20*TICRATE); + } + + player->botvars.itemdelay = TICRATE; + player->botvars.itemconfirm = 0; + + player->itemtype = K_ItemResultToType(getitem); + player->itemamount = K_ItemResultToAmount(getitem); +} + +void K_KartItemRoulette(player_t *const player, ticcmd_t *const cmd) +{ + itemroulette_t *const roulette = &player->itemRoulette; + boolean confirmItem = false; + + // This makes the roulette cycle through items. + // If this isn't active, you shouldn't be here. + if (roulette->active == false) + { + return; + } + + if (roulette->itemList == NULL || roulette->itemListLen == 0) + { + // Invalid roulette setup. + // Escape before we run into issues. + roulette->active = false; + return; + } + + if (roulette->elapsed > TICRATE>>1) // Prevent accidental immediate item confirm + { + if (roulette->elapsed > TICRATE<<4) + { + // Waited way too long, forcefully confirm the item. + confirmItem = true; + } + else + { + // We can stop our item when we choose. + confirmItem = !!(cmd->buttons & BT_ATTACK); + } + } + + // If the roulette finishes or the player presses BT_ATTACK, stop the roulette and calculate the item. + // I'm returning via the exact opposite, however, to forgo having another bracket embed. Same result either way, I think. + // Finally, if you get past this check, now you can actually start calculating what item you get. + if (confirmItem == true && (player->pflags & (PF_ITEMOUT|PF_EGGMANOUT|PF_USERINGS)) == 0) + { + kartitems_t finalItem = roulette->itemList[ roulette->index ]; + + K_KartGetItemResult(player, finalItem); + player->karthud[khud_itemblink] = TICRATE; + + if (P_IsDisplayPlayer(player) && !demo.freecam) + { + S_StartSound(NULL, sfx_itrolf); + } + + // We're done, disable the roulette + roulette->active = false; + return; + } + + roulette->elapsed++; + + if (roulette->tics == 0) + { + roulette->index = (roulette->index + 1) % roulette->itemListLen; + roulette->tics = roulette->speed; + + // This makes the roulette produce the random noises. + roulette->sound = (roulette->sound + 1) % 8; + + if (P_IsDisplayPlayer(player) && !demo.freecam) + { + S_StartSound(NULL, sfx_itrol1 + roulette->sound); + } + } + else + { + roulette->tics--; + } +} diff --git a/src/k_roulette.h b/src/k_roulette.h new file mode 100644 index 000000000..8fd302abf --- /dev/null +++ b/src/k_roulette.h @@ -0,0 +1,35 @@ +// DR. ROBOTNIK'S RING RACERS +//----------------------------------------------------------------------------- +// Copyright (C) 2022 by Kart Krew +// Copyright (C) 2022 by Sally "TehRealSalt" Cochenour +// +// 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_roulette.h +/// \brief Item roulette code. + +#ifndef __K_ROULETTE_H__ +#define __K_ROULETTE_H__ + +#include "doomtype.h" +#include "d_player.h" + +boolean K_ItemEnabled(SINT8 item); + +fixed_t K_ItemOddsScale(UINT8 playerCount); +UINT32 K_ScaleItemDistance(UINT32 distance, UINT8 numPlayers); +UINT32 K_GetItemRouletteDistance(player_t *const player, UINT8 pingame); + +INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, UINT32 ourDist, boolean bot, boolean rival); +UINT8 K_FindUseodds(player_t *const player, UINT32 playerDist); + +boolean K_ForcedSPB(player_t *const player); + +void K_StartItemRoulette(player_t *const player, itemroulette_t *const roulette); +void K_StartEggmanRoulette(player_t *const player); + +void K_KartItemRoulette(player_t *const player, ticcmd_t *cmd); + +#endif // __K_ROULETTE_H__ diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 2a3b9e46a..b69449ba2 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -304,10 +304,10 @@ static int player_get(lua_State *L) lua_pushinteger(L, plr->tripwirePass); else if (fastcmp(field,"tripwireLeniency")) lua_pushinteger(L, plr->tripwireLeniency); + /* else if (fastcmp(field,"itemroulette")) lua_pushinteger(L, plr->itemroulette); - else if (fastcmp(field,"roulettetype")) - lua_pushinteger(L, plr->roulettetype); + */ else if (fastcmp(field,"itemtype")) lua_pushinteger(L, plr->itemtype); else if (fastcmp(field,"itemamount")) @@ -680,10 +680,10 @@ static int player_set(lua_State *L) plr->tripwirePass = luaL_checkinteger(L, 3); else if (fastcmp(field,"tripwireLeniency")) plr->tripwireLeniency = luaL_checkinteger(L, 3); + /* else if (fastcmp(field,"itemroulette")) plr->itemroulette = luaL_checkinteger(L, 3); - else if (fastcmp(field,"roulettetype")) - plr->roulettetype = luaL_checkinteger(L, 3); + */ else if (fastcmp(field,"itemtype")) plr->itemtype = luaL_checkinteger(L, 3); else if (fastcmp(field,"itemamount")) diff --git a/src/p_enemy.c b/src/p_enemy.c index 131e92bf7..636eb500a 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -34,6 +34,7 @@ #include "k_respawn.h" #include "k_collide.h" #include "k_objects.h" +#include "k_roulette.h" #ifdef HW3SOUND #include "hardware/hw3sound.h" @@ -13042,9 +13043,13 @@ void A_ItemPop(mobj_t *actor) Obj_SpawnItemDebrisEffects(actor, actor->target); if (locvar1 == 1) + { P_GivePlayerSpheres(actor->target->player, actor->extravalue1); + } else if (locvar1 == 0) - actor->target->player->itemroulette = 1; + { + K_StartItemRoulette(actor->target->player, &actor->target->player->itemRoulette); + } // Here at mapload in battle? if ((gametyperules & GTR_BUMPERS) && (actor->flags2 & MF2_BOSSNOTRAP)) diff --git a/src/p_inter.c b/src/p_inter.c index 76757f193..2c05f5732 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -38,6 +38,7 @@ #include "k_respawn.h" #include "p_spec.h" #include "k_objects.h" +#include "k_roulette.h" // CTF player names #define CTFTEAMCODE(pl) pl->ctfteam ? (pl->ctfteam == 1 ? "\x85" : "\x84") : "" @@ -130,7 +131,7 @@ boolean P_CanPickupItem(player_t *player, UINT8 weapon) return false; // Already have fake - if (player->roulettetype == 2 + if (player->itemRoulette.eggman == true || player->eggmanexplode) return false; } @@ -143,7 +144,7 @@ boolean P_CanPickupItem(player_t *player, UINT8 weapon) return false; // Item slot already taken up - if (player->itemroulette + if (player->itemRoulette.active == true || (weapon != 3 && player->itemamount) || (player->pflags & PF_ITEMOUT)) return false; @@ -411,8 +412,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (special->fuse || !P_CanPickupItem(player, 1) || ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0)) return; - player->itemroulette = 1; - player->roulettetype = 1; + K_StartItemRoulette(player, &player->itemRoulette); // Karma fireworks for (i = 0; i < 5; i++) @@ -1449,8 +1449,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget } player->karthud[khud_itemblink] = TICRATE; player->karthud[khud_itemblinkmode] = 0; - player->itemroulette = 0; - player->roulettetype = 0; + player->itemRoulette.active = false; if (P_IsDisplayPlayer(player)) S_StartSound(NULL, sfx_itrolf); } diff --git a/src/p_mobj.c b/src/p_mobj.c index 340e40e52..d48fa6de8 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6124,7 +6124,7 @@ static void P_MobjSceneryThink(mobj_t *mobj) break; // see also K_drawKartItem in k_hud.c - case MT_PLAYERARROW: + case MT_PLAYERARROW: // FIXME: Delete this object, attach to name tags instead. if (mobj->target && mobj->target->health && mobj->target->player && !mobj->target->player->spectator && mobj->target->health && mobj->target->player->playerstate != PST_DEAD @@ -6178,7 +6178,7 @@ static void P_MobjSceneryThink(mobj_t *mobj) } // Do this in an easy way - if (mobj->target->player->itemroulette) + if (mobj->target->player->itemRoulette.active) { mobj->tracer->color = mobj->target->player->skincolor; mobj->tracer->colorized = true; @@ -6194,11 +6194,11 @@ static void P_MobjSceneryThink(mobj_t *mobj) const INT32 numberdisplaymin = ((mobj->target->player->itemtype == KITEM_ORBINAUT) ? 5 : 2); // Set it to use the correct states for its condition - if (mobj->target->player->itemroulette) + if (mobj->target->player->itemRoulette.active) { P_SetMobjState(mobj, S_PLAYERARROW_BOX); mobj->tracer->sprite = SPR_ITEM; - mobj->tracer->frame = K_GetRollingRouletteItem(mobj->target->player) | FF_FULLBRIGHT; + mobj->tracer->frame = 1 | FF_FULLBRIGHT; mobj->tracer->renderflags &= ~RF_DONTDRAW; } else if (mobj->target->player->stealingtimer < 0) diff --git a/src/p_saveg.c b/src/p_saveg.c index 73d4a7d1f..fee092df9 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -310,9 +310,6 @@ static void P_NetArchivePlayers(void) WRITEUINT8(save_p, players[i].tripwirePass); WRITEUINT16(save_p, players[i].tripwireLeniency); - WRITEUINT16(save_p, players[i].itemroulette); - WRITEUINT8(save_p, players[i].roulettetype); - WRITESINT8(save_p, players[i].itemtype); WRITEUINT8(save_p, players[i].itemamount); WRITESINT8(save_p, players[i].throwdir); @@ -410,6 +407,19 @@ static void P_NetArchivePlayers(void) WRITEUINT32(save_p, players[i].botvars.itemconfirm); WRITESINT8(save_p, players[i].botvars.turnconfirm); WRITEUINT32(save_p, players[i].botvars.spindashconfirm); + + // itemroulette_t + WRITEUINT8(save_p, players[i].itemRoulette.active); + WRITEUINT32(save_p, players[i].itemRoulette.itemListCap); + WRITEUINT32(save_p, players[i].itemRoulette.itemListLen); + for (j = 0; (unsigned)j < players[i].itemRoulette.itemListLen; j++) + { + WRITESINT8(save_p, players[i].itemRoulette.itemList[j]); + } + WRITEUINT32(save_p, players[i].itemRoulette.index); + WRITEUINT32(save_p, players[i].itemRoulette.speed); + WRITEUINT32(save_p, players[i].itemRoulette.tics); + WRITEUINT32(save_p, players[i].itemRoulette.elapsed); } } @@ -612,9 +622,6 @@ static void P_NetUnArchivePlayers(void) players[i].tripwirePass = READUINT8(save_p); players[i].tripwireLeniency = READUINT16(save_p); - players[i].itemroulette = READUINT16(save_p); - players[i].roulettetype = READUINT8(save_p); - players[i].itemtype = READSINT8(save_p); players[i].itemamount = READUINT8(save_p); players[i].throwdir = READSINT8(save_p); @@ -713,6 +720,39 @@ static void P_NetUnArchivePlayers(void) players[i].botvars.turnconfirm = READSINT8(save_p); players[i].botvars.spindashconfirm = READUINT32(save_p); + // itemroulette_t + players[i].itemRoulette.active = READUINT8(save_p); + players[i].itemRoulette.itemListCap = READUINT32(save_p); + players[i].itemRoulette.itemListLen = READUINT32(save_p); + + if (players[i].itemRoulette.itemList == NULL) + { + players[i].itemRoulette.itemList = Z_Calloc( + sizeof(SINT8) * players[i].itemRoulette.itemListCap, + PU_LEVEL, + &players[i].itemRoulette.itemList + ); + } + else + { + players[i].itemRoulette.itemList = Z_Realloc( + players[i].itemRoulette.itemList, + sizeof(SINT8) * players[i].itemRoulette.itemListCap, + PU_LEVEL, + &players[i].itemRoulette.itemList + ); + } + + for (j = 0; (unsigned)j < players[i].itemRoulette.itemListLen; j++) + { + players[i].itemRoulette.itemList[j] = READSINT8(save_p); + } + + players[i].itemRoulette.index = READUINT32(save_p); + players[i].itemRoulette.speed = READUINT32(save_p); + players[i].itemRoulette.tics = READUINT32(save_p); + players[i].itemRoulette.elapsed = READUINT32(save_p); + //players[i].viewheight = P_GetPlayerViewHeight(players[i]); // scale cannot be factored in at this point } } diff --git a/src/typedef.h b/src/typedef.h index db751340c..0c19fa2ac 100644 --- a/src/typedef.h +++ b/src/typedef.h @@ -37,6 +37,7 @@ TYPEDEF (discordRequest_t); TYPEDEF (respawnvars_t); TYPEDEF (botvars_t); TYPEDEF (skybox_t); +TYPEDEF (itemroulette_t); TYPEDEF (player_t); // d_clisrv.h From 534026764c01ff9153b12c0ec4065426a9e3e398 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 12 Dec 2022 00:22:14 -0500 Subject: [PATCH 28/66] Make Eggman Mark actually work --- src/d_player.h | 1 - src/k_roulette.c | 37 +++++++++++++++++++++++++++---------- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index fdcb5bdc4..a8b70f1a7 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -131,7 +131,6 @@ Do with it whatever you want. Run this macro, then #undef FOREACH afterward */ #define KART_ITEM_ITERATOR \ - FOREACH (EGGEXPLODE, -2),\ FOREACH (SAD, -1),\ FOREACH (NONE, 0),\ FOREACH (SNEAKER, 1),\ diff --git a/src/k_roulette.c b/src/k_roulette.c index df16eba5f..c5a493365 100644 --- a/src/k_roulette.c +++ b/src/k_roulette.c @@ -738,6 +738,7 @@ static void K_InitRoulette(itemroulette_t *const roulette) roulette->elapsed = 0; roulette->tics = roulette->speed = 3; // Some default speed roulette->active = true; + roulette->eggman = false; } static void K_PushToRouletteItemList(itemroulette_t *const roulette, kartitems_t item) @@ -898,9 +899,7 @@ void K_StartItemRoulette(player_t *const player, itemroulette_t *const roulette) void K_StartEggmanRoulette(player_t *const player) { itemroulette_t *const roulette = &player->itemRoulette; - - K_InitRoulette(roulette); - K_PushToRouletteItemList(roulette, KITEM_EGGEXPLODE); + K_StartItemRoulette(player, roulette); roulette->eggman = true; } @@ -964,14 +963,32 @@ void K_KartItemRoulette(player_t *const player, ticcmd_t *const cmd) // Finally, if you get past this check, now you can actually start calculating what item you get. if (confirmItem == true && (player->pflags & (PF_ITEMOUT|PF_EGGMANOUT|PF_USERINGS)) == 0) { - kartitems_t finalItem = roulette->itemList[ roulette->index ]; - - K_KartGetItemResult(player, finalItem); - player->karthud[khud_itemblink] = TICRATE; - - if (P_IsDisplayPlayer(player) && !demo.freecam) + if (roulette->eggman == true) { - S_StartSound(NULL, sfx_itrolf); + // FATASS JUMPSCARE instead of your actual item + player->eggmanexplode = 4*TICRATE; + + //player->karthud[khud_itemblink] = TICRATE; + //player->karthud[khud_itemblinkmode] = 1; + + if (P_IsDisplayPlayer(player) && !demo.freecam) + { + S_StartSound(NULL, sfx_itrole); + } + } + else + { + kartitems_t finalItem = roulette->itemList[ roulette->index ]; + + K_KartGetItemResult(player, finalItem); + + player->karthud[khud_itemblink] = TICRATE; + player->karthud[khud_itemblinkmode] = 0; + + if (P_IsDisplayPlayer(player) && !demo.freecam) + { + S_StartSound(NULL, sfx_itrolf); + } } // We're done, disable the roulette From 202c5056648240cc61429dd831eea185d058129a Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 12 Dec 2022 02:18:18 -0500 Subject: [PATCH 29/66] Implement roulette visuals --- src/d_player.h | 1 + src/k_hud.c | 104 ++++++++++++++++++++++++++++++----------------- src/k_kart.c | 5 +++ src/k_roulette.c | 27 +++++++++--- src/k_roulette.h | 3 ++ 5 files changed, 97 insertions(+), 43 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index a8b70f1a7..842edbc0e 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -225,6 +225,7 @@ typedef enum // Item box khud_itemblink, // Item flashing after roulette, serves as a mashing indicator khud_itemblinkmode, // Type of flashing: 0 = white (normal), 1 = red (mashing), 2 = rainbow (enhanced items) + khud_rouletteoffset,// Roulette stop height // Rings khud_ringframe, // Ring spin frame diff --git a/src/k_hud.c b/src/k_hud.c index f92c94a6f..5ba874913 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -1023,7 +1023,7 @@ static void K_drawKartItem(void) // Why write V_DrawScaledPatch calls over and over when they're all the same? // Set to 'no item' just in case. const UINT8 offset = ((r_splitscreen > 1) ? 1 : 0); - patch_t *localpatch = kp_nodraw; + patch_t *localpatch[3] = {kp_nodraw}; patch_t *localbg = ((offset) ? kp_itembg[2] : kp_itembg[0]); patch_t *localinv = ((offset) ? kp_invincibility[((leveltime % (6*3)) / 3) + 7] : kp_invincibility[(leveltime % (7*3)) / 3]); INT32 fx = 0, fy = 0, fflags = 0; // final coords for hud and flags... @@ -1036,28 +1036,42 @@ static void K_drawKartItem(void) UINT8 *colmap = NULL; boolean flipamount = false; // Used for 3P/4P splitscreen to flip item amount stuff + fixed_t rouletteOffset = 0; + const INT32 rouletteBox = 36; + INT32 i; + if (stplyr->itemRoulette.active == true) { - const SINT8 item = K_ItemResultToType(stplyr->itemRoulette.itemList[ stplyr->itemRoulette.index ]); + rouletteOffset = K_GetRouletteOffset(&stplyr->itemRoulette, rendertimefrac); if (stplyr->skincolor) { localcolor = stplyr->skincolor; } - switch (item) + for (i = 0; i < 3; i++) { - case KITEM_INVINCIBILITY: - localpatch = localinv; - break; + const SINT8 indexOfs = i-1; + const size_t index = (stplyr->itemRoulette.index + indexOfs) % stplyr->itemRoulette.itemListLen; - case KITEM_ORBINAUT: - localpatch = kp_orbinaut[3 + offset]; - break; + const SINT8 result = stplyr->itemRoulette.itemList[index]; + const SINT8 item = K_ItemResultToType(result); + const UINT8 amt = K_ItemResultToAmount(result); - default: - localpatch = K_GetCachedItemPatch(item, offset); - break; + switch (item) + { + case KITEM_INVINCIBILITY: + localpatch[i] = localinv; + break; + + case KITEM_ORBINAUT: + localpatch[i] = kp_orbinaut[(offset ? 4 : min(amt-1, 3))]; + break; + + default: + localpatch[i] = K_GetCachedItemPatch(item, offset); + break; + } } } else @@ -1066,23 +1080,26 @@ static void K_drawKartItem(void) // The only actual reason is to make sneakers line up this way in the code below // This shouldn't have any actual baring over how it functions // Hyudoro is first, because we're drawing it on top of the player's current item + + rouletteOffset = stplyr->karthud[khud_rouletteoffset]; + if (stplyr->stealingtimer < 0) { if (leveltime & 2) - localpatch = kp_hyudoro[offset]; + localpatch[0] = kp_hyudoro[offset]; else - localpatch = kp_nodraw; + localpatch[0] = kp_nodraw; } else if ((stplyr->stealingtimer > 0) && (leveltime & 2)) { - localpatch = kp_hyudoro[offset]; + localpatch[0] = kp_hyudoro[offset]; } else if (stplyr->eggmanexplode > 1) { if (leveltime & 1) - localpatch = kp_eggman[offset]; + localpatch[0] = kp_eggman[offset]; else - localpatch = kp_nodraw; + localpatch[0] = kp_nodraw; } else if (stplyr->ballhogcharge > 0) { @@ -1090,9 +1107,9 @@ static void K_drawKartItem(void) maxl = (((stplyr->itemamount-1) * BALLHOGINCREMENT) + 1); if (leveltime & 1) - localpatch = kp_ballhog[offset]; + localpatch[0] = kp_ballhog[offset]; else - localpatch = kp_nodraw; + localpatch[0] = kp_nodraw; } else if (stplyr->rocketsneakertimer > 1) { @@ -1100,16 +1117,16 @@ static void K_drawKartItem(void) maxl = (itemtime*3) - barlength; if (leveltime & 1) - localpatch = kp_rocketsneaker[offset]; + localpatch[0] = kp_rocketsneaker[offset]; else - localpatch = kp_nodraw; + localpatch[0] = kp_nodraw; } else if (stplyr->sadtimer > 0) { if (leveltime & 2) - localpatch = kp_sadface[offset]; + localpatch[0] = kp_sadface[offset]; else - localpatch = kp_nodraw; + localpatch[0] = kp_nodraw; } else { @@ -1119,12 +1136,12 @@ static void K_drawKartItem(void) switch (stplyr->itemtype) { case KITEM_INVINCIBILITY: - localpatch = localinv; + localpatch[0] = localinv; localbg = kp_itembg[offset+1]; break; case KITEM_ORBINAUT: - localpatch = kp_orbinaut[(offset ? 4 : min(stplyr->itemamount-1, 3))]; + localpatch[0] = kp_orbinaut[(offset ? 4 : min(stplyr->itemamount-1, 3))]; break; case KITEM_SPB: @@ -1135,15 +1152,15 @@ static void K_drawKartItem(void) /*FALLTHRU*/ default: - localpatch = K_GetCachedItemPatch(stplyr->itemtype, offset); + localpatch[0] = K_GetCachedItemPatch(stplyr->itemtype, offset); - if (localpatch == NULL) - localpatch = kp_nodraw; // diagnose underflows + if (localpatch[0] == NULL) + localpatch[0] = kp_nodraw; // diagnose underflows break; } if ((stplyr->pflags & PF_ITEMOUT) && !(leveltime & 1)) - localpatch = kp_nodraw; + localpatch[0] = kp_nodraw; } if (stplyr->karthud[khud_itemblink] && (leveltime & 1)) @@ -1194,18 +1211,31 @@ static void K_drawKartItem(void) V_DrawScaledPatch(fx, fy, V_HUDTRANS|V_SLIDEIN|fflags, localbg); - //V_SetClipRect((fx + 10) << FRACBITS, (fy + 10) << FRACBITS, 30 << FRACBITS, 30 << FRACBITS, V_HUDTRANS|V_SLIDEIN|fflags); - - // Then, the numbers: - if (stplyr->itemamount >= numberdisplaymin && stplyr->itemRoulette.active == false) + if (stplyr->itemRoulette.active == true) { + V_SetClipRect((fx + 7) << FRACBITS, (fy + 7) << FRACBITS, rouletteBox << FRACBITS, rouletteBox << FRACBITS, V_HUDTRANS|V_SLIDEIN|fflags); + + // Need to draw these in a particular order, for sorting. + V_DrawFixedPatch(fx<itemamount >= numberdisplaymin && stplyr->itemRoulette.active == false) + { + // Then, the numbers: V_DrawScaledPatch(fx + (flipamount ? 48 : 0), fy, V_HUDTRANS|V_SLIDEIN|fflags|(flipamount ? V_FLIP : 0), kp_itemmulsticker[offset]); // flip this graphic for p2 and p4 in split and shift it. - V_DrawFixedPatch(fx<itemamount)); else V_DrawString(fx+24, fy+31, V_ALLOWLOWERCASE|V_HUDTRANS|V_SLIDEIN|fflags, va("x%d", stplyr->itemamount)); + } else { V_DrawScaledPatch(fy+28, fy+41, V_HUDTRANS|V_SLIDEIN|fflags, kp_itemx); @@ -1213,9 +1243,9 @@ static void K_drawKartItem(void) } } else - V_DrawFixedPatch(fx<karthud[khud_itemblink] = 0; } + if (player->karthud[khud_rouletteoffset] != 0) + { + player->karthud[khud_rouletteoffset] = FixedMul(player->karthud[khud_rouletteoffset], FRACUNIT*3/4); + } + if (!(gametyperules & GTR_SPHERES)) { if (player->mo && player->mo->hitlag <= 0) diff --git a/src/k_roulette.c b/src/k_roulette.c index c5a493365..7e3d7a3b7 100644 --- a/src/k_roulette.c +++ b/src/k_roulette.c @@ -146,14 +146,12 @@ static kartitems_t K_KartItemReelBreakTheCapsules[] = KITEM_NONE }; -#if 0 static kartitems_t K_KartItemReelBoss[] = { KITEM_ORBINAUT, KITEM_BANANA, KITEM_NONE }; -#endif boolean K_ItemEnabled(SINT8 item) { @@ -809,7 +807,16 @@ void K_StartItemRoulette(player_t *const player, itemroulette_t *const roulette) // SPECIAL CASE No. 2: // Use a special, pre-determined item reel for Time Attack / Free Play - if (modeattacking || playing <= 1) + if (bossinfo.boss == true) + { + for (i = 0; K_KartItemReelBoss[i] != KITEM_NONE; i++) + { + K_PushToRouletteItemList(roulette, K_KartItemReelBoss[i]); + } + + return; + } + else if (modeattacking || playing <= 1) { switch (gametype) { @@ -819,7 +826,6 @@ void K_StartItemRoulette(player_t *const player, itemroulette_t *const roulette) for (i = 0; K_KartItemReelTimeAttack[i] != KITEM_NONE; i++) { K_PushToRouletteItemList(roulette, K_KartItemReelTimeAttack[i]); - CONS_Printf("Added %d\n", K_KartItemReelTimeAttack[i]); } break; } @@ -828,7 +834,6 @@ void K_StartItemRoulette(player_t *const player, itemroulette_t *const roulette) for (i = 0; K_KartItemReelBreakTheCapsules[i] != KITEM_NONE; i++) { K_PushToRouletteItemList(roulette, K_KartItemReelBreakTheCapsules[i]); - CONS_Printf("Added %d\n", K_KartItemReelBreakTheCapsules[i]); } break; } @@ -875,7 +880,7 @@ void K_StartItemRoulette(player_t *const player, itemroulette_t *const roulette) { rngRoll = P_RandomKey(PR_ITEM_ROULETTE, totalSpawnChance); - for (i = 0; i < NUMKARTRESULTS && spawnChance[i] <= rngRoll; i++) + for (i = 1; i < NUMKARTRESULTS && spawnChance[i] <= rngRoll; i++) { continue; } @@ -924,6 +929,14 @@ static void K_KartGetItemResult(player_t *const player, kartitems_t getitem) player->itemamount = K_ItemResultToAmount(getitem); } +fixed_t K_GetRouletteOffset(itemroulette_t *const roulette, fixed_t renderDelta) +{ + const fixed_t curTic = (roulette->tics << FRACBITS) - renderDelta; + const fixed_t midTic = roulette->speed * (FRACUNIT >> 1); + + return FixedMul(FixedDiv(midTic - curTic, ((roulette->speed + 1) << FRACBITS)), ROULETTE_SPACING); +} + void K_KartItemRoulette(player_t *const player, ticcmd_t *const cmd) { itemroulette_t *const roulette = &player->itemRoulette; @@ -970,6 +983,7 @@ void K_KartItemRoulette(player_t *const player, ticcmd_t *const cmd) //player->karthud[khud_itemblink] = TICRATE; //player->karthud[khud_itemblinkmode] = 1; + //player->karthud[khud_rouletteoffset] = K_GetRouletteOffset(roulette, FRACUNIT); if (P_IsDisplayPlayer(player) && !demo.freecam) { @@ -984,6 +998,7 @@ void K_KartItemRoulette(player_t *const player, ticcmd_t *const cmd) player->karthud[khud_itemblink] = TICRATE; player->karthud[khud_itemblinkmode] = 0; + player->karthud[khud_rouletteoffset] = K_GetRouletteOffset(roulette, FRACUNIT); if (P_IsDisplayPlayer(player) && !demo.freecam) { diff --git a/src/k_roulette.h b/src/k_roulette.h index 8fd302abf..81e12aae3 100644 --- a/src/k_roulette.h +++ b/src/k_roulette.h @@ -30,6 +30,9 @@ boolean K_ForcedSPB(player_t *const player); void K_StartItemRoulette(player_t *const player, itemroulette_t *const roulette); void K_StartEggmanRoulette(player_t *const player); +#define ROULETTE_SPACING (36 << FRACBITS) +fixed_t K_GetRouletteOffset(itemroulette_t *const roulette, fixed_t renderDelta); + void K_KartItemRoulette(player_t *const player, ticcmd_t *cmd); #endif // __K_ROULETTE_H__ From 10145b75d1dc4c10c7f4ad4caf6088490e06e798 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 12 Dec 2022 02:59:58 -0500 Subject: [PATCH 30/66] Fix incorrect item reel in actual races --- src/k_roulette.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/k_roulette.c b/src/k_roulette.c index 7e3d7a3b7..09bd671d7 100644 --- a/src/k_roulette.c +++ b/src/k_roulette.c @@ -99,7 +99,7 @@ static UINT8 K_KartItemOddsRace[NUMKARTRESULTS-1][8] = { 0, 0, 1, 2, 1, 0, 0, 0 } // Jawz x2 }; -static UINT8 K_KartItemOddsBattle[NUMKARTRESULTS][2] = +static UINT8 K_KartItemOddsBattle[NUMKARTRESULTS-1][2] = { //K L { 2, 1 }, // Sneaker @@ -309,7 +309,7 @@ INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, UINT32 ourDist, boolean bot, bool INT32 shieldType = KSHIELD_NONE; I_Assert(item > KITEM_NONE); // too many off by one scenarioes. - I_Assert(cv_items[NUMKARTRESULTS-2] != NULL); // Make sure this exists + I_Assert(item < NUMKARTRESULTS); if (K_ItemEnabled(item) == false) { @@ -554,7 +554,8 @@ INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, UINT32 ourDist, boolean bot, bool newOdds = FixedMul(newOdds, FRACUNIT + K_ItemOddsScale(pingame)); } - return FixedInt(FixedRound(newOdds)); + newOdds = FixedInt(FixedRound(newOdds)); + return newOdds; } //{ SRB2kart Roulette Code - Distance Based, yes waypoints @@ -575,7 +576,7 @@ UINT8 K_FindUseodds(player_t *const player, UINT32 playerDist) if (gametype == GT_BATTLE && i > 1) { oddsValid[i] = false; - break; + continue; } for (j = 1; j < NUMKARTRESULTS; j++) @@ -856,7 +857,7 @@ void K_StartItemRoulette(player_t *const player, itemroulette_t *const roulette) for (i = 1; i < NUMKARTRESULTS; i++) { - UINT8 thisItemsOdds = K_KartGetItemOdds( + INT32 thisItemsOdds = K_KartGetItemOdds( useOdds, i, player->distancetofinish, player->bot, (player->bot && player->botvars.rival) @@ -879,7 +880,6 @@ void K_StartItemRoulette(player_t *const player, itemroulette_t *const roulette) while (totalSpawnChance > 0) { rngRoll = P_RandomKey(PR_ITEM_ROULETTE, totalSpawnChance); - for (i = 1; i < NUMKARTRESULTS && spawnChance[i] <= rngRoll; i++) { continue; @@ -896,7 +896,15 @@ void K_StartItemRoulette(player_t *const player, itemroulette_t *const roulette) K_PushToRouletteItemList(roulette, KITEM_SUPERRING); } - spawnChance[i]--; + for (; i < NUMKARTRESULTS; i++) + { + // Be sure to fix the remaining items' odds too. + if (spawnChance[i] > 0) + { + spawnChance[i]--; + } + } + totalSpawnChance--; } } From c8f3533b00a6df3dcdf324a14287845c5506f122 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 12 Dec 2022 04:01:09 -0500 Subject: [PATCH 31/66] Roulette speed adjustments - Speeds up the farther in the course you are - Speeds up the further in the front you are - Slows down before the 20 second mark --- src/k_roulette.c | 86 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 69 insertions(+), 17 deletions(-) diff --git a/src/k_roulette.c b/src/k_roulette.c index 09bd671d7..62d8e7fd1 100644 --- a/src/k_roulette.c +++ b/src/k_roulette.c @@ -62,11 +62,15 @@ #define SPBFORCEDIST (14*DISTVAR) // Distance when the game stops giving you bananas -#define ENDDIST (12*DISTVAR) +#define ENDDIST (18*DISTVAR) // Consistent seed used for item reels #define ITEM_REEL_SEED (0x22D5FAA8) +#define ROULETTE_SPEED_SLOWEST (12) +#define ROULETTE_SPEED_FASTEST (2) +#define ROULETTE_SPEED_DIST (224*DISTVAR) + static UINT8 K_KartItemOddsRace[NUMKARTRESULTS-1][8] = { { 0, 0, 2, 3, 4, 0, 0, 0 }, // Sneaker @@ -759,17 +763,66 @@ static void K_PushToRouletteItemList(itemroulette_t *const roulette, kartitems_t roulette->itemListLen++; } -static void K_CalculateRouletteSpeed(player_t *const player, itemroulette_t *const roulette, UINT8 playing) +static void K_CalculateRouletteSpeed(player_t *const player, itemroulette_t *const roulette) { // TODO: Change speed based on two factors: // - Get faster when your distancetofinish is closer to 1st place's distancetofinish. (winning) // - Get faster based on overall distancetofinish (race progress) // Slowest speed should be 12 tics, fastest should be 3 tics. - (void)player; - (void)playing; + fixed_t frontRun = 0; + fixed_t progress = 0; + fixed_t total = 0; - roulette->tics = roulette->speed = 7; + UINT8 playing = 0; + + UINT32 firstDist = UINT32_MAX; + UINT32 ourDist = UINT32_MAX; + + size_t i; + + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i] == false || players[i].spectator == true) + { + continue; + } + + playing++; + + if (players[i].position == 1) + { + firstDist = players[i].distancetofinish; + } + } + + ourDist = K_ScaleItemDistance(player->distancetofinish, playing); + firstDist = K_ScaleItemDistance(firstDist, playing); + + if (ourDist > ENDDIST) + { + // Being farther in the course makes your roulette faster. + progress = min(FRACUNIT, FixedDiv(ourDist - ENDDIST, ROULETTE_SPEED_DIST)); + } + + if (ourDist > firstDist) + { + // Frontrunning makes your roulette faster. + frontRun = min(FRACUNIT, FixedDiv(ourDist - firstDist, ENDDIST)); + } + + // Combine our two factors together. + total = min(FRACUNIT, (frontRun / 2) + (progress / 2)); + + if (leveltime < starttime + 20*TICRATE) + { + // Don't impact as much at the start. + // This makes it so that everyone gets to enjoy the lowest speed at the start. + fixed_t lerp = FRACUNIT - FixedDiv(max(0, leveltime - starttime), 10*TICRATE); + total += FixedMul(lerp, FRACUNIT - total); + } + + roulette->tics = roulette->speed = ROULETTE_SPEED_FASTEST + FixedMul(ROULETTE_SPEED_SLOWEST - ROULETTE_SPEED_FASTEST, total); } void K_StartItemRoulette(player_t *const player, itemroulette_t *const roulette) @@ -785,18 +838,7 @@ void K_StartItemRoulette(player_t *const player, itemroulette_t *const roulette) size_t i; K_InitRoulette(roulette); - - for (i = 0; i < MAXPLAYERS; i++) - { - if (playeringame[i] == false || players[i].spectator == true) - { - continue; - } - - playing++; - } - - K_CalculateRouletteSpeed(player, roulette, playing); + K_CalculateRouletteSpeed(player, roulette); // SPECIAL CASE No. 1: // Give only the debug item if specified @@ -808,6 +850,16 @@ void K_StartItemRoulette(player_t *const player, itemroulette_t *const roulette) // SPECIAL CASE No. 2: // Use a special, pre-determined item reel for Time Attack / Free Play + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i] == false || players[i].spectator == true) + { + continue; + } + + playing++; + } + if (bossinfo.boss == true) { for (i = 0; K_KartItemReelBoss[i] != KITEM_NONE; i++) From e45cef44df8b05d823991e513a58eb285f4ed63b Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 12 Dec 2022 04:35:51 -0500 Subject: [PATCH 32/66] Make bots stop roulette instead of waiting it out Done in kind of a lazy way, might revisit later. --- src/k_botitem.c | 18 +++--------------- src/k_roulette.c | 4 ++++ 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/src/k_botitem.c b/src/k_botitem.c index e3054aa69..fe0837c84 100644 --- a/src/k_botitem.c +++ b/src/k_botitem.c @@ -1394,27 +1394,15 @@ static void K_BotItemRings(player_t *player, ticcmd_t *cmd) --------------------------------------------------*/ static void K_BotItemRouletteMash(player_t *player, ticcmd_t *cmd) { - boolean mash = false; - if (K_ItemButtonWasDown(player) == true) { return; } - if (player->rings < 0 && K_ItemEnabled(KITEM_SUPERRING) == true) - { - // Uh oh, we need a loan! - // It'll be better in the long run for bots to lose an item set for 10 free rings. - mash = true; - } + // TODO: Would be nice to implement smarter behavior + // for selecting items. - // TODO: Mash based on how far behind you are, when items are - // almost garantueed to be in your favor. - - if (mash == true) - { - cmd->buttons |= BT_ATTACK; - } + cmd->buttons |= BT_ATTACK; } /*-------------------------------------------------- diff --git a/src/k_roulette.c b/src/k_roulette.c index 62d8e7fd1..5a0d73ebb 100644 --- a/src/k_roulette.c +++ b/src/k_roulette.c @@ -823,6 +823,10 @@ static void K_CalculateRouletteSpeed(player_t *const player, itemroulette_t *con } roulette->tics = roulette->speed = ROULETTE_SPEED_FASTEST + FixedMul(ROULETTE_SPEED_SLOWEST - ROULETTE_SPEED_FASTEST, total); + + // Make them select their item after a little while. + // One of the few instances of bot RNG, would be nice to remove it. + player->botvars.itemdelay = P_RandomRange(PR_UNDEFINED, TICRATE, TICRATE*3); } void K_StartItemRoulette(player_t *const player, itemroulette_t *const roulette) From 13d7c791f554d52613eb94861f90bff1bf3bb568 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 12 Dec 2022 04:36:32 -0500 Subject: [PATCH 33/66] Make the slowest speed slower Was designed for Snap's tiny item sprites, for the huge ones it still feels pretty fast. The fastest speed is unchanged, though :) --- src/k_roulette.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/k_roulette.c b/src/k_roulette.c index 5a0d73ebb..124d0a67c 100644 --- a/src/k_roulette.c +++ b/src/k_roulette.c @@ -67,7 +67,7 @@ // Consistent seed used for item reels #define ITEM_REEL_SEED (0x22D5FAA8) -#define ROULETTE_SPEED_SLOWEST (12) +#define ROULETTE_SPEED_SLOWEST (20) #define ROULETTE_SPEED_FASTEST (2) #define ROULETTE_SPEED_DIST (224*DISTVAR) From 8d2eb9220d4905a10db92c35467c669cbd53ed10 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 12 Dec 2022 11:46:03 -0500 Subject: [PATCH 34/66] Make Super Ring flood happen at 0 rings too --- src/k_roulette.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/k_roulette.c b/src/k_roulette.c index 124d0a67c..f154e261e 100644 --- a/src/k_roulette.c +++ b/src/k_roulette.c @@ -945,9 +945,9 @@ void K_StartItemRoulette(player_t *const player, itemroulette_t *const roulette) // If we're in ring debt, pad out the reel with // a BUNCH of Super Rings. - if (K_ItemEnabled(KITEM_SUPERRING) - && player->rings < 0 - && !(gametyperules & GTR_SPHERES)) + if (K_ItemEnabled(KITEM_SUPERRING) == true + && player->rings <= 0 + && (gametyperules & GTR_SPHERES) == 0) { K_PushToRouletteItemList(roulette, KITEM_SUPERRING); } From 63f6b18d59c9f9e719710a319a3a63dd6f3bc4f8 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 12 Dec 2022 11:55:28 -0500 Subject: [PATCH 35/66] No user for roulette itemlist Fixes the occasional Z_Free complaint --- src/k_roulette.c | 9 ++++----- src/p_saveg.c | 4 ++-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/k_roulette.c b/src/k_roulette.c index f154e261e..2a62bf7df 100644 --- a/src/k_roulette.c +++ b/src/k_roulette.c @@ -730,16 +730,15 @@ static void K_InitRoulette(itemroulette_t *const roulette) roulette->itemList = Z_Calloc( sizeof(SINT8) * roulette->itemListCap, PU_LEVEL, - &roulette->itemList + NULL ); } - memset(roulette->itemList, KITEM_NONE, sizeof(SINT8) * roulette->itemListCap); roulette->itemListLen = 0; - roulette->index = 0; + roulette->elapsed = 0; - roulette->tics = roulette->speed = 3; // Some default speed + roulette->tics = roulette->speed = ROULETTE_SPEED_FASTEST; // Some default speed roulette->active = true; roulette->eggman = false; } @@ -755,7 +754,7 @@ static void K_PushToRouletteItemList(itemroulette_t *const roulette, kartitems_t roulette->itemList, sizeof(SINT8) * roulette->itemListCap, PU_LEVEL, - &roulette->itemList + NULL ); } diff --git a/src/p_saveg.c b/src/p_saveg.c index fee092df9..0587b96f8 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -730,7 +730,7 @@ static void P_NetUnArchivePlayers(void) players[i].itemRoulette.itemList = Z_Calloc( sizeof(SINT8) * players[i].itemRoulette.itemListCap, PU_LEVEL, - &players[i].itemRoulette.itemList + NULL ); } else @@ -739,7 +739,7 @@ static void P_NetUnArchivePlayers(void) players[i].itemRoulette.itemList, sizeof(SINT8) * players[i].itemRoulette.itemListCap, PU_LEVEL, - &players[i].itemRoulette.itemList + NULL ); } From 0d49cc176818237f879f7e9e4ad0d1ebb5358833 Mon Sep 17 00:00:00 2001 From: Eidolon Date: Wed, 9 Nov 2022 02:30:35 +0000 Subject: [PATCH 36/66] Cherry-pick internal zlib MR from SRB2/next cmake: build zlib manually in internal build See merge request STJr/SRB2!1856 (cherry picked from commit 3597957af13878854c02305a0aec5ca744209ef2) # Conflicts: # thirdparty/CMakeLists.txt --- thirdparty/CMakeLists.txt | 70 +++++++++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 24 deletions(-) diff --git a/thirdparty/CMakeLists.txt b/thirdparty/CMakeLists.txt index 41c26c4e0..a6b77fd25 100644 --- a/thirdparty/CMakeLists.txt +++ b/thirdparty/CMakeLists.txt @@ -57,30 +57,52 @@ if(NOT "${SRB2_CONFIG_SYSTEM_LIBRARIES}") VERSION 1.2.13 URL "https://github.com/madler/zlib/archive/refs/tags/v1.2.13.zip" EXCLUDE_FROM_ALL - OPTIONS - # The assembly optimizations are unmaintained and slated to be removed - "ASM686 Off" - "AMD64 Off" - "SKIP_INSTALL_ALL ON" + DOWNLOAD_ONLY YES ) - file(MAKE_DIRECTORY "${zlib_BINARY_DIR}/include") - file(COPY "${zlib_SOURCE_DIR}/zlib.h" DESTINATION "${zlib_BINARY_DIR}/include") - file(COPY "${zlib_BINARY_DIR}/zconf.h" DESTINATION "${zlib_BINARY_DIR}/include") - # honestly this should probably be built like png is - set_target_properties(zlib PROPERTIES EXCLUDE_FROM_ALL ON) - set_target_properties(minigzip PROPERTIES EXCLUDE_FROM_ALL ON) - set_target_properties(example PROPERTIES EXCLUDE_FROM_ALL ON) - # zlib cmake also adds these 64 targets separately - if(HAVE_OFF64_T) - set_target_properties(minigzip64 PROPERTIES EXCLUDE_FROM_ALL ON) - set_target_properties(example64 PROPERTIES EXCLUDE_FROM_ALL ON) - endif() - target_include_directories(zlib INTERFACE "${zlib_BINARY_DIR}/include") - target_include_directories(zlibstatic INTERFACE "${zlib_BINARY_DIR}/include") - if(SRB2_CONFIG_SHARED_INTERNAL_LIBRARIES) - add_library(ZLIB::ZLIB ALIAS zlib) - else() - add_library(ZLIB::ZLIB ALIAS zlibstatic) + if(ZLIB_ADDED) + set(ZLIB_SRCS + crc32.h + deflate.h + gzguts.h + inffast.h + inffixed.h + inflate.h + inftrees.h + trees.h + zutil.h + + adler32.c + compress.c + crc32.c + deflate.c + gzclose.c + gzlib.c + gzread.c + gzwrite.c + inflate.c + infback.c + inftrees.c + inffast.c + trees.c + uncompr.c + zutil.c + ) + list(TRANSFORM ZLIB_SRCS PREPEND "${ZLIB_SOURCE_DIR}/") + + configure_file("${ZLIB_SOURCE_DIR}/zlib.pc.cmakein" "${ZLIB_BINARY_DIR}/zlib.pc" @ONLY) + configure_file("${ZLIB_SOURCE_DIR}/zconf.h.cmakein" "${ZLIB_BINARY_DIR}/include/zconf.h" @ONLY) + + add_library(ZLIB ${SRB2_INTERNAL_LIBRARY_TYPE} ${ZLIB_SRCS}) + set_target_properties(ZLIB PROPERTIES + VERSION 1.2.13 + OUTPUT_NAME "z" + ) + target_include_directories(ZLIB PRIVATE "${ZLIB_SOURCE_DIR}") + target_include_directories(ZLIB PUBLIC "${ZLIB_BINARY_DIR}/include") + if(MSVC) + target_compile_definitions(ZLIB PRIVATE -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE) + endif() + add_library(ZLIB::ZLIB ALIAS ZLIB) endif() endif() @@ -474,7 +496,7 @@ if(NOT "${SRB2_CONFIG_SYSTEM_LIBRARIES}") target_compile_options(openmpt PRIVATE "-g0") endif() if("${CMAKE_SYSTEM_NAME}" STREQUAL Windows) - target_link_libraries(openmpt PRIVATE rpcrt4) + target_link_libraries(openmpt PRIVATE Rpcrt4) endif() target_compile_features(openmpt PRIVATE cxx_std_11) target_compile_definitions(openmpt PRIVATE -DLIBOPENMPT_BUILD) From 1f9b97a0a89f47ac68bf3f32f4b1f4dbd099cde1 Mon Sep 17 00:00:00 2001 From: Eidolon Date: Sat, 10 Dec 2022 01:46:42 -0600 Subject: [PATCH 37/66] cmake: Use MAME YM2612 emu in GME (cherry picked from commit fb0f0c5e6c161b4b88439cda84c8b6cae9d236cc) --- thirdparty/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/thirdparty/CMakeLists.txt b/thirdparty/CMakeLists.txt index a6b77fd25..0f8ddd2aa 100644 --- a/thirdparty/CMakeLists.txt +++ b/thirdparty/CMakeLists.txt @@ -521,6 +521,7 @@ if(NOT "${SRB2_CONFIG_SYSTEM_LIBRARIES}") OPTIONS "BUILD_SHARED_LIBS ${SRB2_CONFIG_SHARED_INTERNAL_LIBRARIES}" "ENABLE_UBSAN OFF" + "GME_YM2612_EMU MAME" ) target_compile_features(gme PRIVATE cxx_std_11) target_link_libraries(gme PRIVATE ZLIB::ZLIB) From b9f277df66cb99c59cf6aa48a9dd76045876b63b Mon Sep 17 00:00:00 2001 From: Eidolon Date: Sat, 10 Dec 2022 01:53:23 -0600 Subject: [PATCH 38/66] cmake: Fix png and openmpt builds in clean envs In environments without zlib installed, png would fail to build since it can't find zlib.h. The zlib build's generated public include dir needs zlib.h to work. openmpt fails to build because it can't find Rpcrt4, which is not a necessary link under mingw, but exists in some mingw-w64 toolchains. It is only needed for MSVC. (cherry picked from commit fcf69001ada08077f82d3fc8510dcd24b4433e64) --- thirdparty/CMakeLists.txt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/thirdparty/CMakeLists.txt b/thirdparty/CMakeLists.txt index 0f8ddd2aa..8e9793ee7 100644 --- a/thirdparty/CMakeLists.txt +++ b/thirdparty/CMakeLists.txt @@ -91,6 +91,7 @@ if(NOT "${SRB2_CONFIG_SYSTEM_LIBRARIES}") configure_file("${ZLIB_SOURCE_DIR}/zlib.pc.cmakein" "${ZLIB_BINARY_DIR}/zlib.pc" @ONLY) configure_file("${ZLIB_SOURCE_DIR}/zconf.h.cmakein" "${ZLIB_BINARY_DIR}/include/zconf.h" @ONLY) + configure_file("${ZLIB_SOURCE_DIR}/zlib.h" "${ZLIB_BINARY_DIR}/include/zlib.h" @ONLY) add_library(ZLIB ${SRB2_INTERNAL_LIBRARY_TYPE} ${ZLIB_SRCS}) set_target_properties(ZLIB PROPERTIES @@ -173,8 +174,8 @@ if(NOT "${SRB2_CONFIG_SYSTEM_LIBRARIES}") target_include_directories(png PUBLIC "${png_BINARY_DIR}/include") # ... and these also need to be present only for png build - target_include_directories(png PRIVATE "${zlib_SOURCE_DIR}") - target_include_directories(png PRIVATE "${zlib_BINARY_DIR}") + target_include_directories(png PRIVATE "${ZLIB_SOURCE_DIR}") + target_include_directories(png PRIVATE "${ZLIB_BINARY_DIR}") target_include_directories(png PRIVATE "${png_BINARY_DIR}") target_link_libraries(png PRIVATE ZLIB::ZLIB) @@ -495,7 +496,7 @@ if(NOT "${SRB2_CONFIG_SYSTEM_LIBRARIES}") if("${CMAKE_C_COMPILER_ID}" STREQUAL GNU OR "${CMAKE_C_COMPILER_ID}" STREQUAL Clang OR "${CMAKE_C_COMPILER_ID}" STREQUAL AppleClang) target_compile_options(openmpt PRIVATE "-g0") endif() - if("${CMAKE_SYSTEM_NAME}" STREQUAL Windows) + if("${CMAKE_SYSTEM_NAME}" STREQUAL Windows AND "${CMAKE_C_COMPILER_ID}" STREQUAL MSVC) target_link_libraries(openmpt PRIVATE Rpcrt4) endif() target_compile_features(openmpt PRIVATE cxx_std_11) From 9e3ded610d33d55663efbeeb742b49a595c7e046 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 12 Dec 2022 16:19:45 -0500 Subject: [PATCH 39/66] Get rid of my TODO notes I implemented it, lol --- src/k_roulette.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/k_roulette.c b/src/k_roulette.c index 2a62bf7df..2357cde62 100644 --- a/src/k_roulette.c +++ b/src/k_roulette.c @@ -764,11 +764,6 @@ static void K_PushToRouletteItemList(itemroulette_t *const roulette, kartitems_t static void K_CalculateRouletteSpeed(player_t *const player, itemroulette_t *const roulette) { - // TODO: Change speed based on two factors: - // - Get faster when your distancetofinish is closer to 1st place's distancetofinish. (winning) - // - Get faster based on overall distancetofinish (race progress) - // Slowest speed should be 12 tics, fastest should be 3 tics. - fixed_t frontRun = 0; fixed_t progress = 0; fixed_t total = 0; From b0537de79e41de2c31495948be8e1b41acfecfcb Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 12 Dec 2022 16:44:24 -0500 Subject: [PATCH 40/66] Re-implement debugitemodds --- src/d_player.h | 1 + src/k_hud.c | 92 ++++++++++++------------------------------------ src/k_roulette.c | 7 ++-- src/p_saveg.c | 20 +++++++---- 4 files changed, 41 insertions(+), 79 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index 842edbc0e..2249d9f46 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -339,6 +339,7 @@ struct itemroulette_t size_t itemListLen; SINT8 *itemList; + UINT8 useOdds; size_t index; UINT8 sound; diff --git a/src/k_hud.c b/src/k_hud.c index 5ba874913..2a78c09de 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -4468,13 +4468,7 @@ K_drawMiniPing (void) static void K_drawDistributionDebugger(void) { -#if 1 - // TODO: Create a roulette struct and initialize it, - // and use that to draw the data, instead of recalculating - // most of it. - return; -#else - patch_t *items[NUMKARTRESULTS] = { + patch_t *patches[NUMKARTRESULTS] = { kp_sadface[1], kp_sneaker[1], kp_rocketsneaker[1], @@ -4506,87 +4500,47 @@ static void K_drawDistributionDebugger(void) kp_orbinaut[4], kp_jawz[1] }; - UINT8 useodds = 0; - UINT8 pingame = 0, bestbumper = 0; - UINT32 pdis = 0; - INT32 i; - INT32 x = -9, y = -9; + + itemroulette_t rouletteData = {0}; + + const INT32 space = 32; + const INT32 pad = 9; + + INT32 x = -pad, y = -pad; + size_t i; if (stplyr != &players[displayplayers[0]]) // only for p1 - return; - - if (K_ForcedSPB(stplyr) == true) { - V_DrawScaledPatch(x, y, V_SNAPTOTOP, items[KITEM_SPB]); - V_DrawThinString(x+11, y+31, V_ALLOWLOWERCASE|V_SNAPTOTOP, "EX"); return; } - // The only code duplication from the Kart, just to avoid the actual item function from calculating pingame twice - for (i = 0; i < MAXPLAYERS; i++) + K_StartItemRoulette(stplyr, &rouletteData); + + for (i = 0; i < rouletteData.itemListLen; i++) { - if (!playeringame[i] || players[i].spectator) - continue; - pingame++; - if (players[i].bumpers > bestbumper) - bestbumper = players[i].bumpers; - } + const kartitems_t item = rouletteData.itemList[i]; + UINT8 amount = 1; - // lovely double loop...... - for (i = 0; i < MAXPLAYERS; i++) - { - if (playeringame[i] && !players[i].spectator - && players[i].position == 1) - { - // This player is first! Yay! - pdis = stplyr->distancetofinish - players[i].distancetofinish; - break; - } - } - - pdis = K_ScaleItemDistance(pdis, pingame); - - if (stplyr->bot && stplyr->botvars.rival) - { - // Rival has better odds :) - pdis = (15 * pdis) / 14; - } - - useodds = K_FindUseodds(stplyr, pdis); - - for (i = 1; i < NUMKARTRESULTS; i++) - { - INT32 itemodds = K_KartGetItemOdds( - useodds, i, - stplyr->distancetofinish, - 0, - stplyr->bot, (stplyr->bot && stplyr->botvars.rival) - ); - INT32 amount = 1; - - if (itemodds <= 0) - continue; - - V_DrawScaledPatch(x, y, V_SNAPTOTOP, items[i]); - V_DrawThinString(x+11, y+31, V_SNAPTOTOP, va("%d", itemodds)); + V_DrawScaledPatch(x, y, V_SNAPTOTOP, patches[item]); // Display amount for multi-items - amount = K_ItemResultToAmount(i); + amount = K_ItemResultToAmount(item); if (amount > 1) { V_DrawString(x+24, y+31, V_ALLOWLOWERCASE|V_SNAPTOTOP, va("x%d", amount)); } - x += 32; - if (x >= 297) + y += space; + if (y > BASEVIDHEIGHT - space - pad) { - x = -9; - y += 32; + x += space; + y = -pad; } } - V_DrawString(0, 0, V_SNAPTOTOP, va("USEODDS %d", useodds)); -#endif + V_DrawString(0, 0, V_ALLOWLOWERCASE|V_SNAPTOTOP, va("Table #%d", rouletteData.useOdds)); + + Z_Free(rouletteData.itemList); } static void K_DrawWaypointDebugger(void) diff --git a/src/k_roulette.c b/src/k_roulette.c index 2357cde62..5951b4f42 100644 --- a/src/k_roulette.c +++ b/src/k_roulette.c @@ -736,9 +736,11 @@ static void K_InitRoulette(itemroulette_t *const roulette) roulette->itemListLen = 0; roulette->index = 0; + roulette->useOdds = UINT8_MAX; roulette->elapsed = 0; roulette->tics = roulette->speed = ROULETTE_SPEED_FASTEST; // Some default speed + roulette->active = true; roulette->eggman = false; } @@ -828,7 +830,6 @@ void K_StartItemRoulette(player_t *const player, itemroulette_t *const roulette) UINT8 playing = 0; UINT32 playerDist = UINT32_MAX; - UINT8 useOdds = 0; UINT32 spawnChance[NUMKARTRESULTS] = {0}; UINT32 totalSpawnChance = 0; size_t rngRoll = 0; @@ -903,12 +904,12 @@ void K_StartItemRoulette(player_t *const player, itemroulette_t *const roulette) playerDist = K_GetItemRouletteDistance(player, playing); - useOdds = K_FindUseodds(player, playerDist); + roulette->useOdds = K_FindUseodds(player, playerDist); for (i = 1; i < NUMKARTRESULTS; i++) { INT32 thisItemsOdds = K_KartGetItemOdds( - useOdds, i, + roulette->useOdds, i, player->distancetofinish, player->bot, (player->bot && player->botvars.rival) ); diff --git a/src/p_saveg.c b/src/p_saveg.c index 0587b96f8..99a06782d 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -416,10 +416,13 @@ static void P_NetArchivePlayers(void) { WRITESINT8(save_p, players[i].itemRoulette.itemList[j]); } + WRITEUINT8(save_p, players[i].itemRoulette.useOdds); WRITEUINT32(save_p, players[i].itemRoulette.index); + WRITEUINT8(save_p, players[i].itemRoulette.sound); WRITEUINT32(save_p, players[i].itemRoulette.speed); WRITEUINT32(save_p, players[i].itemRoulette.tics); WRITEUINT32(save_p, players[i].itemRoulette.elapsed); + WRITEUINT8(save_p, players[i].itemRoulette.eggman); } } @@ -721,9 +724,9 @@ static void P_NetUnArchivePlayers(void) players[i].botvars.spindashconfirm = READUINT32(save_p); // itemroulette_t - players[i].itemRoulette.active = READUINT8(save_p); - players[i].itemRoulette.itemListCap = READUINT32(save_p); - players[i].itemRoulette.itemListLen = READUINT32(save_p); + players[i].itemRoulette.active = (boolean)READUINT8(save_p); + players[i].itemRoulette.itemListCap = (size_t)READUINT32(save_p); + players[i].itemRoulette.itemListLen = (size_t)READUINT32(save_p); if (players[i].itemRoulette.itemList == NULL) { @@ -748,10 +751,13 @@ static void P_NetUnArchivePlayers(void) players[i].itemRoulette.itemList[j] = READSINT8(save_p); } - players[i].itemRoulette.index = READUINT32(save_p); - players[i].itemRoulette.speed = READUINT32(save_p); - players[i].itemRoulette.tics = READUINT32(save_p); - players[i].itemRoulette.elapsed = READUINT32(save_p); + players[i].itemRoulette.useOdds = READUINT8(save_p); + players[i].itemRoulette.index = (size_t)READUINT32(save_p); + players[i].itemRoulette.sound = READUINT8(save_p); + players[i].itemRoulette.speed = (tic_t)READUINT32(save_p); + players[i].itemRoulette.tics = (tic_t)READUINT32(save_p); + players[i].itemRoulette.elapsed = (tic_t)READUINT32(save_p); + players[i].itemRoulette.eggman = (boolean)READUINT8(save_p); //players[i].viewheight = P_GetPlayerViewHeight(players[i]); // scale cannot be factored in at this point } From a73e62c163fe94b7a90d9805923de6d8f6c23b41 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 12 Dec 2022 16:59:29 -0500 Subject: [PATCH 41/66] Re-add roulette itemList user Turns out the Z_Free error is something else in r_patch.c, seems unrelated to what I made. --- src/k_roulette.c | 4 ++-- src/p_saveg.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/k_roulette.c b/src/k_roulette.c index 5951b4f42..ad0c754e4 100644 --- a/src/k_roulette.c +++ b/src/k_roulette.c @@ -730,7 +730,7 @@ static void K_InitRoulette(itemroulette_t *const roulette) roulette->itemList = Z_Calloc( sizeof(SINT8) * roulette->itemListCap, PU_LEVEL, - NULL + &roulette->itemList ); } @@ -756,7 +756,7 @@ static void K_PushToRouletteItemList(itemroulette_t *const roulette, kartitems_t roulette->itemList, sizeof(SINT8) * roulette->itemListCap, PU_LEVEL, - NULL + &roulette->itemList ); } diff --git a/src/p_saveg.c b/src/p_saveg.c index 99a06782d..cb4aa7577 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -733,7 +733,7 @@ static void P_NetUnArchivePlayers(void) players[i].itemRoulette.itemList = Z_Calloc( sizeof(SINT8) * players[i].itemRoulette.itemListCap, PU_LEVEL, - NULL + &players[i].itemRoulette.itemList ); } else @@ -742,7 +742,7 @@ static void P_NetUnArchivePlayers(void) players[i].itemRoulette.itemList, sizeof(SINT8) * players[i].itemRoulette.itemListCap, PU_LEVEL, - NULL + &players[i].itemRoulette.itemList ); } From 7bdcb5883dafceb2c12e370ec54edaa979b915c4 Mon Sep 17 00:00:00 2001 From: Eidolon Date: Sat, 5 Nov 2022 20:50:57 -0500 Subject: [PATCH 42/66] cmake: Enable C++ 17 and C11 --- src/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5b681d042..b1099fd1d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -5,7 +5,7 @@ if("${CMAKE_COMPILER_IS_GNUCC}" AND "${CMAKE_SYSTEM_NAME}" MATCHES "Windows" AND target_link_options(SRB2SDL2 PRIVATE "-static") endif() -set_property(TARGET SRB2SDL2 PROPERTY C_STANDARD 11) +target_compile_features(SRB2SDL2 PRIVATE c_std_11 cxx_std_17) # Core sources target_sourcefile(c) From 5139d1276b941153305e6d536e591a0ccb76a121 Mon Sep 17 00:00:00 2001 From: Eidolon Date: Sun, 6 Nov 2022 01:08:43 -0600 Subject: [PATCH 43/66] cmake: Add Catch2 unit testing --- CMakeLists.txt | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 10c65a167..2f65f4d40 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -63,6 +63,7 @@ option( "Link dependencies using CMake's find_package and do not use internal builds" ${SRB2_CONFIG_SYSTEM_LIBRARIES_DEFAULT} ) +option(SRB2_CONFIG_ENABLE_TESTS "Build the test suite" ON) # This option isn't recommended for distribution builds and probably won't work (yet). cmake_dependent_option( SRB2_CONFIG_SHARED_INTERNAL_LIBRARIES @@ -81,6 +82,25 @@ option(SRB2_CONFIG_ZDEBUG "Compile with ZDEBUG defined." OFF) option(SRB2_CONFIG_PROFILEMODE "Compile for profiling (GCC only)." OFF) set(SRB2_CONFIG_ASSET_DIRECTORY "" CACHE PATH "Path to directory that contains all asset files for the installer. If set, assets will be part of installation and cpack.") +if(SRB2_CONFIG_ENABLE_TESTS) + # https://github.com/catchorg/Catch2 + CPMAddPackage( + NAME Catch2 + VERSION 3.1.1 + GITHUB_REPOSITORY catchorg/Catch2 + OPTIONS + "CATCH_INSTALL_DOCS OFF" + ) + list(APPEND CMAKE_MODULE_PATH "${Catch2_SOURCE_DIR}/extras") + include(CTest) + include(Catch) + add_executable(srb2tests) + # To add tests, use target_sources to add individual test files to the target in subdirs. + target_link_libraries(srb2tests PRIVATE Catch2::Catch2 Catch2::Catch2WithMain) + target_compile_features(srb2tests PRIVATE c_std_11 cxx_std_17) + catch_discover_tests(srb2tests) +endif() + # Enable CCache # (Set USE_CCACHE=ON to use, CCACHE_OPTIONS for options) if("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL Windows) From 7423b05f46bbc9420ccda8dd7677de38701bf748 Mon Sep 17 00:00:00 2001 From: Eidolon Date: Sun, 13 Nov 2022 20:06:15 -0600 Subject: [PATCH 44/66] Redefine boolean for C++ compatibility --- src/CMakeLists.txt | 1 + src/doomtype.h | 58 +++++++++++++++++----------------------- src/tests/CMakeLists.txt | 3 +++ src/tests/boolcompat.cpp | 8 ++++++ 4 files changed, 37 insertions(+), 33 deletions(-) create mode 100644 src/tests/CMakeLists.txt create mode 100644 src/tests/boolcompat.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b1099fd1d..97690d812 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -370,6 +370,7 @@ endif() add_subdirectory(sdl) add_subdirectory(objects) +add_subdirectory(tests) # strip debug symbols into separate file when using gcc. # to be consistent with Makefile, don't generate for OS X. diff --git a/src/doomtype.h b/src/doomtype.h index 95f060008..15de30e21 100644 --- a/src/doomtype.h +++ b/src/doomtype.h @@ -17,6 +17,10 @@ #ifndef __DOOMTYPE__ #define __DOOMTYPE__ +#ifdef __cplusplus +extern "C" { +#endif + #ifdef _WIN32 //#define WIN32_LEAN_AND_MEAN #define RPC_NO_WINDOWS_H @@ -107,24 +111,6 @@ typedef long ssize_t; char *strcasestr(const char *in, const char *what); #define stristr strcasestr -#if defined (macintosh) //|| defined (__APPLE__) //skip all boolean/Boolean crap - #define true 1 - #define false 0 - #define min(x,y) (((x)<(y)) ? (x) : (y)) - #define max(x,y) (((x)>(y)) ? (x) : (y)) - -#ifdef macintosh - #define stricmp strcmp - #define strnicmp strncmp -#endif - - #define boolean INT32 - - #ifndef O_BINARY - #define O_BINARY 0 - #endif -#endif //macintosh - #if defined (PC_DOS) || defined (_WIN32) || defined (__HAIKU__) #define HAVE_DOSSTR_FUNCS #endif @@ -151,22 +137,24 @@ size_t strlcpy(char *dst, const char *src, size_t siz); /* Boolean type definition */ -// \note __BYTEBOOL__ used to be set above if "macintosh" was defined, -// if macintosh's version of boolean type isn't needed anymore, then isn't this macro pointless now? -#ifndef __BYTEBOOL__ - #define __BYTEBOOL__ +// Note: C++ bool and C99/C11 _Bool are NOT compatible. +// Historically, boolean was win32 BOOL on Windows. For equivalence, it's now +// int32_t. "true" and "false" are only declared for C code; in C++, conversion +// between "bool" and "int32_t" takes over. +#ifndef _WIN32 +typedef int32_t boolean; +#else +#define BOOL boolean +#endif - //faB: clean that up !! - #if defined( _MSC_VER) && (_MSC_VER >= 1800) // MSVC 2013 and forward - #include "stdbool.h" - #elif defined (_WIN32) - #define false FALSE // use windows types - #define true TRUE - #define boolean BOOL - #else - typedef enum {false, true} boolean; - #endif -#endif // __BYTEBOOL__ +#ifndef __cplusplus +#ifndef _WIN32 +enum {false = 0, true = 1}; +#else +#define false FALSE +#define true TRUE +#endif +#endif /* 7.18.2.1 Limits of exact-width integer types */ @@ -408,4 +396,8 @@ typedef UINT64 precise_t; #include "typedef.h" +#ifdef __cplusplus +} // extern "C" +#endif + #endif //__DOOMTYPE__ diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt new file mode 100644 index 000000000..28c4ce492 --- /dev/null +++ b/src/tests/CMakeLists.txt @@ -0,0 +1,3 @@ +target_sources(srb2tests PRIVATE + boolcompat.cpp +) diff --git a/src/tests/boolcompat.cpp b/src/tests/boolcompat.cpp new file mode 100644 index 000000000..fee40cd36 --- /dev/null +++ b/src/tests/boolcompat.cpp @@ -0,0 +1,8 @@ +#include + +#include "../doomtype.h" + +TEST_CASE("C++ bool is convertible to doomtype.h boolean") { + REQUIRE(static_cast(true) == 1); + REQUIRE(static_cast(false) == 0); +} From dceeadd3aa2e381f5632085dcddd7ef49dbf0527 Mon Sep 17 00:00:00 2001 From: Eidolon Date: Sun, 13 Nov 2022 20:07:36 -0600 Subject: [PATCH 45/66] Don't preproc. define `inline` in C++ --- src/doomtype.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/doomtype.h b/src/doomtype.h index 15de30e21..fd5e6c2c4 100644 --- a/src/doomtype.h +++ b/src/doomtype.h @@ -92,7 +92,9 @@ typedef long ssize_t; #endif #define strncasecmp strnicmp #define strcasecmp stricmp +#ifndef __cplusplus #define inline __inline +#endif #elif defined (__WATCOMC__) #include #include From 15acefcc33dcfc117e98d4e2c62b208c01019cf3 Mon Sep 17 00:00:00 2001 From: Eidolon Date: Mon, 12 Dec 2022 16:38:25 -0600 Subject: [PATCH 46/66] c++: Make some defines C++-valid --- src/doomdef.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/doomdef.h b/src/doomdef.h index f54916599..669b90c71 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -126,10 +126,10 @@ extern char logfilename[1024]; // VERSIONSTRING_RC is for the resource-definition script used by windows builds #else #ifdef BETAVERSION -#define VERSIONSTRING "v"SRB2VERSION" "BETAVERSION +#define VERSIONSTRING "v" SRB2VERSION " " BETAVERSION #define VERSIONSTRING_RC SRB2VERSION " " BETAVERSION "\0" #else -#define VERSIONSTRING "v"SRB2VERSION +#define VERSIONSTRING "v" SRB2VERSION #define VERSIONSTRING_RC SRB2VERSION "\0" #endif // Hey! If you change this, add 1 to the MODVERSION below! @@ -614,12 +614,14 @@ UINT32 quickncasehash (const char *p, size_t n) return x; } +#ifndef __cplusplus #ifndef min // Double-Check with WATTCP-32's cdefs.h #define min(x, y) (((x) < (y)) ? (x) : (y)) #endif #ifndef max // Double-Check with WATTCP-32's cdefs.h #define max(x, y) (((x) > (y)) ? (x) : (y)) #endif +#endif // Max gamepad/joysticks that can be detected/used. #define MAX_JOYSTICKS 4 From 51e0bed20ad915401898306d409ff29b7e8015ad Mon Sep 17 00:00:00 2001 From: Eidolon Date: Mon, 12 Dec 2022 16:40:56 -0600 Subject: [PATCH 47/66] c++: add finally RAII utility This mirrors the `finally` utility in Guidelines Support Library for ensuring that a cleanup function is always called when the utility object leaves scope, even when unwinding the stack from an exception. This is to aid in transitioning malloc/free pairs in function bodies to be more exception-safe. --- src/cxxutil.hpp | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 src/cxxutil.hpp diff --git a/src/cxxutil.hpp b/src/cxxutil.hpp new file mode 100644 index 000000000..befe9c20b --- /dev/null +++ b/src/cxxutil.hpp @@ -0,0 +1,37 @@ +#ifndef __SRB2_CXXUTIL_HPP__ +#define __SRB2_CXXUTIL_HPP__ + +#include +#include + +namespace srb2 { + +template +class Finally { +public: + explicit Finally(const F& f) noexcept : f_(f) {} + explicit Finally(F&& f) noexcept : f_(f) {} + + Finally(Finally&& from) noexcept : f_(std::move(from.f_)), call_(std::exchange(from.call_, false)) {} + + Finally(const Finally& from) = delete; + void operator=(const Finally& from) = delete; + void operator=(Finally&& from) = delete; + + ~Finally() noexcept { + f_(); + } + +private: + F f_; + bool call_ = true; +}; + +template +Finally> finally(F&& f) noexcept { + return Finally {std::forward(f)}; +} + +} + +#endif // __SRB2_CXXUTIL_HPP__ From 8534703de6278a350e7f507e0861f3678eabaf58 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 12 Dec 2022 17:43:32 -0500 Subject: [PATCH 48/66] Further improve item debugger visibility - Half the scale of the item graphics, and reduce the spacing, so more of the reel can fit in one column. - Move the item table text over to the right, depending on how many columns were drawn. - Display the item roulette speed, as well. --- src/k_hud.c | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/src/k_hud.c b/src/k_hud.c index 2a78c09de..6dc556f80 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -4503,10 +4503,12 @@ static void K_drawDistributionDebugger(void) itemroulette_t rouletteData = {0}; - const INT32 space = 32; - const INT32 pad = 9; + const fixed_t scale = (FRACUNIT >> 1); + const fixed_t space = 24 * scale; + const fixed_t pad = 9 * scale; - INT32 x = -pad, y = -pad; + fixed_t x = -pad; + fixed_t y = -pad; size_t i; if (stplyr != &players[displayplayers[0]]) // only for p1 @@ -4521,24 +4523,33 @@ static void K_drawDistributionDebugger(void) const kartitems_t item = rouletteData.itemList[i]; UINT8 amount = 1; - V_DrawScaledPatch(x, y, V_SNAPTOTOP, patches[item]); + if (y > (BASEVIDHEIGHT << FRACBITS) - space - pad) + { + x += space; + y = -pad; + } + + V_DrawFixedPatch(x, y, scale, V_SNAPTOTOP, patches[item], NULL); // Display amount for multi-items amount = K_ItemResultToAmount(item); if (amount > 1) { - V_DrawString(x+24, y+31, V_ALLOWLOWERCASE|V_SNAPTOTOP, va("x%d", amount)); + V_DrawStringScaled( + x + (18 * scale), + y + (23 * scale), + scale, FRACUNIT, FRACUNIT, + V_ALLOWLOWERCASE|V_SNAPTOTOP, + NULL, HU_FONT, + va("x%d", amount) + ); } y += space; - if (y > BASEVIDHEIGHT - space - pad) - { - x += space; - y = -pad; - } } - V_DrawString(0, 0, V_ALLOWLOWERCASE|V_SNAPTOTOP, va("Table #%d", rouletteData.useOdds)); + V_DrawString((x >> FRACBITS) + 20, 2, V_ALLOWLOWERCASE|V_SNAPTOTOP, va("useOdds[%u]", rouletteData.useOdds)); + V_DrawString((x >> FRACBITS) + 20, 10, V_ALLOWLOWERCASE|V_SNAPTOTOP, va("speed = %u", rouletteData.speed)); Z_Free(rouletteData.itemList); } From 7713ce0ebbbd34fdda274f04c2a2e59807894d83 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 12 Dec 2022 19:41:33 -0500 Subject: [PATCH 49/66] Fix speed being messed up near level start Used the wrong constant, leftover from an earlier experiment that was only partially reverted. Fixes "ghost" roulettes. --- src/k_roulette.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/k_roulette.c b/src/k_roulette.c index ad0c754e4..dc0ae76c7 100644 --- a/src/k_roulette.c +++ b/src/k_roulette.c @@ -814,7 +814,7 @@ static void K_CalculateRouletteSpeed(player_t *const player, itemroulette_t *con { // Don't impact as much at the start. // This makes it so that everyone gets to enjoy the lowest speed at the start. - fixed_t lerp = FRACUNIT - FixedDiv(max(0, leveltime - starttime), 10*TICRATE); + fixed_t lerp = FRACUNIT - FixedDiv(max(0, leveltime - starttime), 20*TICRATE); total += FixedMul(lerp, FRACUNIT - total); } From 59ee8177d7faa9b6d269d96b8fcd553083c411d9 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 13 Dec 2022 00:00:37 -0500 Subject: [PATCH 50/66] Try some things for roulette sync - PU_STATIC instead of PU_LEVEL, since player_t is always kept around anyway. - Don't alloc itemList when cap is 0 - Read/write 0 when itemList is NULL --- src/k_roulette.c | 4 ++-- src/p_saveg.c | 52 ++++++++++++++++++++++++++++++------------------ 2 files changed, 35 insertions(+), 21 deletions(-) diff --git a/src/k_roulette.c b/src/k_roulette.c index dc0ae76c7..d07246a66 100644 --- a/src/k_roulette.c +++ b/src/k_roulette.c @@ -729,7 +729,7 @@ static void K_InitRoulette(itemroulette_t *const roulette) roulette->itemListCap = 8; roulette->itemList = Z_Calloc( sizeof(SINT8) * roulette->itemListCap, - PU_LEVEL, + PU_STATIC, &roulette->itemList ); } @@ -755,7 +755,7 @@ static void K_PushToRouletteItemList(itemroulette_t *const roulette, kartitems_t roulette->itemList = Z_Realloc( roulette->itemList, sizeof(SINT8) * roulette->itemListCap, - PU_LEVEL, + PU_STATIC, &roulette->itemList ); } diff --git a/src/p_saveg.c b/src/p_saveg.c index cb4aa7577..b69c63a5b 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -412,9 +412,16 @@ static void P_NetArchivePlayers(void) WRITEUINT8(save_p, players[i].itemRoulette.active); WRITEUINT32(save_p, players[i].itemRoulette.itemListCap); WRITEUINT32(save_p, players[i].itemRoulette.itemListLen); - for (j = 0; (unsigned)j < players[i].itemRoulette.itemListLen; j++) + for (j = 0; j < (signed)players[i].itemRoulette.itemListLen; j++) { - WRITESINT8(save_p, players[i].itemRoulette.itemList[j]); + if (players[i].itemRoulette.itemList == NULL) + { + WRITESINT8(save_p, KITEM_NONE); + } + else + { + WRITESINT8(save_p, players[i].itemRoulette.itemList[j]); + } } WRITEUINT8(save_p, players[i].itemRoulette.useOdds); WRITEUINT32(save_p, players[i].itemRoulette.index); @@ -728,27 +735,34 @@ static void P_NetUnArchivePlayers(void) players[i].itemRoulette.itemListCap = (size_t)READUINT32(save_p); players[i].itemRoulette.itemListLen = (size_t)READUINT32(save_p); - if (players[i].itemRoulette.itemList == NULL) + if (players[i].itemRoulette.itemListCap > 0) { - players[i].itemRoulette.itemList = Z_Calloc( - sizeof(SINT8) * players[i].itemRoulette.itemListCap, - PU_LEVEL, - &players[i].itemRoulette.itemList - ); - } - else - { - players[i].itemRoulette.itemList = Z_Realloc( - players[i].itemRoulette.itemList, - sizeof(SINT8) * players[i].itemRoulette.itemListCap, - PU_LEVEL, - &players[i].itemRoulette.itemList - ); + if (players[i].itemRoulette.itemList == NULL) + { + players[i].itemRoulette.itemList = Z_Calloc( + sizeof(SINT8) * players[i].itemRoulette.itemListCap, + PU_STATIC, + &players[i].itemRoulette.itemList + ); + } + else + { + players[i].itemRoulette.itemList = Z_Realloc( + players[i].itemRoulette.itemList, + sizeof(SINT8) * players[i].itemRoulette.itemListCap, + PU_STATIC, + &players[i].itemRoulette.itemList + ); + } } - for (j = 0; (unsigned)j < players[i].itemRoulette.itemListLen; j++) + for (j = 0; j < (signed)players[i].itemRoulette.itemListLen; j++) { - players[i].itemRoulette.itemList[j] = READSINT8(save_p); + SINT8 item = READSINT8(save_p); + if (players[i].itemRoulette.itemList != NULL) + { + players[i].itemRoulette.itemList[j] = item; + } } players[i].itemRoulette.useOdds = READUINT8(save_p); From c1845673615cb1e5878950a03072848bca285ea7 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 13 Dec 2022 12:06:52 -0500 Subject: [PATCH 51/66] No longer dynamically allocate roulette list Done with the issues trying to sync this memory over the wire, so now it's just a long static array... --- src/d_player.h | 10 +++++++++ src/k_roulette.c | 26 ++++++++++++++++++++++- src/p_saveg.c | 54 ++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 78 insertions(+), 12 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index 2249d9f46..fc45174d2 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -331,13 +331,23 @@ struct skybox_t { }; // player_t struct for item roulette variables + +// Doing this the right way is causing problems. +// so FINE, it's a static length now. +#define ITEM_LIST_SIZE (NUMKARTRESULTS * 20) + struct itemroulette_t { boolean active; +#ifdef ITEM_LIST_SIZE + size_t itemListLen; + SINT8 itemList[ITEM_LIST_SIZE]; +#else size_t itemListCap; size_t itemListLen; SINT8 *itemList; +#endif UINT8 useOdds; size_t index; diff --git a/src/k_roulette.c b/src/k_roulette.c index d07246a66..b136113b6 100644 --- a/src/k_roulette.c +++ b/src/k_roulette.c @@ -724,6 +724,7 @@ boolean K_ForcedSPB(player_t *const player) static void K_InitRoulette(itemroulette_t *const roulette) { +#ifndef ITEM_LIST_SIZE if (roulette->itemList == NULL) { roulette->itemListCap = 8; @@ -732,7 +733,13 @@ static void K_InitRoulette(itemroulette_t *const roulette) PU_STATIC, &roulette->itemList ); + + if (roulette->itemList == NULL) + { + I_Error("Not enough memory for item roulette list\n"); + } } +#endif roulette->itemListLen = 0; roulette->index = 0; @@ -747,6 +754,13 @@ static void K_InitRoulette(itemroulette_t *const roulette) static void K_PushToRouletteItemList(itemroulette_t *const roulette, kartitems_t item) { +#ifdef ITEM_LIST_SIZE + if (roulette->itemListLen >= ITEM_LIST_SIZE) + { + I_Error("Out of space for item reel! Go and make ITEM_LIST_SIZE bigger I guess?\n"); + return; + } +#else I_Assert(roulette->itemList != NULL); if (roulette->itemListLen >= roulette->itemListCap) @@ -758,7 +772,13 @@ static void K_PushToRouletteItemList(itemroulette_t *const roulette, kartitems_t PU_STATIC, &roulette->itemList ); + + if (roulette->itemList == NULL) + { + I_Error("Not enough memory for item roulette list\n"); + } } +#endif roulette->itemList[ roulette->itemListLen ] = item; roulette->itemListLen++; @@ -1008,7 +1028,11 @@ void K_KartItemRoulette(player_t *const player, ticcmd_t *const cmd) return; } - if (roulette->itemList == NULL || roulette->itemListLen == 0) + if (roulette->itemListLen == 0 +#ifndef ITEM_LIST_SIZE + || roulette->itemList == NULL +#endif + ) { // Invalid roulette setup. // Escape before we run into issues. diff --git a/src/p_saveg.c b/src/p_saveg.c index b69c63a5b..46aa64147 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -96,7 +96,7 @@ static void P_NetArchivePlayers(void) { INT32 i, j; UINT16 flags; -// size_t q; + size_t q; WRITEUINT32(save_p, ARCHIVEBLOCK_PLAYERS); @@ -410,19 +410,39 @@ static void P_NetArchivePlayers(void) // itemroulette_t WRITEUINT8(save_p, players[i].itemRoulette.active); - WRITEUINT32(save_p, players[i].itemRoulette.itemListCap); + +#ifdef ITEM_LIST_SIZE WRITEUINT32(save_p, players[i].itemRoulette.itemListLen); - for (j = 0; j < (signed)players[i].itemRoulette.itemListLen; j++) + + for (q = 0; q < ITEM_LIST_SIZE; q++) { - if (players[i].itemRoulette.itemList == NULL) + if (q >= players[i].itemRoulette.itemListLen) { WRITESINT8(save_p, KITEM_NONE); } else { - WRITESINT8(save_p, players[i].itemRoulette.itemList[j]); + WRITESINT8(save_p, players[i].itemRoulette.itemList[q]); } } +#else + if (players[i].itemRoulette.itemList == NULL) + { + WRITEUINT32(save_p, 0); + WRITEUINT32(save_p, 0); + } + else + { + WRITEUINT32(save_p, players[i].itemRoulette.itemListCap); + WRITEUINT32(save_p, players[i].itemRoulette.itemListLen); + + for (q = 0; q < players[i].itemRoulette.itemListLen; q++) + { + WRITESINT8(save_p, players[i].itemRoulette.itemList[q]); + } + } +#endif + WRITEUINT8(save_p, players[i].itemRoulette.useOdds); WRITEUINT32(save_p, players[i].itemRoulette.index); WRITEUINT8(save_p, players[i].itemRoulette.sound); @@ -437,6 +457,7 @@ static void P_NetUnArchivePlayers(void) { INT32 i, j; UINT16 flags; + size_t q; if (READUINT32(save_p) != ARCHIVEBLOCK_PLAYERS) I_Error("Bad $$$.sav at archive block Players"); @@ -732,6 +753,15 @@ static void P_NetUnArchivePlayers(void) // itemroulette_t players[i].itemRoulette.active = (boolean)READUINT8(save_p); + +#ifdef ITEM_LIST_SIZE + players[i].itemRoulette.itemListLen = (size_t)READUINT32(save_p); + + for (q = 0; q < ITEM_LIST_SIZE; q++) + { + players[i].itemRoulette.itemList[q] = READSINT8(save_p); + } +#else players[i].itemRoulette.itemListCap = (size_t)READUINT32(save_p); players[i].itemRoulette.itemListLen = (size_t)READUINT32(save_p); @@ -754,16 +784,18 @@ static void P_NetUnArchivePlayers(void) &players[i].itemRoulette.itemList ); } - } - for (j = 0; j < (signed)players[i].itemRoulette.itemListLen; j++) - { - SINT8 item = READSINT8(save_p); - if (players[i].itemRoulette.itemList != NULL) + if (players[i].itemRoulette.itemList == NULL) { - players[i].itemRoulette.itemList[j] = item; + I_Error("Not enough memory for item roulette list\n"); + } + + for (q = 0; q < players[i].itemRoulette.itemListLen; q++) + { + players[i].itemRoulette.itemList[q] = READSINT8(save_p); } } +#endif players[i].itemRoulette.useOdds = READUINT8(save_p); players[i].itemRoulette.index = (size_t)READUINT32(save_p); From 2a546df3fbc7caa3012b2dba92215769cec3eaa7 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 13 Dec 2022 12:44:11 -0500 Subject: [PATCH 52/66] Fix debugger breaking, reduce size --- src/d_player.h | 2 +- src/k_hud.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/d_player.h b/src/d_player.h index fc45174d2..1a447d8de 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -334,7 +334,7 @@ struct skybox_t { // Doing this the right way is causing problems. // so FINE, it's a static length now. -#define ITEM_LIST_SIZE (NUMKARTRESULTS * 20) +#define ITEM_LIST_SIZE (NUMKARTRESULTS << 2) struct itemroulette_t { diff --git a/src/k_hud.c b/src/k_hud.c index 6dc556f80..4e73b85a0 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -4551,7 +4551,9 @@ static void K_drawDistributionDebugger(void) V_DrawString((x >> FRACBITS) + 20, 2, V_ALLOWLOWERCASE|V_SNAPTOTOP, va("useOdds[%u]", rouletteData.useOdds)); V_DrawString((x >> FRACBITS) + 20, 10, V_ALLOWLOWERCASE|V_SNAPTOTOP, va("speed = %u", rouletteData.speed)); +#ifndef ITEM_LIST_SIZE Z_Free(rouletteData.itemList); +#endif } static void K_DrawWaypointDebugger(void) From 6b8a011aa1561137e8997f552236067e456ab8b3 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 13 Dec 2022 18:02:21 -0500 Subject: [PATCH 53/66] Flicker other items when selecting Makes the lerp back to the middle less jarring, since the items that were just there won't disappear. --- src/k_hud.c | 166 +++++++++++++++++++++++++++++++-------------------- src/k_kart.c | 11 +++- 2 files changed, 112 insertions(+), 65 deletions(-) diff --git a/src/k_hud.c b/src/k_hud.c index 4e73b85a0..30c41e227 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -1023,7 +1023,7 @@ static void K_drawKartItem(void) // Why write V_DrawScaledPatch calls over and over when they're all the same? // Set to 'no item' just in case. const UINT8 offset = ((r_splitscreen > 1) ? 1 : 0); - patch_t *localpatch[3] = {kp_nodraw}; + patch_t *localpatch[3] = { kp_nodraw }; patch_t *localbg = ((offset) ? kp_itembg[2] : kp_itembg[0]); patch_t *localinv = ((offset) ? kp_invincibility[((leveltime % (6*3)) / 3) + 7] : kp_invincibility[(leveltime % (7*3)) / 3]); INT32 fx = 0, fy = 0, fflags = 0; // final coords for hud and flags... @@ -1031,24 +1031,17 @@ static void K_drawKartItem(void) INT32 itembar = 0; INT32 maxl = 0; // itembar's normal highest value const INT32 barlength = (r_splitscreen > 1 ? 12 : 26); - UINT16 localcolor = SKINCOLOR_NONE; - SINT8 colormode = TC_RAINBOW; - UINT8 *colmap = NULL; + UINT16 localcolor[3] = { stplyr->skincolor }; + SINT8 colormode[3] = { TC_RAINBOW }; boolean flipamount = false; // Used for 3P/4P splitscreen to flip item amount stuff fixed_t rouletteOffset = 0; const INT32 rouletteBox = 36; INT32 i; - if (stplyr->itemRoulette.active == true) + if (stplyr->itemRoulette.itemListLen > 0) { - rouletteOffset = K_GetRouletteOffset(&stplyr->itemRoulette, rendertimefrac); - - if (stplyr->skincolor) - { - localcolor = stplyr->skincolor; - } - + // Init with item roulette stuff. for (i = 0; i < 3; i++) { const SINT8 indexOfs = i-1; @@ -1074,6 +1067,11 @@ static void K_drawKartItem(void) } } } + + if (stplyr->itemRoulette.active == true) + { + rouletteOffset = K_GetRouletteOffset(&stplyr->itemRoulette, rendertimefrac); + } else { // I'm doing this a little weird and drawing mostly in reverse order @@ -1081,25 +1079,26 @@ static void K_drawKartItem(void) // This shouldn't have any actual baring over how it functions // Hyudoro is first, because we're drawing it on top of the player's current item + localcolor[1] = SKINCOLOR_NONE; rouletteOffset = stplyr->karthud[khud_rouletteoffset]; if (stplyr->stealingtimer < 0) { if (leveltime & 2) - localpatch[0] = kp_hyudoro[offset]; + localpatch[1] = kp_hyudoro[offset]; else - localpatch[0] = kp_nodraw; + localpatch[1] = kp_nodraw; } else if ((stplyr->stealingtimer > 0) && (leveltime & 2)) { - localpatch[0] = kp_hyudoro[offset]; + localpatch[1] = kp_hyudoro[offset]; } else if (stplyr->eggmanexplode > 1) { if (leveltime & 1) - localpatch[0] = kp_eggman[offset]; + localpatch[1] = kp_eggman[offset]; else - localpatch[0] = kp_nodraw; + localpatch[1] = kp_nodraw; } else if (stplyr->ballhogcharge > 0) { @@ -1107,9 +1106,9 @@ static void K_drawKartItem(void) maxl = (((stplyr->itemamount-1) * BALLHOGINCREMENT) + 1); if (leveltime & 1) - localpatch[0] = kp_ballhog[offset]; + localpatch[1] = kp_ballhog[offset]; else - localpatch[0] = kp_nodraw; + localpatch[1] = kp_nodraw; } else if (stplyr->rocketsneakertimer > 1) { @@ -1117,16 +1116,16 @@ static void K_drawKartItem(void) maxl = (itemtime*3) - barlength; if (leveltime & 1) - localpatch[0] = kp_rocketsneaker[offset]; + localpatch[1] = kp_rocketsneaker[offset]; else - localpatch[0] = kp_nodraw; + localpatch[1] = kp_nodraw; } else if (stplyr->sadtimer > 0) { if (leveltime & 2) - localpatch[0] = kp_sadface[offset]; + localpatch[1] = kp_sadface[offset]; else - localpatch[0] = kp_nodraw; + localpatch[1] = kp_nodraw; } else { @@ -1136,12 +1135,12 @@ static void K_drawKartItem(void) switch (stplyr->itemtype) { case KITEM_INVINCIBILITY: - localpatch[0] = localinv; + localpatch[1] = localinv; localbg = kp_itembg[offset+1]; break; case KITEM_ORBINAUT: - localpatch[0] = kp_orbinaut[(offset ? 4 : min(stplyr->itemamount-1, 3))]; + localpatch[1] = kp_orbinaut[(offset ? 4 : min(stplyr->itemamount-1, 3))]; break; case KITEM_SPB: @@ -1152,34 +1151,41 @@ static void K_drawKartItem(void) /*FALLTHRU*/ default: - localpatch[0] = K_GetCachedItemPatch(stplyr->itemtype, offset); + localpatch[1] = K_GetCachedItemPatch(stplyr->itemtype, offset); - if (localpatch[0] == NULL) - localpatch[0] = kp_nodraw; // diagnose underflows + if (localpatch[1] == NULL) + localpatch[1] = kp_nodraw; // diagnose underflows break; } if ((stplyr->pflags & PF_ITEMOUT) && !(leveltime & 1)) - localpatch[0] = kp_nodraw; + localpatch[1] = kp_nodraw; } if (stplyr->karthud[khud_itemblink] && (leveltime & 1)) { - colormode = TC_BLINK; + colormode[1] = TC_BLINK; switch (stplyr->karthud[khud_itemblinkmode]) { case 2: - localcolor = K_RainbowColor(leveltime); + localcolor[1] = K_RainbowColor(leveltime); break; case 1: - localcolor = SKINCOLOR_RED; + localcolor[1] = SKINCOLOR_RED; break; default: - localcolor = SKINCOLOR_WHITE; + localcolor[1] = SKINCOLOR_WHITE; break; } } + else + { + // Hide the other items. + // Effectively lets the other roulette items + // show flicker away after you select. + localpatch[0] = localpatch[2] = kp_nodraw; + } } // pain and suffering defined below @@ -1206,45 +1212,77 @@ static void K_drawKartItem(void) } } - if (localcolor != SKINCOLOR_NONE) - colmap = R_GetTranslationColormap(colormode, localcolor, GTC_CACHE); - V_DrawScaledPatch(fx, fy, V_HUDTRANS|V_SLIDEIN|fflags, localbg); + // Need to draw these in a particular order, for sorting. + V_SetClipRect( + (fx + 7) << FRACBITS, (fy + 7) << FRACBITS, + rouletteBox << FRACBITS, rouletteBox << FRACBITS, + V_SLIDEIN|fflags + ); + + V_DrawFixedPatch( + fx<itemRoulette.active == true) { - V_SetClipRect((fx + 7) << FRACBITS, (fy + 7) << FRACBITS, rouletteBox << FRACBITS, rouletteBox << FRACBITS, V_HUDTRANS|V_SLIDEIN|fflags); - - // Need to draw these in a particular order, for sorting. - V_DrawFixedPatch(fx<itemamount >= numberdisplaymin && stplyr->itemRoulette.active == false) - { - // Then, the numbers: - V_DrawScaledPatch(fx + (flipamount ? 48 : 0), fy, V_HUDTRANS|V_SLIDEIN|fflags|(flipamount ? V_FLIP : 0), kp_itemmulsticker[offset]); // flip this graphic for p2 and p4 in split and shift it. - - V_DrawFixedPatch(fx<itemamount)); - else - V_DrawString(fx+24, fy+31, V_ALLOWLOWERCASE|V_HUDTRANS|V_SLIDEIN|fflags, va("x%d", stplyr->itemamount)); - } - else - { - V_DrawScaledPatch(fy+28, fy+41, V_HUDTRANS|V_SLIDEIN|fflags, kp_itemx); - V_DrawKartString(fx+38, fy+36, V_HUDTRANS|V_SLIDEIN|fflags, va("%d", stplyr->itemamount)); - } - } else { - V_DrawFixedPatch(fx<itemamount >= numberdisplaymin && stplyr->itemRoulette.active == false) + { + // Then, the numbers: + V_DrawScaledPatch( + fx + (flipamount ? 48 : 0), fy, + V_HUDTRANS|V_SLIDEIN|fflags|(flipamount ? V_FLIP : 0), + kp_itemmulsticker[offset] + ); // flip this graphic for p2 and p4 in split and shift it. + + V_DrawFixedPatch( + fx<itemamount)); + else + V_DrawString(fx+24, fy+31, V_ALLOWLOWERCASE|V_HUDTRANS|V_SLIDEIN|fflags, va("x%d", stplyr->itemamount)); + } + else + { + V_DrawScaledPatch(fy+28, fy+41, V_HUDTRANS|V_SLIDEIN|fflags, kp_itemx); + V_DrawKartString(fx+38, fy+36, V_HUDTRANS|V_SLIDEIN|fflags, va("%d", stplyr->itemamount)); + } + } + else + { + V_DrawFixedPatch( + fx<karthud[khud_rouletteoffset] != 0) { - player->karthud[khud_rouletteoffset] = FixedMul(player->karthud[khud_rouletteoffset], FRACUNIT*3/4); + if (abs(player->karthud[khud_rouletteoffset]) < (FRACUNIT >> 1)) + { + // Snap to 0, since the change is getting very small. + player->karthud[khud_rouletteoffset] = 0; + } + else + { + // Lerp to 0. + player->karthud[khud_rouletteoffset] = FixedMul(player->karthud[khud_rouletteoffset], FRACUNIT*3/4); + } } if (!(gametyperules & GTR_SPHERES)) From 8d43acccb7ac9fb5b7038b2993f4cf9920a4ed67 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 13 Dec 2022 18:03:44 -0500 Subject: [PATCH 54/66] Use predetermined roulette speed for Time Attack --- src/k_roulette.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/k_roulette.c b/src/k_roulette.c index b136113b6..07633a7e0 100644 --- a/src/k_roulette.c +++ b/src/k_roulette.c @@ -70,6 +70,7 @@ #define ROULETTE_SPEED_SLOWEST (20) #define ROULETTE_SPEED_FASTEST (2) #define ROULETTE_SPEED_DIST (224*DISTVAR) +#define ROULETTE_SPEED_TIMEATTACK (9) static UINT8 K_KartItemOddsRace[NUMKARTRESULTS-1][8] = { @@ -797,6 +798,10 @@ static void K_CalculateRouletteSpeed(player_t *const player, itemroulette_t *con size_t i; + // Make them select their item after a little while. + // One of the few instances of bot RNG, would be nice to remove it. + player->botvars.itemdelay = P_RandomRange(PR_UNDEFINED, TICRATE, TICRATE*3); + for (i = 0; i < MAXPLAYERS; i++) { if (playeringame[i] == false || players[i].spectator == true) @@ -812,6 +817,13 @@ static void K_CalculateRouletteSpeed(player_t *const player, itemroulette_t *con } } + if (modeattacking || playing <= 1) + { + // Time Attack rules; use a consistent speed. + roulette->tics = roulette->speed = ROULETTE_SPEED_TIMEATTACK; + return; + } + ourDist = K_ScaleItemDistance(player->distancetofinish, playing); firstDist = K_ScaleItemDistance(firstDist, playing); @@ -834,15 +846,18 @@ static void K_CalculateRouletteSpeed(player_t *const player, itemroulette_t *con { // Don't impact as much at the start. // This makes it so that everyone gets to enjoy the lowest speed at the start. - fixed_t lerp = FRACUNIT - FixedDiv(max(0, leveltime - starttime), 20*TICRATE); - total += FixedMul(lerp, FRACUNIT - total); + if (leveltime < starttime) + { + total = FRACUNIT; + } + else + { + const fixed_t lerp = FixedDiv(leveltime - starttime, 20*TICRATE); + total = FRACUNIT + FixedMul(lerp, total - FRACUNIT); + } } roulette->tics = roulette->speed = ROULETTE_SPEED_FASTEST + FixedMul(ROULETTE_SPEED_SLOWEST - ROULETTE_SPEED_FASTEST, total); - - // Make them select their item after a little while. - // One of the few instances of bot RNG, would be nice to remove it. - player->botvars.itemdelay = P_RandomRange(PR_UNDEFINED, TICRATE, TICRATE*3); } void K_StartItemRoulette(player_t *const player, itemroulette_t *const roulette) From 34dec00539d9823afcab4272b7f850fd5ac66296 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 12 Dec 2022 20:56:34 -0800 Subject: [PATCH 55/66] Add K_SpawnBrolyKi, green circle shrinks during explosion hitlag --- src/deh_tables.c | 5 +++++ src/info.c | 5 +++++ src/info.h | 6 ++++++ src/k_collide.c | 23 +++++++++++++++++++++-- src/k_collide.h | 2 +- src/k_kart.c | 42 +++++++++++++++++++++++++++++++++++++++--- src/k_kart.h | 3 ++- src/lua_baselib.c | 3 ++- src/p_enemy.c | 26 ++++++++++++++++++++++---- src/p_mobj.c | 4 ++++ 10 files changed, 107 insertions(+), 12 deletions(-) diff --git a/src/deh_tables.c b/src/deh_tables.c index ab0ef138b..5f026fe39 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -313,6 +313,7 @@ actionpointer_t actionpointers[] = {{A_JawzExplode}, "A_JAWZEXPLODE"}, {{A_SSMineSearch}, "A_SSMINESEARCH"}, {{A_SSMineExplode}, "A_SSMINEEXPLODE"}, + {{A_SSMineFlash}, "A_SSMINEFLASH"}, {{A_LandMineExplode}, "A_LANDMINEEXPLODE"}, {{A_BallhogExplode}, "A_BALLHOGEXPLODE"}, {{A_LightningFollowPlayer}, "A_LIGHTNINGFOLLOWPLAYER"}, @@ -4529,6 +4530,10 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_JANKSPARK2", "S_JANKSPARK3", "S_JANKSPARK4", + + // Broly Ki Orb + "S_BROLY1", + "S_BROLY2", }; // RegEx to generate this from info.h: ^\tMT_([^,]+), --> \t"MT_\1", diff --git a/src/info.c b/src/info.c index 3c6612ac4..345069d54 100644 --- a/src/info.c +++ b/src/info.c @@ -495,6 +495,7 @@ char sprnames[NUMSPRITES + 1][5] = "BOM3", // Boss Explosion 2 "BOM4", // Underwater Explosion "BMNB", // Mine Explosion + "LSSJ", // My ki is overflowing!! // Crumbly rocks "ROIA", @@ -5141,6 +5142,10 @@ state_t states[NUMSTATES] = {SPR_JANK, FF_PAPERSPRITE|FF_FULLBRIGHT|FF_ANIMATE, 4, {NULL}, 3, 1, S_JANKSPARK3}, // S_JANKSPARK2 {SPR_JANK, 0, 0, {A_SetCustomValue}, -1, 5, S_JANKSPARK4}, // S_JANKSPARK3 {SPR_JANK, 0, 0, {A_ChangeAngleRelative}, 180, 180, S_JANKSPARK2}, // S_JANKSPARK4 + + // Broly Ki Orb + {SPR_LSSJ, FF_REVERSESUBTRACT|FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_BROLY2}, // S_BROLY1 + {SPR_NULL, 0, 1, {A_SSMineFlash}, 0, 0, S_NULL}, // S_BROLY2 }; mobjinfo_t mobjinfo[NUMMOBJTYPES] = diff --git a/src/info.h b/src/info.h index 35a050011..e4c96915c 100644 --- a/src/info.h +++ b/src/info.h @@ -549,6 +549,7 @@ void A_ItemPop(); void A_JawzExplode(); void A_SSMineSearch(); void A_SSMineExplode(); +void A_SSMineFlash(); void A_LandMineExplode(); void A_LandMineExplode(); void A_BallhogExplode(); @@ -1041,6 +1042,7 @@ typedef enum sprite SPR_BOM3, // Boss Explosion 2 SPR_BOM4, // Underwater Explosion SPR_BMNB, // Mine Explosion + SPR_LSSJ, // My ki is overflowing!! // Crumbly rocks SPR_ROIA, @@ -5563,6 +5565,10 @@ typedef enum state S_JANKSPARK3, S_JANKSPARK4, + // Broly Ki Orb + S_BROLY1, + S_BROLY2, + S_FIRSTFREESLOT, S_LASTFREESLOT = S_FIRSTFREESLOT + NUMSTATEFREESLOTS - 1, NUMSTATES diff --git a/src/k_collide.c b/src/k_collide.c index dac44b5f7..64f460a61 100644 --- a/src/k_collide.c +++ b/src/k_collide.c @@ -206,6 +206,7 @@ boolean K_EggItemCollide(mobj_t *t1, mobj_t *t2) static mobj_t *grenade; static fixed_t explodedist; static boolean explodespin; +static tic_t minehitlag; static inline boolean PIT_SSMineChecks(mobj_t *thing) { @@ -284,17 +285,22 @@ static inline BlockItReturn_t PIT_SSMineExplode(mobj_t *thing) if (PIT_SSMineChecks(thing) == true) return BMIT_CONTINUE; - P_DamageMobj(thing, grenade, grenade->target, 1, (explodespin ? DMG_NORMAL : DMG_EXPLODE)); + if (P_DamageMobj(thing, grenade, grenade->target, 1, (explodespin ? DMG_NORMAL : DMG_EXPLODE))) + { + minehitlag = thing->hitlag; + } + return BMIT_CONTINUE; } -void K_MineExplodeAttack(mobj_t *actor, fixed_t size, boolean spin) +tic_t K_MineExplodeAttack(mobj_t *actor, fixed_t size, boolean spin) { INT32 bx, by, xl, xh, yl, yh; explodespin = spin; explodedist = FixedMul(size, actor->scale); grenade = actor; + minehitlag = 0; // Use blockmap to check for nearby shootables yh = (unsigned)(actor->y + explodedist - bmaporgy)>>MAPBLOCKSHIFT; @@ -310,6 +316,15 @@ void K_MineExplodeAttack(mobj_t *actor, fixed_t size, boolean spin) // Set this flag to ensure that the inital action won't be triggered twice. actor->flags2 |= MF2_DEBRIS; + + if (!spin) + { + K_SpawnBrolyKi(actor, minehitlag); + + return minehitlag; + } + + return 0; } boolean K_MineCollide(mobj_t *t1, mobj_t *t2) @@ -396,6 +411,7 @@ boolean K_LandMineCollide(mobj_t *t1, mobj_t *t2) P_DamageMobj(t2, t1, t1->target, 1, DMG_TUMBLE); } + t1->reactiontime = t2->hitlag; P_KillMobj(t1, t2, t2, DMG_NORMAL); } else if (t2->type == MT_BANANA || t2->type == MT_BANANA_SHIELD @@ -419,6 +435,7 @@ boolean K_LandMineCollide(mobj_t *t1, mobj_t *t2) P_SpawnMobj(t2->x/2 + t1->x/2, t2->y/2 + t1->y/2, t2->z/2 + t1->z/2, MT_ITEMCLASH); + t1->reactiontime = t2->hitlag; P_KillMobj(t1, t2, t2, DMG_NORMAL); } else if (t2->type == MT_SSMINE_SHIELD || t2->type == MT_SSMINE || t2->type == MT_LANDMINE) @@ -431,6 +448,8 @@ boolean K_LandMineCollide(mobj_t *t1, mobj_t *t2) { // Shootable damage P_DamageMobj(t2, t1, t1->target, 1, DMG_NORMAL); + + t1->reactiontime = t2->hitlag; P_KillMobj(t1, t2, t2, DMG_NORMAL); } diff --git a/src/k_collide.h b/src/k_collide.h index a498241ca..e8700a097 100644 --- a/src/k_collide.h +++ b/src/k_collide.h @@ -10,7 +10,7 @@ boolean K_BananaBallhogCollide(mobj_t *t1, mobj_t *t2); boolean K_EggItemCollide(mobj_t *t1, mobj_t *t2); void K_DoMineSearch(mobj_t *actor, fixed_t size); -void K_MineExplodeAttack(mobj_t *actor, fixed_t size, boolean spin); +tic_t K_MineExplodeAttack(mobj_t *actor, fixed_t size, boolean spin); boolean K_MineCollide(mobj_t *t1, mobj_t *t2); boolean K_LandMineCollide(mobj_t *t1, mobj_t *t2); diff --git a/src/k_kart.c b/src/k_kart.c index d3fd17661..05decab06 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -5122,7 +5122,7 @@ void K_MineFlashScreen(mobj_t *source) } // Spawns the purely visual explosion -void K_SpawnMineExplosion(mobj_t *source, UINT8 color) +void K_SpawnMineExplosion(mobj_t *source, UINT8 color, tic_t delay) { INT32 i, radius, height; mobj_t *smoldering = P_SpawnMobj(source->x, source->y, source->z, MT_SMOLDERING); @@ -5130,10 +5130,9 @@ void K_SpawnMineExplosion(mobj_t *source, UINT8 color) mobj_t *truc; INT32 speed, speed2; - K_MineFlashScreen(source); - K_MatchGenericExtraFlags(smoldering, source); smoldering->tics = TICRATE*3; + smoldering->hitlag += delay; radius = source->radius>>FRACBITS; height = source->height>>FRACBITS; @@ -5151,6 +5150,8 @@ void K_SpawnMineExplosion(mobj_t *source, UINT8 color) dust->destscale = source->scale*10; dust->scalespeed = source->scale/12; P_InstaThrust(dust, dust->angle, FixedMul(20*FRACUNIT, source->scale)); + dust->hitlag += delay; + dust->renderflags |= RF_DONTDRAW; truc = P_SpawnMobj(source->x + P_RandomRange(PR_EXPLOSION, -radius, radius)*FRACUNIT, source->y + P_RandomRange(PR_EXPLOSION, -radius, radius)*FRACUNIT, @@ -5167,6 +5168,8 @@ void K_SpawnMineExplosion(mobj_t *source, UINT8 color) if (truc->eflags & MFE_UNDERWATER) truc->momz = (117 * truc->momz) / 200; truc->color = color; + truc->hitlag += delay; + truc->renderflags |= RF_DONTDRAW; } for (i = 0; i < 16; i++) @@ -5180,6 +5183,8 @@ void K_SpawnMineExplosion(mobj_t *source, UINT8 color) dust->scalespeed = source->scale/12; dust->tics = 30; dust->momz = P_RandomRange(PR_EXPLOSION, FixedMul(3*FRACUNIT, source->scale)>>FRACBITS, FixedMul(7*FRACUNIT, source->scale)>>FRACBITS)*FRACUNIT; + dust->hitlag += delay; + dust->renderflags |= RF_DONTDRAW; truc = P_SpawnMobj(source->x + P_RandomRange(PR_EXPLOSION, -radius, radius)*FRACUNIT, source->y + P_RandomRange(PR_EXPLOSION, -radius, radius)*FRACUNIT, @@ -5200,9 +5205,40 @@ void K_SpawnMineExplosion(mobj_t *source, UINT8 color) truc->momz = (117 * truc->momz) / 200; truc->tics = TICRATE*2; truc->color = color; + truc->hitlag += delay; + truc->renderflags |= RF_DONTDRAW; } } +void K_SpawnBrolyKi(mobj_t *source, tic_t duration) +{ + mobj_t *x; + + if (duration == 0) + { + return; + } + + x = P_SpawnMobjFromMobj(source, 0, 0, 0, MT_THOK); + + // Shrink into center of source object. + x->z = (source->z + source->height / 2); + x->height = 0; + + P_SetMobjState(x, S_BROLY1); + x->hitlag = 0; // do not copy source hitlag + + P_SetScale(x, 64 * mapobjectscale); + x->scalespeed = x->scale / duration; + + // The last tic doesn't actually get rendered so in order + // to show scale = destscale, add one buffer tic. + x->tics = (duration + 1); + x->destscale = 1; // 0 also doesn't work + + K_ReduceVFX(x, NULL); +} + #undef MINEQUAKEDIST fixed_t K_ItemScaleForPlayer(player_t *player) diff --git a/src/k_kart.h b/src/k_kart.h index cddf3d503..87f3e1998 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -106,7 +106,8 @@ void K_HandleBumperChanges(player_t *player, UINT8 prevBumpers); void K_DestroyBumpers(player_t *player, UINT8 amount); void K_TakeBumpersFromPlayer(player_t *player, player_t *victim, UINT8 amount); void K_MineFlashScreen(mobj_t *source); -void K_SpawnMineExplosion(mobj_t *source, UINT8 color); +void K_SpawnMineExplosion(mobj_t *source, UINT8 color, tic_t delay); +void K_SpawnBrolyKi(mobj_t *source, tic_t duration); void K_RunFinishLineBeam(void); UINT16 K_DriftSparkColor(player_t *player, INT32 charge); void K_SpawnBoostTrail(player_t *player); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 06fbb789c..8c88c5155 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -3601,10 +3601,11 @@ static int lib_kSpawnMineExplosion(lua_State *L) { mobj_t *source = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); UINT8 color = (UINT8)luaL_optinteger(L, 2, SKINCOLOR_KETCHUP); + tic_t delay = (tic_t)luaL_optinteger(L, 3, 0); NOHUD if (!source) return LUA_ErrInvalid(L, "mobj_t"); - K_SpawnMineExplosion(source, color); + K_SpawnMineExplosion(source, color, delay); return 0; } diff --git a/src/p_enemy.c b/src/p_enemy.c index 131e92bf7..afe17b5bc 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -315,6 +315,7 @@ void A_ItemPop(mobj_t *actor); void A_JawzExplode(mobj_t *actor); void A_SSMineSearch(mobj_t *actor); void A_SSMineExplode(mobj_t *actor); +void A_SSMineFlash(mobj_t *actor); void A_LandMineExplode(mobj_t *actor); void A_BallhogExplode(mobj_t *actor); void A_LightningFollowPlayer(mobj_t *actor); @@ -13117,14 +13118,21 @@ void A_SSMineExplode(mobj_t *actor) { INT32 locvar1 = var1; + tic_t delay; + if (LUA_CallAction(A_SSMINEEXPLODE, actor)) return; if (actor->flags2 & MF2_DEBRIS) return; - K_SpawnMineExplosion(actor, (actor->target && actor->target->player) ? actor->target->player->skincolor : SKINCOLOR_KETCHUP); - K_MineExplodeAttack(actor, (3*actor->info->painchance)>>1, (boolean)locvar1); + delay = K_MineExplodeAttack(actor, (3*actor->info->painchance)>>1, (boolean)locvar1); + K_SpawnMineExplosion(actor, (actor->target && actor->target->player) ? actor->target->player->skincolor : SKINCOLOR_KETCHUP, delay); +} + +void A_SSMineFlash(mobj_t *actor) +{ + K_MineFlashScreen(actor); } void A_LandMineExplode(mobj_t *actor) @@ -13135,21 +13143,27 @@ void A_LandMineExplode(mobj_t *actor) INT32 i; mobj_t *smoldering; + tic_t delay = actor->reactiontime; + if (LUA_CallAction(A_LANDMINEEXPLODE, actor)) return; + if (delay == 0) + { + delay = 8; + } + // we'll base the explosion "timer" off of some stupid variable like uh... cvmem! // Yeah let's use cvmem since nobody uses that if (actor->target && !P_MobjWasRemoved(actor->target)) colour = actor->target->color; - K_MineFlashScreen(actor); - // Spawn smoke remains: smoldering = P_SpawnMobj(actor->x, actor->y, actor->z, MT_SMOLDERING); P_SetScale(smoldering, actor->scale); smoldering->tics = TICRATE*3; + smoldering->hitlag = delay; actor->fuse = actor->tics; // disappear when this state ends. @@ -13159,6 +13173,8 @@ void A_LandMineExplode(mobj_t *actor) expl = P_SpawnMobj(actor->x, actor->y, actor->z + actor->scale, MT_BOOMEXPLODE); expl->color = colour; expl->tics = (i+1); + expl->hitlag = delay; + expl->renderflags |= RF_DONTDRAW; //K_MatchGenericExtraFlags(expl, actor); P_SetScale(expl, actor->scale*4); @@ -13169,6 +13185,8 @@ void A_LandMineExplode(mobj_t *actor) // 100/45 = 2.22 fu/t expl->momz = ((i+1)*actor->scale*5/2)*P_MobjFlip(expl); } + + K_SpawnBrolyKi(actor, delay); } void A_BallhogExplode(mobj_t *actor) diff --git a/src/p_mobj.c b/src/p_mobj.c index 340e40e52..ce526659d 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -5889,6 +5889,10 @@ static void P_MobjSceneryThink(mobj_t *mobj) smoke->momz = P_RandomRange(PR_SMOLDERING, 4, 9)*mobj->scale*P_MobjFlip(smoke); } break; + case MT_SMOKE: + case MT_BOOMEXPLODE: + mobj->renderflags &= ~(RF_DONTDRAW); + break; case MT_BOOMPARTICLE: { fixed_t x = P_RandomRange(PR_EXPLOSION, -16, 16)*mobj->scale; From 2ec29b258652d5a8d04ce7283a66e86e500cd825 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 14 Dec 2022 01:33:31 -0800 Subject: [PATCH 56/66] Adjust mine and explosion to center Broly ki --- src/info.c | 2 +- src/k_kart.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/info.c b/src/info.c index 345069d54..4c45490e5 100644 --- a/src/info.c +++ b/src/info.c @@ -23347,7 +23347,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius - 24*FRACUNIT, // height + 56*FRACUNIT, // height 0, // display offset 100, // mass 1, // damage diff --git a/src/k_kart.c b/src/k_kart.c index 05decab06..f618763c5 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -8640,6 +8640,8 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) //player->flashing = 0; eggsexplode = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_SPBEXPLOSION); + eggsexplode->height = 2 * player->mo->height; + if (player->eggmanblame >= 0 && player->eggmanblame < MAXPLAYERS && playeringame[player->eggmanblame] From 2d52e4a04784e44fa024495324529b2a5775f8d7 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 14 Dec 2022 02:00:56 -0800 Subject: [PATCH 57/66] Colorize Broly ki to player color --- src/k_kart.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/k_kart.c b/src/k_kart.c index f618763c5..d72cb30f1 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -5226,6 +5226,8 @@ void K_SpawnBrolyKi(mobj_t *source, tic_t duration) x->height = 0; P_SetMobjState(x, S_BROLY1); + x->colorized = true; + x->color = source->color; x->hitlag = 0; // do not copy source hitlag P_SetScale(x, 64 * mapobjectscale); @@ -8641,6 +8643,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) //player->flashing = 0; eggsexplode = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_SPBEXPLOSION); eggsexplode->height = 2 * player->mo->height; + eggsexplode->color = player->mo->color; if (player->eggmanblame >= 0 && player->eggmanblame < MAXPLAYERS From 9017ca1c2020a794cab5f31f0d8ebc0aa813b51d Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 14 Dec 2022 02:21:41 -0800 Subject: [PATCH 58/66] Delay mine explosion sound until after Broly ki --- src/info.c | 2 +- src/k_kart.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/info.c b/src/info.c index 4c45490e5..5a1cefa1f 100644 --- a/src/info.c +++ b/src/info.c @@ -5145,7 +5145,7 @@ state_t states[NUMSTATES] = // Broly Ki Orb {SPR_LSSJ, FF_REVERSESUBTRACT|FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_BROLY2}, // S_BROLY1 - {SPR_NULL, 0, 1, {A_SSMineFlash}, 0, 0, S_NULL}, // S_BROLY2 + {SPR_NULL, 0, 5*TICRATE, {A_SSMineFlash}, 0, 0, S_NULL}, // S_BROLY2 }; mobjinfo_t mobjinfo[NUMMOBJTYPES] = diff --git a/src/k_kart.c b/src/k_kart.c index d72cb30f1..0ed21875c 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -5100,6 +5100,8 @@ void K_MineFlashScreen(mobj_t *source) INT32 pnum; player_t *p; + S_StartSound(source, sfx_s3k4e); + // check for potential display players near the source so we can have a sick earthquake / flashpal. for (pnum = 0; pnum < MAXPLAYERS; pnum++) { @@ -5136,8 +5138,6 @@ void K_SpawnMineExplosion(mobj_t *source, UINT8 color, tic_t delay) radius = source->radius>>FRACBITS; height = source->height>>FRACBITS; - S_StartSound(smoldering, sfx_s3k4e); - if (!color) color = SKINCOLOR_KETCHUP; From 130953fc7e799e1d814046f71c8c6b3f6a6d4f31 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 14 Dec 2022 02:37:30 -0800 Subject: [PATCH 59/66] Add sfx to Broly ki --- src/k_kart.c | 2 ++ src/sounds.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/k_kart.c b/src/k_kart.c index 0ed21875c..1c8213998 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -5239,6 +5239,8 @@ void K_SpawnBrolyKi(mobj_t *source, tic_t duration) x->destscale = 1; // 0 also doesn't work K_ReduceVFX(x, NULL); + + S_StartSound(x, sfx_cdfm74); } #undef MINEQUAKEDIST diff --git a/src/sounds.c b/src/sounds.c index f50e94942..a82cd2e59 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -750,7 +750,7 @@ sfxinfo_t S_sfx[NUMSFX] = {"cdfm71", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"cdfm72", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"cdfm73", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, - {"cdfm74", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"cdfm74", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Broly ki {"cdfm75", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"cdfm76", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"cdfm77", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, From b97c8cd176ad75bbe8f732f350ce01164ce3b0dc Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 14 Dec 2022 19:31:32 -0800 Subject: [PATCH 60/66] Make explosions louder from a distance --- src/sounds.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sounds.c b/src/sounds.c index a82cd2e59..016cf5029 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -479,7 +479,7 @@ sfxinfo_t S_sfx[NUMSFX] = {"s3k4b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Splash"}, {"s3k4c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Heavy hit"}, {"s3k4d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Firing bullet"}, - {"s3k4e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Big explosion"}, // Kart explosion + {"s3k4e", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Big explosion"}, // Kart explosion {"s3k4f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Flamethrower"}, {"s3k50", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Siren"}, {"s3k51", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Falling"}, From f7e53ec81128a16fe0b15652cd4d07c4885cb7cd Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Thu, 15 Dec 2022 01:23:23 -0500 Subject: [PATCH 61/66] Cleanup lots of the older roulette code - Most of it now requires a reference to itemroulette_t, rather than copying all of the variables over. - Increased the effect of Frantic Items, as the old scaling was made extremely low because item distance was exponential back then. - A lot of variables are pre-calculated in itemroulette_t instead of redoing the calculations every time (player count, first place's dist, etc) - Make most of these functions only accessible by k_roulette.c - Even when single items get forced into your roulette, the Super Ring Debt effect can happen - Make the game support setting single items from other gametypes (Pogo Spring-only races work now) - Fix some item distances not accounting for scale - Prevent multiple of certain items from rolling at once; Shrinks (not a big deal) and SPBs (OH GOD NO) --- src/d_player.h | 7 +- src/k_hud.c | 7 + src/k_kart.c | 12 +- src/k_roulette.c | 471 ++++++++++++++++++++++++----------------------- src/k_roulette.h | 10 +- src/p_saveg.c | 2 + 6 files changed, 266 insertions(+), 243 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index 1a447d8de..81a80d641 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -334,7 +334,7 @@ struct skybox_t { // Doing this the right way is causing problems. // so FINE, it's a static length now. -#define ITEM_LIST_SIZE (NUMKARTRESULTS << 2) +#define ITEM_LIST_SIZE (NUMKARTRESULTS << 3) struct itemroulette_t { @@ -350,6 +350,11 @@ struct itemroulette_t #endif UINT8 useOdds; + UINT8 playing, exiting; + UINT32 dist, baseDist; + UINT32 firstDist, secondDist; + UINT32 secondToFirst; + size_t index; UINT8 sound; diff --git a/src/k_hud.c b/src/k_hud.c index 30c41e227..32904beaa 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -4589,6 +4589,13 @@ static void K_drawDistributionDebugger(void) V_DrawString((x >> FRACBITS) + 20, 2, V_ALLOWLOWERCASE|V_SNAPTOTOP, va("useOdds[%u]", rouletteData.useOdds)); V_DrawString((x >> FRACBITS) + 20, 10, V_ALLOWLOWERCASE|V_SNAPTOTOP, va("speed = %u", rouletteData.speed)); + V_DrawString((x >> FRACBITS) + 20, 22, V_ALLOWLOWERCASE|V_SNAPTOTOP, va("baseDist = %u", rouletteData.baseDist)); + V_DrawString((x >> FRACBITS) + 20, 30, V_ALLOWLOWERCASE|V_SNAPTOTOP, va("dist = %u", rouletteData.dist)); + + V_DrawString((x >> FRACBITS) + 20, 42, V_ALLOWLOWERCASE|V_SNAPTOTOP, va("firstDist = %u", rouletteData.firstDist)); + V_DrawString((x >> FRACBITS) + 20, 50, V_ALLOWLOWERCASE|V_SNAPTOTOP, va("secondDist = %u", rouletteData.secondDist)); + V_DrawString((x >> FRACBITS) + 20, 58, V_ALLOWLOWERCASE|V_SNAPTOTOP, va("secondToFirst = %u", rouletteData.secondToFirst)); + #ifndef ITEM_LIST_SIZE Z_Free(rouletteData.itemList); #endif diff --git a/src/k_kart.c b/src/k_kart.c index 235f838f8..b512a64c3 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -6053,6 +6053,7 @@ mobj_t *K_CreatePaperItem(fixed_t x, fixed_t y, fixed_t z, angle_t angle, SINT8 if (type == 0) { + itemroulette_t rouletteData = {0}; UINT8 useodds = 0; INT32 spawnchance[NUMKARTRESULTS]; INT32 totalspawnchance = 0; @@ -6062,12 +6063,12 @@ mobj_t *K_CreatePaperItem(fixed_t x, fixed_t y, fixed_t z, angle_t angle, SINT8 useodds = amount; + K_StartItemRoulette(stplyr, &rouletteData); + for (i = 1; i < NUMKARTRESULTS; i++) { - spawnchance[i] = (totalspawnchance += K_KartGetItemOdds( - useodds, i, - UINT32_MAX, - false, false) + spawnchance[i] = ( + totalspawnchance += K_KartGetItemOdds(NULL, &rouletteData, useodds, i) ); } @@ -10498,8 +10499,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) if (spbplace == -1 || player->position != spbplace) player->pflags &= ~PF_RINGLOCK; // reset ring lock - if (player->itemtype == KITEM_SPB - || player->itemtype == KITEM_SHRINK) + if (K_ItemSingularity(player->itemtype) == true) { K_SetItemCooldown(player->itemtype, 20*TICRATE); } diff --git a/src/k_roulette.c b/src/k_roulette.c index 07633a7e0..b77659be6 100644 --- a/src/k_roulette.c +++ b/src/k_roulette.c @@ -59,17 +59,19 @@ #define SPBSTARTDIST (8*DISTVAR) // Distance when SPB is forced onto the next person who rolls an item -#define SPBFORCEDIST (14*DISTVAR) +#define SPBFORCEDIST (16*DISTVAR) // Distance when the game stops giving you bananas -#define ENDDIST (18*DISTVAR) +#define ENDDIST (14*DISTVAR) // Consistent seed used for item reels #define ITEM_REEL_SEED (0x22D5FAA8) +#define FRANTIC_ITEM_SCALE (FRACUNIT*6/5) + #define ROULETTE_SPEED_SLOWEST (20) #define ROULETTE_SPEED_FASTEST (2) -#define ROULETTE_SPEED_DIST (224*DISTVAR) +#define ROULETTE_SPEED_DIST (150*DISTVAR) #define ROULETTE_SPEED_TIMEATTACK (9) static UINT8 K_KartItemOddsRace[NUMKARTRESULTS-1][8] = @@ -176,7 +178,23 @@ boolean K_ItemEnabled(SINT8 item) return cv_items[item - 1].value; } -fixed_t K_ItemOddsScale(UINT8 playerCount) +boolean K_ItemSingularity(kartitems_t item) +{ + switch (item) + { + case KITEM_SPB: + case KITEM_SHRINK: + { + return true; + } + default: + { + return false; + } + } +} + +static fixed_t K_ItemOddsScale(UINT8 playerCount) { const UINT8 basePlayer = 8; // The player count we design most of the game around. fixed_t playerScaling = 0; @@ -205,18 +223,23 @@ fixed_t K_ItemOddsScale(UINT8 playerCount) return playerScaling; } -UINT32 K_ScaleItemDistance(UINT32 distance, UINT8 numPlayers) +static UINT32 K_UndoMapScaling(UINT32 distance) { if (mapobjectscale != FRACUNIT) { // Bring back to normal scale. - distance = FixedDiv(distance, mapobjectscale); + return FixedDiv(distance, mapobjectscale); } + return distance; +} + +static UINT32 K_ScaleItemDistance(UINT32 distance, UINT8 numPlayers) +{ if (franticitems == true) { // Frantic items pretends everyone's farther apart, for crazier items. - distance = (15 * distance) / 14; + distance = FixedMul(distance, FRANTIC_ITEM_SCALE); } // Items get crazier with the fewer players that you have. @@ -228,7 +251,7 @@ UINT32 K_ScaleItemDistance(UINT32 distance, UINT8 numPlayers) return distance; } -UINT32 K_GetItemRouletteDistance(player_t *const player, UINT8 pingame) +static UINT32 K_GetItemRouletteDistance(player_t *const player, UINT8 numPlayers) { UINT32 pdis = 0; @@ -274,12 +297,13 @@ UINT32 K_GetItemRouletteDistance(player_t *const player, UINT8 pingame) } } - pdis = K_ScaleItemDistance(pdis, pingame); + pdis = K_UndoMapScaling(pdis); + pdis = K_ScaleItemDistance(pdis, numPlayers); if (player->bot && player->botvars.rival) { // Rival has better odds :) - pdis = (15 * pdis) / 14; + pdis = FixedMul(pdis, FRANTIC_ITEM_SCALE); } return pdis; @@ -292,30 +316,33 @@ UINT32 K_GetItemRouletteDistance(player_t *const player, UINT8 pingame) \return void */ -INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, UINT32 ourDist, boolean bot, boolean rival) +INT32 K_KartGetItemOdds(player_t *const player, itemroulette_t *const roulette, UINT8 pos, kartitems_t item) { - fixed_t newOdds; - INT32 i; + boolean bot = false; + boolean rival = false; + UINT8 position = 0; - UINT8 pingame = 0, pexiting = 0; - - player_t *first = NULL; - player_t *second = NULL; - - UINT32 firstDist = UINT32_MAX; - UINT32 secondDist = UINT32_MAX; - UINT32 secondToFirst = 0; - boolean isFirst = false; + INT32 shieldType = KSHIELD_NONE; boolean powerItem = false; boolean cooldownOnStart = false; boolean notNearEnd = false; - INT32 shieldType = KSHIELD_NONE; + fixed_t newOdds = 0; + size_t i, j; + + I_Assert(roulette != NULL); I_Assert(item > KITEM_NONE); // too many off by one scenarioes. I_Assert(item < NUMKARTRESULTS); + if (player != NULL) + { + bot = player->bot; + rival = (bot == true && player->botvars.rival == true); + position = player->position; + } + if (K_ItemEnabled(item) == false) { return 0; @@ -345,6 +372,58 @@ INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, UINT32 ourDist, boolean bot, bool */ (void)bot; + shieldType = K_GetShieldFromItem(item); + switch (shieldType) + { + case KSHIELD_NONE: + /* Marble Garden Top is not REALLY + a Sonic 3 shield */ + case KSHIELD_TOP: + { + break; + } + + default: + { + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i] == false || players[i].spectator == true) + { + continue; + } + + if (shieldType == K_GetShieldFromItem(players[i].itemtype)) + { + // Don't allow more than one of each shield type at a time + return 0; + } + } + } + } + + if (K_ItemSingularity(item) == true) + { + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i] == false || players[i].spectator == true) + { + continue; + } + + if (players[i].itemRoulette.active == true) + { + for (j = 0; j < players[i].itemRoulette.itemListLen; j++) + { + if (players[i].itemRoulette.itemList[j] == item) + { + // Don't add if someone is already rolling for it. + return 0; + } + } + } + } + } + if (gametype == GT_BATTLE) { I_Assert(pos < 2); // DO NOT allow positions past the bounds of the table @@ -358,73 +437,6 @@ INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, UINT32 ourDist, boolean bot, bool newOdds <<= FRACBITS; - shieldType = K_GetShieldFromItem(item); - - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i] || players[i].spectator) - { - continue; - } - - if (!(gametyperules & GTR_BUMPERS) || players[i].bumpers) - { - pingame++; - } - - if (players[i].exiting) - { - pexiting++; - } - - switch (shieldType) - { - case KSHIELD_NONE: - /* Marble Garden Top is not REALLY - a Sonic 3 shield */ - case KSHIELD_TOP: - { - break; - } - - default: - { - if (shieldType == K_GetShieldFromItem(players[i].itemtype)) - { - // Don't allow more than one of each shield type at a time - return 0; - } - } - } - - if (players[i].position == 1) - { - first = &players[i]; - } - - if (players[i].position == 2) - { - second = &players[i]; - } - } - - if (first != NULL) // calculate 2nd's distance from 1st, for SPB - { - firstDist = first->distancetofinish; - isFirst = (ourDist <= firstDist); - } - - if (second != NULL) - { - secondDist = second->distancetofinish; - } - - if (first != NULL && second != NULL) - { - secondToFirst = secondDist - firstDist; - secondToFirst = K_ScaleItemDistance(secondToFirst, 16 - pingame); // Reversed scaling, so 16P is like 1v1, and 1v1 is like 16P - } - switch (item) { case KITEM_BANANA: @@ -440,7 +452,6 @@ INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, UINT32 ourDist, boolean bot, bool case KITEM_LANDMINE: case KITEM_DROPTARGET: case KITEM_BALLHOG: - case KITEM_HYUDORO: case KRITEM_TRIPLESNEAKER: case KRITEM_TRIPLEORBINAUT: case KRITEM_QUADORBINAUT: @@ -450,6 +461,7 @@ INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, UINT32 ourDist, boolean bot, bool break; } + case KITEM_HYUDORO: case KRITEM_TRIPLEBANANA: { powerItem = true; @@ -473,17 +485,23 @@ INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, UINT32 ourDist, boolean bot, bool cooldownOnStart = true; notNearEnd = true; - if (firstDist < ENDDIST*2 // No SPB when 1st is almost done - || isFirst == true) // No SPB for 1st ever + if ((gametyperules & GTR_CIRCUIT) == 0) { - newOdds = 0; + // Needs to be a race. + return 0; + } + + if (roulette->firstDist < ENDDIST*2 // No SPB when 1st is almost done + || position == 1) // No SPB for 1st ever + { + return 0; } else { - const UINT32 dist = max(0, ((signed)secondToFirst) - SPBSTARTDIST); + const UINT32 dist = max(0, ((signed)roulette->secondToFirst) - SPBSTARTDIST); const UINT32 distRange = SPBFORCEDIST - SPBSTARTDIST; - const UINT8 maxOdds = 20; - fixed_t multiplier = (dist * FRACUNIT) / distRange; + const fixed_t maxOdds = 20 << FRACBITS; + fixed_t multiplier = FixedDiv(dist, distRange); if (multiplier < 0) { @@ -495,34 +513,40 @@ INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, UINT32 ourDist, boolean bot, bool multiplier = FRACUNIT; } - newOdds = FixedMul(maxOdds << FRACBITS, multiplier); + newOdds = FixedMul(maxOdds, multiplier); } break; } case KITEM_SHRINK: + { cooldownOnStart = true; powerItem = true; notNearEnd = true; - if (pingame-1 <= pexiting) + if (roulette->playing - 1 <= roulette->exiting) { - newOdds = 0; + return 0; } break; + } case KITEM_LIGHTNINGSHIELD: + { cooldownOnStart = true; powerItem = true; if (spbplace != -1) { - newOdds = 0; + return 0; } break; + } default: + { break; + } } if (newOdds == 0) @@ -536,7 +560,7 @@ INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, UINT32 ourDist, boolean bot, bool // This item should not appear at the beginning of a race. (Usually really powerful crowd-breaking items) newOdds = 0; } - else if ((notNearEnd == true) && (ourDist < ENDDIST)) + else if ((notNearEnd == true) && (roulette->baseDist < ENDDIST)) { // This item should not appear at the end of a race. (Usually trap items that lose their effectiveness) newOdds = 0; @@ -556,16 +580,14 @@ INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, UINT32 ourDist, boolean bot, bool newOdds *= 2; } - newOdds = FixedMul(newOdds, FRACUNIT + K_ItemOddsScale(pingame)); + newOdds = FixedMul(newOdds, FRACUNIT + K_ItemOddsScale(roulette->playing)); } newOdds = FixedInt(FixedRound(newOdds)); return newOdds; } -//{ SRB2kart Roulette Code - Distance Based, yes waypoints - -UINT8 K_FindUseodds(player_t *const player, UINT32 playerDist) +static UINT8 K_FindUseodds(player_t *const player, itemroulette_t *const roulette) { UINT8 i; UINT8 useOdds = 0; @@ -586,11 +608,7 @@ UINT8 K_FindUseodds(player_t *const player, UINT32 playerDist) for (j = 1; j < NUMKARTRESULTS; j++) { - if (K_KartGetItemOdds( - i, j, - player->distancetofinish, - player->bot, (player->bot && player->botvars.rival) - ) > 0) + if (K_KartGetItemOdds(player, roulette, i, j) > 0) { break; } @@ -636,7 +654,7 @@ UINT8 K_FindUseodds(player_t *const player, UINT32 playerDist) dist = FixedMul(DISTVAR << FRACBITS, pos) >> FRACBITS; index = FixedInt(FixedRound(pos)); - if (playerDist <= (unsigned)dist) + if (roulette->dist <= (unsigned)dist) { useOdds = distTable[index]; break; @@ -649,14 +667,8 @@ UINT8 K_FindUseodds(player_t *const player, UINT32 playerDist) return useOdds; } -boolean K_ForcedSPB(player_t *const player) +static boolean K_ForcedSPB(player_t *const player, itemroulette_t *const roulette) { - player_t *first = NULL; - player_t *second = NULL; - UINT32 secondToFirst = UINT32_MAX; - UINT8 pingame = 0; - UINT8 i; - if (K_ItemEnabled(KITEM_SPB) == false) { return false; @@ -682,49 +694,20 @@ boolean K_ForcedSPB(player_t *const player) return false; } - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i] || players[i].spectator) - { - continue; - } - - if (players[i].exiting) - { - return false; - } - - pingame++; - - if (players[i].position == 1) - { - first = &players[i]; - } - - if (players[i].position == 2) - { - second = &players[i]; - } - } - #if 0 - if (pingame <= 2) + if (roulette->playing <= 2) { return false; } #endif - if (first != NULL && second != NULL) - { - secondToFirst = second->distancetofinish - first->distancetofinish; - secondToFirst = K_ScaleItemDistance(secondToFirst, 16 - pingame); - } - - return (secondToFirst >= SPBFORCEDIST); + return (roulette->secondToFirst >= SPBFORCEDIST); } static void K_InitRoulette(itemroulette_t *const roulette) { + size_t i; + #ifndef ITEM_LIST_SIZE if (roulette->itemList == NULL) { @@ -744,13 +727,50 @@ static void K_InitRoulette(itemroulette_t *const roulette) roulette->itemListLen = 0; roulette->index = 0; + roulette->useOdds = UINT8_MAX; + roulette->baseDist = roulette->dist = 0; + roulette->playing = roulette->exiting = 0; + roulette->firstDist = roulette->secondDist = UINT32_MAX; + roulette->secondToFirst = 0; roulette->elapsed = 0; roulette->tics = roulette->speed = ROULETTE_SPEED_FASTEST; // Some default speed roulette->active = true; roulette->eggman = false; + + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i] == false || players[i].spectator == true) + { + continue; + } + + roulette->playing++; + + if (players[i].exiting) + { + roulette->exiting++; + } + + if (players[i].position == 1) + { + roulette->firstDist = K_UndoMapScaling(players[i].distancetofinish); + } + + if (players[i].position == 2) + { + roulette->secondDist = K_UndoMapScaling(players[i].distancetofinish); + } + } + + // Calculate 2nd's distance from 1st, for SPB + if (roulette->firstDist != UINT32_MAX && roulette->secondDist != UINT32_MAX) + { + roulette->secondToFirst = roulette->secondDist - roulette->firstDist; + roulette->secondToFirst = K_ScaleItemDistance(roulette->secondToFirst, 16 - roulette->playing); // Reversed scaling + } } static void K_PushToRouletteItemList(itemroulette_t *const roulette, kartitems_t item) @@ -785,58 +805,47 @@ static void K_PushToRouletteItemList(itemroulette_t *const roulette, kartitems_t roulette->itemListLen++; } +static void K_AddItemToReel(player_t *const player, itemroulette_t *const roulette, kartitems_t item) +{ + K_PushToRouletteItemList(roulette, item); + + // If we're in ring debt, pad out the reel with + // a BUNCH of Super Rings. + if (K_ItemEnabled(KITEM_SUPERRING) == true + && player->rings <= 0 + && (gametyperules & GTR_SPHERES) == 0) + { + K_PushToRouletteItemList(roulette, KITEM_SUPERRING); + } +} + static void K_CalculateRouletteSpeed(player_t *const player, itemroulette_t *const roulette) { fixed_t frontRun = 0; fixed_t progress = 0; fixed_t total = 0; - UINT8 playing = 0; - - UINT32 firstDist = UINT32_MAX; - UINT32 ourDist = UINT32_MAX; - - size_t i; - // Make them select their item after a little while. // One of the few instances of bot RNG, would be nice to remove it. player->botvars.itemdelay = P_RandomRange(PR_UNDEFINED, TICRATE, TICRATE*3); - for (i = 0; i < MAXPLAYERS; i++) - { - if (playeringame[i] == false || players[i].spectator == true) - { - continue; - } - - playing++; - - if (players[i].position == 1) - { - firstDist = players[i].distancetofinish; - } - } - - if (modeattacking || playing <= 1) + if (modeattacking || roulette->playing <= 1) { // Time Attack rules; use a consistent speed. roulette->tics = roulette->speed = ROULETTE_SPEED_TIMEATTACK; return; } - ourDist = K_ScaleItemDistance(player->distancetofinish, playing); - firstDist = K_ScaleItemDistance(firstDist, playing); - - if (ourDist > ENDDIST) + if (roulette->baseDist > ENDDIST) { // Being farther in the course makes your roulette faster. - progress = min(FRACUNIT, FixedDiv(ourDist - ENDDIST, ROULETTE_SPEED_DIST)); + progress = min(FRACUNIT, FixedDiv(roulette->baseDist - ENDDIST, ROULETTE_SPEED_DIST)); } - if (ourDist > firstDist) + if (roulette->baseDist > roulette->firstDist) { // Frontrunning makes your roulette faster. - frontRun = min(FRACUNIT, FixedDiv(ourDist - firstDist, ENDDIST)); + frontRun = min(FRACUNIT, FixedDiv(roulette->baseDist - roulette->firstDist, ENDDIST)); } // Combine our two factors together. @@ -862,16 +871,19 @@ static void K_CalculateRouletteSpeed(player_t *const player, itemroulette_t *con void K_StartItemRoulette(player_t *const player, itemroulette_t *const roulette) { - UINT8 playing = 0; - UINT32 playerDist = UINT32_MAX; - UINT32 spawnChance[NUMKARTRESULTS] = {0}; UINT32 totalSpawnChance = 0; size_t rngRoll = 0; + UINT8 numItems = 0; + kartitems_t singleItem = KITEM_SAD; + size_t i; K_InitRoulette(roulette); + + roulette->baseDist = K_UndoMapScaling(player->distancetofinish); + K_CalculateRouletteSpeed(player, roulette); // SPECIAL CASE No. 1: @@ -884,16 +896,6 @@ void K_StartItemRoulette(player_t *const player, itemroulette_t *const roulette) // SPECIAL CASE No. 2: // Use a special, pre-determined item reel for Time Attack / Free Play - for (i = 0; i < MAXPLAYERS; i++) - { - if (playeringame[i] == false || players[i].spectator == true) - { - continue; - } - - playing++; - } - if (bossinfo.boss == true) { for (i = 0; K_KartItemReelBoss[i] != KITEM_NONE; i++) @@ -903,7 +905,7 @@ void K_StartItemRoulette(player_t *const player, itemroulette_t *const roulette) return; } - else if (modeattacking || playing <= 1) + else if (modeattacking || roulette->playing <= 1) { switch (gametype) { @@ -931,36 +933,58 @@ void K_StartItemRoulette(player_t *const player, itemroulette_t *const roulette) // SPECIAL CASE No. 3: // Only give the SPB if conditions are right - if (K_ForcedSPB(player) == true) + if (K_ForcedSPB(player, roulette) == true) { - K_PushToRouletteItemList(roulette, KITEM_SPB); + K_AddItemToReel(player, roulette, KITEM_SPB); return; } - playerDist = K_GetItemRouletteDistance(player, playing); - - roulette->useOdds = K_FindUseodds(player, playerDist); - - for (i = 1; i < NUMKARTRESULTS; i++) - { - INT32 thisItemsOdds = K_KartGetItemOdds( - roulette->useOdds, i, - player->distancetofinish, - player->bot, (player->bot && player->botvars.rival) - ); - - spawnChance[i] = (totalSpawnChance += thisItemsOdds); - } - // SPECIAL CASE No. 4: - // All items are off, so give a placeholder item - if (totalSpawnChance == 0) + // If only one item is enabled, always use it + for (i = 1; i < NUMKARTRESULTS; i++) { - K_PushToRouletteItemList(roulette, KITEM_SAD); + if (K_ItemEnabled(i) == true) + { + numItems++; + if (numItems > 1) + { + break; + } + + singleItem = i; + } + } + + if (numItems < 2) + { + // singleItem = KITEM_SAD by default, + // so it will be used when all items are turned off. + K_AddItemToReel(player, roulette, singleItem); return; } - // We always want the same result when making the same item reel. + // Special cases are all handled, we can now + // actually calculate actual item reels. + roulette->dist = K_GetItemRouletteDistance(player, roulette->playing); + roulette->useOdds = K_FindUseodds(player, roulette); + + for (i = 1; i < NUMKARTRESULTS; i++) + { + spawnChance[i] = ( + totalSpawnChance += K_KartGetItemOdds(player, roulette, roulette->useOdds, i) + ); + } + + if (totalSpawnChance == 0) + { + // This shouldn't happen, but if it does, early exit. + // Maybe can happen if you enable multiple items for + // another gametype, so we give the singleItem as a fallback. + K_AddItemToReel(player, roulette, singleItem); + return; + } + + // Create the same item reel given the same inputs. P_SetRandSeed(PR_ITEM_ROULETTE, ITEM_REEL_SEED); while (totalSpawnChance > 0) @@ -971,16 +995,7 @@ void K_StartItemRoulette(player_t *const player, itemroulette_t *const roulette) continue; } - K_PushToRouletteItemList(roulette, i); - - // If we're in ring debt, pad out the reel with - // a BUNCH of Super Rings. - if (K_ItemEnabled(KITEM_SUPERRING) == true - && player->rings <= 0 - && (gametyperules & GTR_SPHERES) == 0) - { - K_PushToRouletteItemList(roulette, KITEM_SUPERRING); - } + K_AddItemToReel(player, roulette, i); for (; i < NUMKARTRESULTS; i++) { @@ -1011,7 +1026,7 @@ void K_StartEggmanRoulette(player_t *const player) */ static void K_KartGetItemResult(player_t *const player, kartitems_t getitem) { - if (getitem == KITEM_SPB || getitem == KITEM_SHRINK) + if (K_ItemSingularity(getitem) == true) { K_SetItemCooldown(getitem, 20*TICRATE); } diff --git a/src/k_roulette.h b/src/k_roulette.h index 81e12aae3..3d52123f9 100644 --- a/src/k_roulette.h +++ b/src/k_roulette.h @@ -17,15 +17,9 @@ #include "d_player.h" boolean K_ItemEnabled(SINT8 item); +boolean K_ItemSingularity(kartitems_t item); -fixed_t K_ItemOddsScale(UINT8 playerCount); -UINT32 K_ScaleItemDistance(UINT32 distance, UINT8 numPlayers); -UINT32 K_GetItemRouletteDistance(player_t *const player, UINT8 pingame); - -INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, UINT32 ourDist, boolean bot, boolean rival); -UINT8 K_FindUseodds(player_t *const player, UINT32 playerDist); - -boolean K_ForcedSPB(player_t *const player); +INT32 K_KartGetItemOdds(player_t *const player, itemroulette_t *const roulette, UINT8 pos, kartitems_t item); void K_StartItemRoulette(player_t *const player, itemroulette_t *const roulette); void K_StartEggmanRoulette(player_t *const player); diff --git a/src/p_saveg.c b/src/p_saveg.c index 46aa64147..3ce18aa5f 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -444,6 +444,7 @@ static void P_NetArchivePlayers(void) #endif WRITEUINT8(save_p, players[i].itemRoulette.useOdds); + WRITEUINT32(save_p, players[i].itemRoulette.dist); WRITEUINT32(save_p, players[i].itemRoulette.index); WRITEUINT8(save_p, players[i].itemRoulette.sound); WRITEUINT32(save_p, players[i].itemRoulette.speed); @@ -798,6 +799,7 @@ static void P_NetUnArchivePlayers(void) #endif players[i].itemRoulette.useOdds = READUINT8(save_p); + players[i].itemRoulette.dist = READUINT32(save_p); players[i].itemRoulette.index = (size_t)READUINT32(save_p); players[i].itemRoulette.sound = READUINT8(save_p); players[i].itemRoulette.speed = (tic_t)READUINT32(save_p); From ffe9d5cd1d20d7dee3f89c9270554d0c34c6b254 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Thu, 15 Dec 2022 01:41:34 -0500 Subject: [PATCH 62/66] Properly support small splitscreen itembox --- src/k_hud.c | 32 +++++++++++++++++++------------- src/k_roulette.h | 1 + 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/k_hud.c b/src/k_hud.c index 32904beaa..49bb6aa07 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -1030,13 +1030,14 @@ static void K_drawKartItem(void) const INT32 numberdisplaymin = ((!offset && stplyr->itemtype == KITEM_ORBINAUT) ? 5 : 2); INT32 itembar = 0; INT32 maxl = 0; // itembar's normal highest value - const INT32 barlength = (r_splitscreen > 1 ? 12 : 26); + const INT32 barlength = (offset ? 12 : 26); UINT16 localcolor[3] = { stplyr->skincolor }; SINT8 colormode[3] = { TC_RAINBOW }; boolean flipamount = false; // Used for 3P/4P splitscreen to flip item amount stuff fixed_t rouletteOffset = 0; - const INT32 rouletteBox = 36; + fixed_t rouletteSpace = ROULETTE_SPACING; + vector2_t rouletteCrop = {7, 7}; INT32 i; if (stplyr->itemRoulette.itemListLen > 0) @@ -1189,13 +1190,7 @@ static void K_drawKartItem(void) } // pain and suffering defined below - if (r_splitscreen < 2) // don't change shit for THIS splitscreen. - { - fx = ITEM_X; - fy = ITEM_Y; - fflags = V_SNAPTOTOP|V_SNAPTOLEFT|V_SPLITSCREEN; - } - else // now we're having a fun game. + if (offset) { if (stplyr == &players[displayplayers[0]] || stplyr == &players[displayplayers[2]]) // If we are P1 or P3... { @@ -1210,24 +1205,35 @@ static void K_drawKartItem(void) fflags = V_SNAPTORIGHT|V_SNAPTOTOP|V_SPLITSCREEN; flipamount = true; } + + rouletteSpace = ROULETTE_SPACING_SPLITSCREEN; + rouletteOffset = FixedMul(rouletteOffset, FixedDiv(ROULETTE_SPACING_SPLITSCREEN, ROULETTE_SPACING)); + rouletteCrop.x = 16; + rouletteCrop.y = 15; + } + else + { + fx = ITEM_X; + fy = ITEM_Y; + fflags = V_SNAPTOTOP|V_SNAPTOLEFT|V_SPLITSCREEN; } V_DrawScaledPatch(fx, fy, V_HUDTRANS|V_SLIDEIN|fflags, localbg); // Need to draw these in a particular order, for sorting. V_SetClipRect( - (fx + 7) << FRACBITS, (fy + 7) << FRACBITS, - rouletteBox << FRACBITS, rouletteBox << FRACBITS, + (fx + rouletteCrop.x) << FRACBITS, (fy + rouletteCrop.y) << FRACBITS, + rouletteSpace, rouletteSpace, V_SLIDEIN|fflags ); V_DrawFixedPatch( - fx< Date: Thu, 15 Dec 2022 01:44:09 -0500 Subject: [PATCH 63/66] Remove item roulette between maps --- src/g_game.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 91d309638..ab4b6bc9c 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2322,8 +2322,13 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) pflags = (players[player].pflags & (PF_WANTSTOJOIN|PF_KICKSTARTACCEL|PF_SHRINKME|PF_SHRINKACTIVE)); // SRB2kart + memcpy(&itemRoulette, &players[player].itemRoulette, sizeof (itemRoulette)); + memcpy(&respawn, &players[player].respawn, sizeof (respawn)); + if (betweenmaps || leveltime < introtime) { + itemRoulette.active = false; + itemtype = 0; itemamount = 0; growshrinktimer = 0; @@ -2400,9 +2405,6 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) P_SetTarget(&players[player].follower, NULL); } - memcpy(&itemRoulette, &players[player].itemRoulette, sizeof (itemRoulette)); - memcpy(&respawn, &players[player].respawn, sizeof (respawn)); - p = &players[player]; memset(p, 0, sizeof (*p)); From 6554c8bfb1f7e2746a867713b20cbe9d106ddf62 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Thu, 15 Dec 2022 02:13:46 -0500 Subject: [PATCH 64/66] Improve scope handling of the roulette All of the player_t references are now full-const instead of const pointer after a certain point. This is because I've made two mistakes so far of modifying the player with this, when it's supposed to be safe to call for HUD as well. Also uses this split to add a more efficient way to prevent multi-Shrink/SPB. Also handles NULL player better, for the sake of Battle's K_CreatePaperItem. --- src/k_hud.c | 2 +- src/k_kart.c | 2 +- src/k_roulette.c | 91 +++++++++++++++++++++++++++--------------------- src/k_roulette.h | 5 +-- src/p_enemy.c | 2 +- src/p_inter.c | 2 +- 6 files changed, 59 insertions(+), 45 deletions(-) diff --git a/src/k_hud.c b/src/k_hud.c index 49bb6aa07..7c1d94e42 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -4560,7 +4560,7 @@ static void K_drawDistributionDebugger(void) return; } - K_StartItemRoulette(stplyr, &rouletteData); + K_FillItemRouletteData(stplyr, &rouletteData); for (i = 0; i < rouletteData.itemListLen; i++) { diff --git a/src/k_kart.c b/src/k_kart.c index b512a64c3..3bce71c54 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -6063,7 +6063,7 @@ mobj_t *K_CreatePaperItem(fixed_t x, fixed_t y, fixed_t z, angle_t angle, SINT8 useodds = amount; - K_StartItemRoulette(stplyr, &rouletteData); + K_FillItemRouletteData(NULL, &rouletteData); for (i = 1; i < NUMKARTRESULTS; i++) { diff --git a/src/k_roulette.c b/src/k_roulette.c index b77659be6..6d59f1ec3 100644 --- a/src/k_roulette.c +++ b/src/k_roulette.c @@ -251,10 +251,15 @@ static UINT32 K_ScaleItemDistance(UINT32 distance, UINT8 numPlayers) return distance; } -static UINT32 K_GetItemRouletteDistance(player_t *const player, UINT8 numPlayers) +static UINT32 K_GetItemRouletteDistance(const player_t *player, UINT8 numPlayers) { UINT32 pdis = 0; + if (player == NULL) + { + return 0; + } + #if 0 if (specialStage.active == true) { @@ -316,7 +321,7 @@ static UINT32 K_GetItemRouletteDistance(player_t *const player, UINT8 numPlayers \return void */ -INT32 K_KartGetItemOdds(player_t *const player, itemroulette_t *const roulette, UINT8 pos, kartitems_t item) +INT32 K_KartGetItemOdds(const player_t *player, itemroulette_t *const roulette, UINT8 pos, kartitems_t item) { boolean bot = false; boolean rival = false; @@ -329,7 +334,7 @@ INT32 K_KartGetItemOdds(player_t *const player, itemroulette_t *const roulette, boolean notNearEnd = false; fixed_t newOdds = 0; - size_t i, j; + size_t i; I_Assert(roulette != NULL); @@ -401,29 +406,6 @@ INT32 K_KartGetItemOdds(player_t *const player, itemroulette_t *const roulette, } } - if (K_ItemSingularity(item) == true) - { - for (i = 0; i < MAXPLAYERS; i++) - { - if (playeringame[i] == false || players[i].spectator == true) - { - continue; - } - - if (players[i].itemRoulette.active == true) - { - for (j = 0; j < players[i].itemRoulette.itemListLen; j++) - { - if (players[i].itemRoulette.itemList[j] == item) - { - // Don't add if someone is already rolling for it. - return 0; - } - } - } - } - } - if (gametype == GT_BATTLE) { I_Assert(pos < 2); // DO NOT allow positions past the bounds of the table @@ -587,7 +569,7 @@ INT32 K_KartGetItemOdds(player_t *const player, itemroulette_t *const roulette, return newOdds; } -static UINT8 K_FindUseodds(player_t *const player, itemroulette_t *const roulette) +static UINT8 K_FindUseodds(const player_t *player, itemroulette_t *const roulette) { UINT8 i; UINT8 useOdds = 0; @@ -667,7 +649,7 @@ static UINT8 K_FindUseodds(player_t *const player, itemroulette_t *const roulett return useOdds; } -static boolean K_ForcedSPB(player_t *const player, itemroulette_t *const roulette) +static boolean K_ForcedSPB(const player_t *player, itemroulette_t *const roulette) { if (K_ItemEnabled(KITEM_SPB) == false) { @@ -679,6 +661,11 @@ static boolean K_ForcedSPB(player_t *const player, itemroulette_t *const roulett return false; } + if (player == NULL) + { + return false; + } + if (player->position <= 1) { return false; @@ -805,10 +792,15 @@ static void K_PushToRouletteItemList(itemroulette_t *const roulette, kartitems_t roulette->itemListLen++; } -static void K_AddItemToReel(player_t *const player, itemroulette_t *const roulette, kartitems_t item) +static void K_AddItemToReel(const player_t *player, itemroulette_t *const roulette, kartitems_t item) { K_PushToRouletteItemList(roulette, item); + if (player == NULL) + { + return; + } + // If we're in ring debt, pad out the reel with // a BUNCH of Super Rings. if (K_ItemEnabled(KITEM_SUPERRING) == true @@ -819,16 +811,12 @@ static void K_AddItemToReel(player_t *const player, itemroulette_t *const roulet } } -static void K_CalculateRouletteSpeed(player_t *const player, itemroulette_t *const roulette) +static void K_CalculateRouletteSpeed(itemroulette_t *const roulette) { fixed_t frontRun = 0; fixed_t progress = 0; fixed_t total = 0; - // Make them select their item after a little while. - // One of the few instances of bot RNG, would be nice to remove it. - player->botvars.itemdelay = P_RandomRange(PR_UNDEFINED, TICRATE, TICRATE*3); - if (modeattacking || roulette->playing <= 1) { // Time Attack rules; use a consistent speed. @@ -869,7 +857,7 @@ static void K_CalculateRouletteSpeed(player_t *const player, itemroulette_t *con roulette->tics = roulette->speed = ROULETTE_SPEED_FASTEST + FixedMul(ROULETTE_SPEED_SLOWEST - ROULETTE_SPEED_FASTEST, total); } -void K_StartItemRoulette(player_t *const player, itemroulette_t *const roulette) +void K_FillItemRouletteData(const player_t *player, itemroulette_t *const roulette) { UINT32 spawnChance[NUMKARTRESULTS] = {0}; UINT32 totalSpawnChance = 0; @@ -882,9 +870,11 @@ void K_StartItemRoulette(player_t *const player, itemroulette_t *const roulette) K_InitRoulette(roulette); - roulette->baseDist = K_UndoMapScaling(player->distancetofinish); - - K_CalculateRouletteSpeed(player, roulette); + if (player != NULL) + { + roulette->baseDist = K_UndoMapScaling(player->distancetofinish); + K_CalculateRouletteSpeed(roulette); + } // SPECIAL CASE No. 1: // Give only the debug item if specified @@ -1010,10 +1000,33 @@ void K_StartItemRoulette(player_t *const player, itemroulette_t *const roulette) } } +void K_StartItemRoulette(player_t *const player) +{ + itemroulette_t *const roulette = &player->itemRoulette; + size_t i; + + K_FillItemRouletteData(player, roulette); + + // Make the bots select their item after a little while. + // One of the few instances of bot RNG, would be nice to remove it. + player->botvars.itemdelay = P_RandomRange(PR_UNDEFINED, TICRATE, TICRATE*3); + + // Prevent further duplicates of items that + // are intended to only have one out at a time. + for (i = 0; i < roulette->itemListLen; i++) + { + kartitems_t item = roulette->itemList[i]; + if (K_ItemSingularity(item) == true) + { + K_SetItemCooldown(item, TICRATE<<4); + } + } +} + void K_StartEggmanRoulette(player_t *const player) { itemroulette_t *const roulette = &player->itemRoulette; - K_StartItemRoulette(player, roulette); + K_StartItemRoulette(player); roulette->eggman = true; } diff --git a/src/k_roulette.h b/src/k_roulette.h index b1664643c..fbc6d4a4b 100644 --- a/src/k_roulette.h +++ b/src/k_roulette.h @@ -19,9 +19,10 @@ boolean K_ItemEnabled(SINT8 item); boolean K_ItemSingularity(kartitems_t item); -INT32 K_KartGetItemOdds(player_t *const player, itemroulette_t *const roulette, UINT8 pos, kartitems_t item); +INT32 K_KartGetItemOdds(const player_t *player, itemroulette_t *const roulette, UINT8 pos, kartitems_t item); +void K_FillItemRouletteData(const player_t *player, itemroulette_t *const roulette); -void K_StartItemRoulette(player_t *const player, itemroulette_t *const roulette); +void K_StartItemRoulette(player_t *const player); void K_StartEggmanRoulette(player_t *const player); #define ROULETTE_SPACING (36 << FRACBITS) diff --git a/src/p_enemy.c b/src/p_enemy.c index 636eb500a..3c45a1d2e 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -13048,7 +13048,7 @@ void A_ItemPop(mobj_t *actor) } else if (locvar1 == 0) { - K_StartItemRoulette(actor->target->player, &actor->target->player->itemRoulette); + K_StartItemRoulette(actor->target->player); } // Here at mapload in battle? diff --git a/src/p_inter.c b/src/p_inter.c index 2c05f5732..6400b9d35 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -412,7 +412,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (special->fuse || !P_CanPickupItem(player, 1) || ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0)) return; - K_StartItemRoulette(player, &player->itemRoulette); + K_StartItemRoulette(player); // Karma fireworks for (i = 0; i < 5; i++) From 7f569fe1688886a8f72871f46fdb454c8e8043ca Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 15 Dec 2022 04:14:38 -0800 Subject: [PATCH 65/66] Rename K_SpawnBrolyKi to Obj_SpawnBrolyKi, move to objects/broly.c, spawn MT_BROLY --- src/deh_tables.c | 2 ++ src/info.c | 27 +++++++++++++++++++++++++++ src/info.h | 2 ++ src/k_collide.c | 2 +- src/k_kart.c | 33 --------------------------------- src/k_kart.h | 1 - src/k_objects.h | 3 +++ src/objects/Sourcefile | 1 + src/objects/broly.c | 41 +++++++++++++++++++++++++++++++++++++++++ src/p_enemy.c | 2 +- 10 files changed, 78 insertions(+), 36 deletions(-) create mode 100644 src/objects/broly.c diff --git a/src/deh_tables.c b/src/deh_tables.c index 5f026fe39..9abc8f3f2 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -5627,6 +5627,8 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_PAPERITEMSPOT", "MT_BEAMPOINT", + + "MT_BROLY", }; const char *const MOBJFLAG_LIST[] = { diff --git a/src/info.c b/src/info.c index 5a1cefa1f..17d930a90 100644 --- a/src/info.c +++ b/src/info.c @@ -29030,6 +29030,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIPTHING|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags S_NULL // raisestate }, + + { // MT_BROLY + -1, // doomednum + S_BROLY1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 0, // radius + 0, // height + 0, // display offset + 100, // mass + 1, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPTHING|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY|MF_DONTENCOREMAP, // flags + S_NULL // raisestate + }, }; skincolor_t skincolors[MAXSKINCOLORS] = { diff --git a/src/info.h b/src/info.h index e4c96915c..bc074a0b5 100644 --- a/src/info.h +++ b/src/info.h @@ -6682,6 +6682,8 @@ typedef enum mobj_type MT_BEAMPOINT, + MT_BROLY, + MT_FIRSTFREESLOT, MT_LASTFREESLOT = MT_FIRSTFREESLOT + NUMMOBJFREESLOTS - 1, NUMMOBJTYPES diff --git a/src/k_collide.c b/src/k_collide.c index 64f460a61..11ac0b745 100644 --- a/src/k_collide.c +++ b/src/k_collide.c @@ -319,7 +319,7 @@ tic_t K_MineExplodeAttack(mobj_t *actor, fixed_t size, boolean spin) if (!spin) { - K_SpawnBrolyKi(actor, minehitlag); + Obj_SpawnBrolyKi(actor, minehitlag); return minehitlag; } diff --git a/src/k_kart.c b/src/k_kart.c index 1c8213998..12598f831 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -5210,39 +5210,6 @@ void K_SpawnMineExplosion(mobj_t *source, UINT8 color, tic_t delay) } } -void K_SpawnBrolyKi(mobj_t *source, tic_t duration) -{ - mobj_t *x; - - if (duration == 0) - { - return; - } - - x = P_SpawnMobjFromMobj(source, 0, 0, 0, MT_THOK); - - // Shrink into center of source object. - x->z = (source->z + source->height / 2); - x->height = 0; - - P_SetMobjState(x, S_BROLY1); - x->colorized = true; - x->color = source->color; - x->hitlag = 0; // do not copy source hitlag - - P_SetScale(x, 64 * mapobjectscale); - x->scalespeed = x->scale / duration; - - // The last tic doesn't actually get rendered so in order - // to show scale = destscale, add one buffer tic. - x->tics = (duration + 1); - x->destscale = 1; // 0 also doesn't work - - K_ReduceVFX(x, NULL); - - S_StartSound(x, sfx_cdfm74); -} - #undef MINEQUAKEDIST fixed_t K_ItemScaleForPlayer(player_t *player) diff --git a/src/k_kart.h b/src/k_kart.h index 87f3e1998..6827c77bc 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -107,7 +107,6 @@ void K_DestroyBumpers(player_t *player, UINT8 amount); void K_TakeBumpersFromPlayer(player_t *player, player_t *victim, UINT8 amount); void K_MineFlashScreen(mobj_t *source); void K_SpawnMineExplosion(mobj_t *source, UINT8 color, tic_t delay); -void K_SpawnBrolyKi(mobj_t *source, tic_t duration); void K_RunFinishLineBeam(void); UINT16 K_DriftSparkColor(player_t *player, INT32 charge); void K_SpawnBoostTrail(player_t *player); diff --git a/src/k_objects.h b/src/k_objects.h index 96e0fa2b5..fc15a2153 100644 --- a/src/k_objects.h +++ b/src/k_objects.h @@ -54,4 +54,7 @@ void Obj_DuelBombReverse(mobj_t *bomb); void Obj_DuelBombTouch(mobj_t *bomb, mobj_t *toucher); void Obj_DuelBombInit(mobj_t *bomb); +/* Broly Ki */ +mobj_t *Obj_SpawnBrolyKi(mobj_t *source, tic_t duration); + #endif/*k_objects_H*/ diff --git a/src/objects/Sourcefile b/src/objects/Sourcefile index b8cb63b1f..099f0d203 100644 --- a/src/objects/Sourcefile +++ b/src/objects/Sourcefile @@ -7,3 +7,4 @@ manta-ring.c orbinaut.c jawz.c duel-bomb.c +broly.c diff --git a/src/objects/broly.c b/src/objects/broly.c new file mode 100644 index 000000000..8c743a64a --- /dev/null +++ b/src/objects/broly.c @@ -0,0 +1,41 @@ +#include "../doomdef.h" +#include "../info.h" +#include "../k_kart.h" +#include "../k_objects.h" +#include "../p_local.h" +#include "../s_sound.h" + +mobj_t * +Obj_SpawnBrolyKi +( mobj_t * source, + tic_t duration) +{ + mobj_t *x = P_SpawnMobjFromMobj( + source, 0, 0, 0, MT_BROLY); + + if (duration == 0) + { + return x; + } + + // Shrink into center of source object. + x->z = (source->z + source->height / 2); + + x->colorized = true; + x->color = source->color; + x->hitlag = 0; // do not copy source hitlag + + P_SetScale(x, 64 * mapobjectscale); + x->scalespeed = x->scale / duration; + + // The last tic doesn't actually get rendered so in order + // to show scale = destscale, add one buffer tic. + x->tics = (duration + 1); + x->destscale = 1; // 0 also doesn't work + + K_ReduceVFX(x, NULL); + + S_StartSound(x, sfx_cdfm74); + + return x; +} diff --git a/src/p_enemy.c b/src/p_enemy.c index afe17b5bc..61762cce8 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -13186,7 +13186,7 @@ void A_LandMineExplode(mobj_t *actor) expl->momz = ((i+1)*actor->scale*5/2)*P_MobjFlip(expl); } - K_SpawnBrolyKi(actor, delay); + Obj_SpawnBrolyKi(actor, delay); } void A_BallhogExplode(mobj_t *actor) From 05413eeb2d93d5cb0d0725016ab95d8158fd4cd8 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Thu, 15 Dec 2022 16:19:06 -0500 Subject: [PATCH 66/66] Add proper comments for each function (I think this is the only code style I want to actively enforce :p) --- src/k_roulette.c | 211 ++++++++++++++++++++++++++++++++++++++++++----- src/k_roulette.h | 153 ++++++++++++++++++++++++++++++++-- 2 files changed, 336 insertions(+), 28 deletions(-) diff --git a/src/k_roulette.c b/src/k_roulette.c index 6d59f1ec3..ec15f4e9b 100644 --- a/src/k_roulette.c +++ b/src/k_roulette.c @@ -160,7 +160,12 @@ static kartitems_t K_KartItemReelBoss[] = KITEM_NONE }; -boolean K_ItemEnabled(SINT8 item) +/*-------------------------------------------------- + boolean K_ItemEnabled(kartitems_t item) + + See header file for description. +--------------------------------------------------*/ +boolean K_ItemEnabled(kartitems_t item) { if (item < 1 || item >= NUMKARTRESULTS) { @@ -178,6 +183,11 @@ boolean K_ItemEnabled(SINT8 item) return cv_items[item - 1].value; } +/*-------------------------------------------------- + boolean K_ItemSingularity(kartitems_t item) + + See header file for description. +--------------------------------------------------*/ boolean K_ItemSingularity(kartitems_t item) { switch (item) @@ -194,6 +204,19 @@ boolean K_ItemSingularity(kartitems_t item) } } +/*-------------------------------------------------- + static fixed_t K_ItemOddsScale(UINT8 playerCount) + + A multiplier for odds and distances to scale + them with the player count. + + Input Arguments:- + playerCount - Number of players in the game. + + Return:- + Fixed point number, to multiply odds or + distances by. +--------------------------------------------------*/ static fixed_t K_ItemOddsScale(UINT8 playerCount) { const UINT8 basePlayer = 8; // The player count we design most of the game around. @@ -223,6 +246,18 @@ static fixed_t K_ItemOddsScale(UINT8 playerCount) return playerScaling; } +/*-------------------------------------------------- + static UINT32 K_UndoMapScaling(UINT32 distance) + + Takes a raw map distance and adjusts it to + be in x1 scale. + + Input Arguments:- + distance - Original distance. + + Return:- + Distance unscaled by mapobjectscale. +--------------------------------------------------*/ static UINT32 K_UndoMapScaling(UINT32 distance) { if (mapobjectscale != FRACUNIT) @@ -234,6 +269,19 @@ static UINT32 K_UndoMapScaling(UINT32 distance) return distance; } +/*-------------------------------------------------- + static UINT32 K_ScaleItemDistance(UINT32 distance, UINT8 numPlayers) + + Adjust item distance for lobby-size scaling + as well as Frantic Items. + + Input Arguments:- + distance - Original distance. + numPlayers - Number of players in the game. + + Return:- + New distance after scaling. +--------------------------------------------------*/ static UINT32 K_ScaleItemDistance(UINT32 distance, UINT8 numPlayers) { if (franticitems == true) @@ -251,6 +299,19 @@ static UINT32 K_ScaleItemDistance(UINT32 distance, UINT8 numPlayers) return distance; } +/*-------------------------------------------------- + static UINT32 K_GetItemRouletteDistance(const player_t *player, UINT8 numPlayers) + + Gets a player's distance used for the item + roulette, including all scaling factors. + + Input Arguments:- + player - The player to get the distance of. + numPlayers - Number of players in the game. + + Return:- + The player's finalized item distance. +--------------------------------------------------*/ static UINT32 K_GetItemRouletteDistance(const player_t *player, UINT8 numPlayers) { UINT32 pdis = 0; @@ -314,13 +375,11 @@ static UINT32 K_GetItemRouletteDistance(const player_t *player, UINT8 numPlayers return pdis; } -/** \brief Item Roulette for Kart - - \param player player object passed from P_KartPlayerThink - - \return void -*/ +/*-------------------------------------------------- + INT32 K_KartGetItemOdds(const player_t *player, itemroulette_t *const roulette, UINT8 pos, kartitems_t item) + See header file for description. +--------------------------------------------------*/ INT32 K_KartGetItemOdds(const player_t *player, itemroulette_t *const roulette, UINT8 pos, kartitems_t item) { boolean bot = false; @@ -569,6 +628,21 @@ INT32 K_KartGetItemOdds(const player_t *player, itemroulette_t *const roulette, return newOdds; } +/*-------------------------------------------------- + static UINT8 K_FindUseodds(const player_t *player, itemroulette_t *const roulette) + + Gets which item bracket the player is in. + This can be adjusted depending on which + items being turned off. + + Input Arguments:- + player - The player the roulette is for. + roulette - The item roulette data. + + Return:- + The item bracket the player is in, as an + index to the array. +--------------------------------------------------*/ static UINT8 K_FindUseodds(const player_t *player, itemroulette_t *const roulette) { UINT8 i; @@ -649,6 +723,20 @@ static UINT8 K_FindUseodds(const player_t *player, itemroulette_t *const roulett return useOdds; } +/*-------------------------------------------------- + static boolean K_ForcedSPB(const player_t *player, itemroulette_t *const roulette) + + Determines special conditions where we want + to forcefully give the player an SPB. + + Input Arguments:- + player - The player the roulette is for. + roulette - The item roulette data. + + Return:- + true if we want to give the player a forced SPB, + otherwise false. +--------------------------------------------------*/ static boolean K_ForcedSPB(const player_t *player, itemroulette_t *const roulette) { if (K_ItemEnabled(KITEM_SPB) == false) @@ -691,6 +779,17 @@ static boolean K_ForcedSPB(const player_t *player, itemroulette_t *const roulett return (roulette->secondToFirst >= SPBFORCEDIST); } +/*-------------------------------------------------- + static void K_InitRoulette(itemroulette_t *const roulette) + + Initializes the data for a new item roulette. + + Input Arguments:- + roulette - The item roulette data to initialize. + + Return:- + N/A +--------------------------------------------------*/ static void K_InitRoulette(itemroulette_t *const roulette) { size_t i; @@ -760,6 +859,19 @@ static void K_InitRoulette(itemroulette_t *const roulette) } } +/*-------------------------------------------------- + static void K_PushToRouletteItemList(itemroulette_t *const roulette, kartitems_t item) + + Pushes a new item to the end of the item + roulette's item list. + + Input Arguments:- + roulette - The item roulette data to modify. + item - The item to push to the list. + + Return:- + N/A +--------------------------------------------------*/ static void K_PushToRouletteItemList(itemroulette_t *const roulette, kartitems_t item) { #ifdef ITEM_LIST_SIZE @@ -792,6 +904,23 @@ static void K_PushToRouletteItemList(itemroulette_t *const roulette, kartitems_t roulette->itemListLen++; } +/*-------------------------------------------------- + static void K_AddItemToReel(const player_t *player, itemroulette_t *const roulette, kartitems_t item) + + Adds an item to a player's item reel. Unlike + pushing directly with K_PushToRouletteItemList, + this function handles special behaviors (like + padding with extra Super Rings). + + Input Arguments:- + player - The player to add to the item roulette. + This is valid to be NULL. + roulette - The player's item roulette data. + item - The item to push to the list. + + Return:- + N/A +--------------------------------------------------*/ static void K_AddItemToReel(const player_t *player, itemroulette_t *const roulette, kartitems_t item) { K_PushToRouletteItemList(roulette, item); @@ -811,6 +940,19 @@ static void K_AddItemToReel(const player_t *player, itemroulette_t *const roulet } } +/*-------------------------------------------------- + static void K_CalculateRouletteSpeed(itemroulette_t *const roulette) + + Determines the speed for the item roulette, + adjusted for progress in the race and front + running. + + Input Arguments:- + roulette - The item roulette data to modify. + + Return:- + N/A +--------------------------------------------------*/ static void K_CalculateRouletteSpeed(itemroulette_t *const roulette) { fixed_t frontRun = 0; @@ -857,6 +999,11 @@ static void K_CalculateRouletteSpeed(itemroulette_t *const roulette) roulette->tics = roulette->speed = ROULETTE_SPEED_FASTEST + FixedMul(ROULETTE_SPEED_SLOWEST - ROULETTE_SPEED_FASTEST, total); } +/*-------------------------------------------------- + void K_FillItemRouletteData(const player_t *player, itemroulette_t *const roulette) + + See header file for description. +--------------------------------------------------*/ void K_FillItemRouletteData(const player_t *player, itemroulette_t *const roulette) { UINT32 spawnChance[NUMKARTRESULTS] = {0}; @@ -1000,6 +1147,11 @@ void K_FillItemRouletteData(const player_t *player, itemroulette_t *const roulet } } +/*-------------------------------------------------- + void K_StartItemRoulette(player_t *const player) + + See header file for description. +--------------------------------------------------*/ void K_StartItemRoulette(player_t *const player) { itemroulette_t *const roulette = &player->itemRoulette; @@ -1023,6 +1175,11 @@ void K_StartItemRoulette(player_t *const player) } } +/*-------------------------------------------------- + void K_StartEggmanRoulette(player_t *const player) + + See header file for description. +--------------------------------------------------*/ void K_StartEggmanRoulette(player_t *const player) { itemroulette_t *const roulette = &player->itemRoulette; @@ -1030,13 +1187,32 @@ void K_StartEggmanRoulette(player_t *const player) roulette->eggman = true; } -/** \brief Item Roulette for Kart +/*-------------------------------------------------- + fixed_t K_GetRouletteOffset(itemroulette_t *const roulette, fixed_t renderDelta) - \param player player - \param getitem what item we're looking for + See header file for description. +--------------------------------------------------*/ +fixed_t K_GetRouletteOffset(itemroulette_t *const roulette, fixed_t renderDelta) +{ + const fixed_t curTic = (roulette->tics << FRACBITS) - renderDelta; + const fixed_t midTic = roulette->speed * (FRACUNIT >> 1); - \return void -*/ + return FixedMul(FixedDiv(midTic - curTic, ((roulette->speed + 1) << FRACBITS)), ROULETTE_SPACING); +} + +/*-------------------------------------------------- + static void K_KartGetItemResult(player_t *const player, kartitems_t getitem) + + Initializes a player's item to what was + received from the roulette. + + Input Arguments:- + player - The player receiving the item. + getitem - The item to give to the player. + + Return:- + N/A +--------------------------------------------------*/ static void K_KartGetItemResult(player_t *const player, kartitems_t getitem) { if (K_ItemSingularity(getitem) == true) @@ -1051,14 +1227,11 @@ static void K_KartGetItemResult(player_t *const player, kartitems_t getitem) player->itemamount = K_ItemResultToAmount(getitem); } -fixed_t K_GetRouletteOffset(itemroulette_t *const roulette, fixed_t renderDelta) -{ - const fixed_t curTic = (roulette->tics << FRACBITS) - renderDelta; - const fixed_t midTic = roulette->speed * (FRACUNIT >> 1); - - return FixedMul(FixedDiv(midTic - curTic, ((roulette->speed + 1) << FRACBITS)), ROULETTE_SPACING); -} +/*-------------------------------------------------- + void K_KartItemRoulette(player_t *const player, ticcmd_t *const cmd) + See header file for description. +--------------------------------------------------*/ void K_KartItemRoulette(player_t *const player, ticcmd_t *const cmd) { itemroulette_t *const roulette = &player->itemRoulette; diff --git a/src/k_roulette.h b/src/k_roulette.h index fbc6d4a4b..0cef89f7a 100644 --- a/src/k_roulette.h +++ b/src/k_roulette.h @@ -16,19 +16,154 @@ #include "doomtype.h" #include "d_player.h" -boolean K_ItemEnabled(SINT8 item); -boolean K_ItemSingularity(kartitems_t item); - -INT32 K_KartGetItemOdds(const player_t *player, itemroulette_t *const roulette, UINT8 pos, kartitems_t item); -void K_FillItemRouletteData(const player_t *player, itemroulette_t *const roulette); - -void K_StartItemRoulette(player_t *const player); -void K_StartEggmanRoulette(player_t *const player); - #define ROULETTE_SPACING (36 << FRACBITS) #define ROULETTE_SPACING_SPLITSCREEN (16 << FRACBITS) + +/*-------------------------------------------------- + boolean K_ItemEnabled(kartitems_t item); + + Determines whenever or not an item should + be enabled. Accounts for situations where + rules should not be able to be changed. + + Input Arguments:- + item - The item to check. + + Return:- + true if the item is enabled, otherwise false. +--------------------------------------------------*/ + +boolean K_ItemEnabled(kartitems_t item); + + +/*-------------------------------------------------- + boolean K_ItemSingularity(kartitems_t item); + + Determines whenever or not this item should + be using special cases to prevent more than + one existing at a time. + + Input Arguments:- + item - The item to check. + + Return:- + true to use the special rules, otherwise false. +--------------------------------------------------*/ + +boolean K_ItemSingularity(kartitems_t item); + + +/*-------------------------------------------------- + INT32 K_KartGetItemOdds(const player_t *player, itemroulette_t *const roulette, UINT8 pos, kartitems_t item); + + Gets the frequency an item should show up in + an item bracket, and adjusted for special + factors (such as Frantic Items). + + Input Arguments:- + player - The player we intend to give the item to later. + Can be NULL for generic use. + roulette - The roulette data that we intend to + insert this item into. + pos - The item bracket we are in. + item - The item to give. + + Return:- + The number of items we want to insert + into the roulette. +--------------------------------------------------*/ + +INT32 K_KartGetItemOdds(const player_t *player, itemroulette_t *const roulette, UINT8 pos, kartitems_t item); + + +/*-------------------------------------------------- + void K_FillItemRouletteData(const player_t *player, itemroulette_t *const roulette); + + Fills out the item roulette struct when it is + initially created. This function needs to be + HUD-safe for the item debugger, so the player + cannot be modified at this stage. + + Input Arguments:- + player - The player this roulette data is for. + Can be NULL for generic use. + roulette - The roulette data struct to fill out. + + Return:- + N/A +--------------------------------------------------*/ + +void K_FillItemRouletteData(const player_t *player, itemroulette_t *const roulette); + + +/*-------------------------------------------------- + void K_StartItemRoulette(player_t *const player); + + Starts the item roulette sequence for a player. + This stage can only be used by gameplay, thus + this handles gameplay modifications as well. + + Input Arguments:- + player - The player to start the item roulette for. + + Return:- + N/A +--------------------------------------------------*/ + +void K_StartItemRoulette(player_t *const player); + + +/*-------------------------------------------------- + void K_StartEggmanRoulette(player_t *const player); + + Starts the Eggman Mark roulette sequence for + a player. Looks identical to a regular item + roulette, but gives you the Eggman explosion + countdown instead when confirming it. + + Input Arguments:- + player - The player to start the Eggman roulette for. + + Return:- + N/A +--------------------------------------------------*/ + +void K_StartEggmanRoulette(player_t *const player); + + +/*-------------------------------------------------- + fixed_t K_GetRouletteOffset(itemroulette_t *const roulette, fixed_t renderDelta); + + Gets the Y offset, for use in the roulette HUD. + A separate function since it is used both by the + HUD itself, as well as when confirming an item. + + Input Arguments:- + roulette - The roulette we are drawing for. + renderDelta - Fractional tic delta, when used for HUD. + + Return:- + The Y offset when drawing the item. +--------------------------------------------------*/ + fixed_t K_GetRouletteOffset(itemroulette_t *const roulette, fixed_t renderDelta); + +/*-------------------------------------------------- + void K_KartItemRoulette(player_t *const player, ticcmd_t *cmd); + + Handles ticking a player's item roulette, + and player input for stopping it. + + Input Arguments:- + player - The player to run the item roulette for. + cmd - The player's controls. + + Return:- + N/A +--------------------------------------------------*/ + void K_KartItemRoulette(player_t *const player, ticcmd_t *cmd); + #endif // __K_ROULETTE_H__