mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-03-12 22:02:12 +00:00
Merge branch 'master' of https://git.magicalgirl.moe/STJr/SRB2Internal.git into metalrecording
# Conflicts: # src/p_user.c
This commit is contained in:
commit
5729ba3cd2
69 changed files with 5905 additions and 2319 deletions
|
@ -423,7 +423,11 @@ if(${SRB2_CONFIG_HWRENDER})
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_light.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_main.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md2.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md2load.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md3load.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_model.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_trick.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/hardware/u_list.c
|
||||
)
|
||||
|
||||
set (SRB2_HWRENDER_HEADERS
|
||||
|
@ -437,6 +441,10 @@ if(${SRB2_CONFIG_HWRENDER})
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_light.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_main.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md2.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md2load.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md3load.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_model.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/hardware/u_list.h
|
||||
)
|
||||
|
||||
set(SRB2_R_OPENGL_SOURCES
|
||||
|
|
23
src/Makefile
23
src/Makefile
|
@ -226,7 +226,8 @@ else
|
|||
#OPTS+=-DUSE_PALETTED_TEXTURE
|
||||
OPTS+=-DHWRENDER
|
||||
OBJS+=$(OBJDIR)/hw_bsp.o $(OBJDIR)/hw_draw.o $(OBJDIR)/hw_light.o \
|
||||
$(OBJDIR)/hw_main.o $(OBJDIR)/hw_clip.o $(OBJDIR)/hw_md2.o $(OBJDIR)/hw_cache.o $(OBJDIR)/hw_trick.o
|
||||
$(OBJDIR)/hw_main.o $(OBJDIR)/hw_clip.o $(OBJDIR)/hw_md2.o $(OBJDIR)/hw_cache.o $(OBJDIR)/hw_trick.o \
|
||||
$(OBJDIR)/hw_md2load.o $(OBJDIR)/hw_md3load.o $(OBJDIR)/hw_model.o $(OBJDIR)/u_list.o
|
||||
endif
|
||||
|
||||
ifdef NOHS
|
||||
|
@ -646,16 +647,18 @@ ifdef MINGW
|
|||
$(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \
|
||||
doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \
|
||||
command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \
|
||||
hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h am_map.h \
|
||||
d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \
|
||||
hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \
|
||||
hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \
|
||||
am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \
|
||||
p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h
|
||||
$(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@
|
||||
else
|
||||
$(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \
|
||||
doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \
|
||||
command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \
|
||||
hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h am_map.h \
|
||||
d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \
|
||||
hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \
|
||||
hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \
|
||||
am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \
|
||||
p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h
|
||||
$(CC) $(CFLAGS) $(WFLAGS) -I/usr/X11R6/include -c $< -o $@
|
||||
endif
|
||||
|
@ -733,16 +736,18 @@ ifndef NOHW
|
|||
$(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \
|
||||
doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \
|
||||
command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \
|
||||
hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h am_map.h \
|
||||
d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \
|
||||
hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \
|
||||
hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \
|
||||
am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \
|
||||
p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h
|
||||
$(CC) $(CFLAGS) $(WFLAGS) -D_WINDOWS -mwindows -c $< -o $@
|
||||
|
||||
$(OBJDIR)/ogl_win.o: hardware/r_opengl/ogl_win.c hardware/r_opengl/r_opengl.h \
|
||||
doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \
|
||||
command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \
|
||||
hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h am_map.h \
|
||||
d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \
|
||||
hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \
|
||||
hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \
|
||||
am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \
|
||||
p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h
|
||||
$(CC) $(CFLAGS) $(WFLAGS) -D_WINDOWS -mwindows -c $< -o $@
|
||||
endif
|
||||
|
|
|
@ -4708,7 +4708,12 @@ void TryRunTics(tic_t realtics)
|
|||
if (neededtic > gametic && !resynch_local_inprogress)
|
||||
{
|
||||
if (advancedemo)
|
||||
D_StartTitle();
|
||||
{
|
||||
if (timedemo_quit)
|
||||
COM_ImmedExecute("quit");
|
||||
else
|
||||
D_StartTitle();
|
||||
}
|
||||
else
|
||||
// run the count * tics
|
||||
while (neededtic > gametic)
|
||||
|
|
127
src/d_main.c
127
src/d_main.c
|
@ -291,11 +291,8 @@ static void D_Display(void)
|
|||
switch (gamestate)
|
||||
{
|
||||
case GS_TITLESCREEN:
|
||||
if (!titlemapinaction || !curbghide) {
|
||||
F_TitleScreenDrawer();
|
||||
break;
|
||||
}
|
||||
/* FALLTHRU */
|
||||
F_TitleScreenDrawer();
|
||||
break;
|
||||
case GS_LEVEL:
|
||||
if (!gametic)
|
||||
break;
|
||||
|
@ -366,56 +363,11 @@ static void D_Display(void)
|
|||
|
||||
// clean up border stuff
|
||||
// see if the border needs to be initially drawn
|
||||
if (gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction && curbghide && (!hidetitlemap)))
|
||||
if (gamestate == GS_LEVEL)
|
||||
{
|
||||
// draw the view directly
|
||||
|
||||
if (!automapactive && !dedicated && cv_renderview.value)
|
||||
{
|
||||
if (players[displayplayer].mo || players[displayplayer].playerstate == PST_DEAD)
|
||||
{
|
||||
topleft = screens[0] + viewwindowy*vid.width + viewwindowx;
|
||||
objectsdrawn = 0;
|
||||
#ifdef HWRENDER
|
||||
if (rendermode != render_soft)
|
||||
HWR_RenderPlayerView(0, &players[displayplayer]);
|
||||
else
|
||||
#endif
|
||||
if (rendermode != render_none)
|
||||
R_RenderPlayerView(&players[displayplayer]);
|
||||
}
|
||||
|
||||
// render the second screen
|
||||
if (splitscreen && players[secondarydisplayplayer].mo)
|
||||
{
|
||||
#ifdef HWRENDER
|
||||
if (rendermode != render_soft)
|
||||
HWR_RenderPlayerView(1, &players[secondarydisplayplayer]);
|
||||
else
|
||||
#endif
|
||||
if (rendermode != render_none)
|
||||
{
|
||||
viewwindowy = vid.height / 2;
|
||||
M_Memcpy(ylookup, ylookup2, viewheight*sizeof (ylookup[0]));
|
||||
|
||||
topleft = screens[0] + viewwindowy*vid.width + viewwindowx;
|
||||
|
||||
R_RenderPlayerView(&players[secondarydisplayplayer]);
|
||||
|
||||
viewwindowy = 0;
|
||||
M_Memcpy(ylookup, ylookup1, viewheight*sizeof (ylookup[0]));
|
||||
}
|
||||
}
|
||||
|
||||
// Image postprocessing effect
|
||||
if (rendermode == render_soft)
|
||||
{
|
||||
if (postimgtype)
|
||||
V_DoPostProcessor(0, postimgtype, postimgparam);
|
||||
if (postimgtype2)
|
||||
V_DoPostProcessor(1, postimgtype2, postimgparam2);
|
||||
}
|
||||
}
|
||||
D_Render();
|
||||
|
||||
if (lastdraw)
|
||||
{
|
||||
|
@ -428,14 +380,9 @@ static void D_Display(void)
|
|||
lastdraw = false;
|
||||
}
|
||||
|
||||
if (gamestate == GS_LEVEL)
|
||||
{
|
||||
ST_Drawer();
|
||||
F_TextPromptDrawer();
|
||||
HU_Drawer();
|
||||
}
|
||||
else
|
||||
F_TitleScreenDrawer();
|
||||
ST_Drawer();
|
||||
F_TextPromptDrawer();
|
||||
HU_Drawer();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -491,6 +438,13 @@ static void D_Display(void)
|
|||
F_RunWipe(wipetypepost, gamestate != GS_TIMEATTACK && gamestate != GS_TITLESCREEN);
|
||||
}
|
||||
|
||||
// reset counters so timedemo doesn't count the wipe duration
|
||||
if (timingdemo)
|
||||
{
|
||||
framecount = 0;
|
||||
demostarttime = I_GetTime();
|
||||
}
|
||||
|
||||
wipetypepost = -1;
|
||||
}
|
||||
else
|
||||
|
@ -531,6 +485,56 @@ static void D_Display(void)
|
|||
}
|
||||
}
|
||||
|
||||
void D_Render(void)
|
||||
{
|
||||
if (!automapactive && !dedicated && cv_renderview.value)
|
||||
{
|
||||
if (players[displayplayer].mo || players[displayplayer].playerstate == PST_DEAD)
|
||||
{
|
||||
topleft = screens[0] + viewwindowy*vid.width + viewwindowx;
|
||||
objectsdrawn = 0;
|
||||
#ifdef HWRENDER
|
||||
if (rendermode != render_soft)
|
||||
HWR_RenderPlayerView(0, &players[displayplayer]);
|
||||
else
|
||||
#endif
|
||||
if (rendermode != render_none)
|
||||
R_RenderPlayerView(&players[displayplayer]);
|
||||
}
|
||||
|
||||
// render the second screen
|
||||
if (splitscreen && players[secondarydisplayplayer].mo)
|
||||
{
|
||||
#ifdef HWRENDER
|
||||
if (rendermode != render_soft)
|
||||
HWR_RenderPlayerView(1, &players[secondarydisplayplayer]);
|
||||
else
|
||||
#endif
|
||||
if (rendermode != render_none)
|
||||
{
|
||||
viewwindowy = vid.height / 2;
|
||||
M_Memcpy(ylookup, ylookup2, viewheight*sizeof (ylookup[0]));
|
||||
|
||||
topleft = screens[0] + viewwindowy*vid.width + viewwindowx;
|
||||
|
||||
R_RenderPlayerView(&players[secondarydisplayplayer]);
|
||||
|
||||
viewwindowy = 0;
|
||||
M_Memcpy(ylookup, ylookup1, viewheight*sizeof (ylookup[0]));
|
||||
}
|
||||
}
|
||||
|
||||
// Image postprocessing effect
|
||||
if (rendermode == render_soft)
|
||||
{
|
||||
if (postimgtype)
|
||||
V_DoPostProcessor(0, postimgtype, postimgparam);
|
||||
if (postimgtype2)
|
||||
V_DoPostProcessor(1, postimgtype2, postimgparam2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// D_SRB2Loop
|
||||
// =========================================================================
|
||||
|
@ -544,9 +548,6 @@ void D_SRB2Loop(void)
|
|||
if (dedicated)
|
||||
server = true;
|
||||
|
||||
if (M_CheckParm("-voodoo")) // 256x256 Texture Limiter
|
||||
COM_BufAddText("gr_voodoocompatibility on\n");
|
||||
|
||||
// Pushing of + parameters is now done back in D_SRB2Main, not here.
|
||||
|
||||
CONS_Printf("I_StartupKeyboard()...\n");
|
||||
|
|
|
@ -54,4 +54,7 @@ const char *D_Home(void);
|
|||
void D_AdvanceDemo(void);
|
||||
void D_StartTitle(void);
|
||||
|
||||
/* Here for title maps */
|
||||
void D_Render(void);
|
||||
|
||||
#endif //__D_MAIN__
|
||||
|
|
|
@ -365,6 +365,11 @@ consvar_t cv_mute = {"mute", "Off", CV_NETVAR|CV_CALL, CV_OnOff, Mute_OnChange,
|
|||
|
||||
consvar_t cv_sleep = {"cpusleep", "1", CV_SAVE, sleeping_cons_t, NULL, -1, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
char timedemo_name[256];
|
||||
boolean timedemo_csv;
|
||||
char timedemo_csv_id[256];
|
||||
boolean timedemo_quit;
|
||||
|
||||
INT16 gametype = GT_COOP;
|
||||
boolean splitscreen = false;
|
||||
boolean circuitmap = false;
|
||||
|
@ -1569,11 +1574,11 @@ static void Command_Playdemo_f(void)
|
|||
|
||||
static void Command_Timedemo_f(void)
|
||||
{
|
||||
char name[256];
|
||||
size_t i = 0;
|
||||
|
||||
if (COM_Argc() != 2)
|
||||
if (COM_Argc() < 2)
|
||||
{
|
||||
CONS_Printf(M_GetText("timedemo <demoname>: time a demo\n"));
|
||||
CONS_Printf(M_GetText("timedemo <demoname> [-csv [<trialid>]] [-quit]: time a demo\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1590,12 +1595,23 @@ static void Command_Timedemo_f(void)
|
|||
G_StopMetalDemo();
|
||||
|
||||
// open the demo file
|
||||
strcpy (name, COM_Argv(1));
|
||||
strcpy (timedemo_name, COM_Argv(1));
|
||||
// dont add .lmp so internal game demos can be played
|
||||
|
||||
CONS_Printf(M_GetText("Timing demo '%s'.\n"), name);
|
||||
// print timedemo results as CSV?
|
||||
i = COM_CheckParm("-csv");
|
||||
timedemo_csv = (i > 0);
|
||||
if (COM_CheckParm("-quit") != i + 1)
|
||||
strcpy(timedemo_csv_id, COM_Argv(i + 1)); // user-defined string to identify row
|
||||
else
|
||||
timedemo_csv_id[0] = 0;
|
||||
|
||||
G_TimeDemo(name);
|
||||
// exit after the timedemo?
|
||||
timedemo_quit = (COM_CheckParm("-quit") > 0);
|
||||
|
||||
CONS_Printf(M_GetText("Timing demo '%s'.\n"), timedemo_name);
|
||||
|
||||
G_TimeDemo(timedemo_name);
|
||||
}
|
||||
|
||||
// stop current demo
|
||||
|
@ -1646,7 +1662,31 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pultmode, boolean rese
|
|||
// The supplied data are assumed to be good.
|
||||
I_Assert(delay >= 0 && delay <= 2);
|
||||
if (mapnum != -1)
|
||||
{
|
||||
CV_SetValue(&cv_nextmap, mapnum);
|
||||
// Kick bot from special stages
|
||||
if (botskin)
|
||||
{
|
||||
if (G_IsSpecialStage(mapnum) || (mapheaderinfo[mapnum-1] && (mapheaderinfo[mapnum-1]->typeoflevel & TOL_NIGHTS)))
|
||||
{
|
||||
if (botingame)
|
||||
{
|
||||
//CL_RemoveSplitscreenPlayer();
|
||||
botingame = false;
|
||||
playeringame[1] = false;
|
||||
}
|
||||
}
|
||||
else if (!botingame)
|
||||
{
|
||||
//CL_AddSplitscreenPlayer();
|
||||
botingame = true;
|
||||
secondarydisplayplayer = 1;
|
||||
playeringame[1] = true;
|
||||
players[1].bot = 1;
|
||||
SendNameAndColor2();
|
||||
}
|
||||
}
|
||||
}
|
||||
CONS_Debug(DBG_GAMELOGIC, "Map change: mapnum=%d gametype=%d ultmode=%d resetplayers=%d delay=%d skipprecutscene=%d\n",
|
||||
mapnum, newgametype, pultmode, resetplayers, delay, skipprecutscene);
|
||||
if ((netgame || multiplayer) && !((gametype == newgametype) && (newgametype == GT_COOP)))
|
||||
|
@ -1689,29 +1729,6 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pultmode, boolean rese
|
|||
return;
|
||||
}
|
||||
|
||||
// Kick bot from special stages
|
||||
if (botskin)
|
||||
{
|
||||
if (G_IsSpecialStage(mapnum) || (mapheaderinfo[mapnum-1] && (mapheaderinfo[mapnum-1]->typeoflevel & TOL_NIGHTS)))
|
||||
{
|
||||
if (botingame)
|
||||
{
|
||||
//CL_RemoveSplitscreenPlayer();
|
||||
botingame = false;
|
||||
playeringame[1] = false;
|
||||
}
|
||||
}
|
||||
else if (!botingame)
|
||||
{
|
||||
//CL_AddSplitscreenPlayer();
|
||||
botingame = true;
|
||||
secondarydisplayplayer = 1;
|
||||
playeringame[1] = true;
|
||||
players[1].bot = 1;
|
||||
SendNameAndColor2();
|
||||
}
|
||||
}
|
||||
|
||||
chmappending++;
|
||||
if (netgame)
|
||||
WRITEUINT32(buf_p, M_RandomizedSeed()); // random seed
|
||||
|
|
|
@ -113,6 +113,11 @@ extern consvar_t cv_skipmapcheck;
|
|||
|
||||
extern consvar_t cv_sleep;
|
||||
|
||||
extern char timedemo_name[256];
|
||||
extern boolean timedemo_csv;
|
||||
extern char timedemo_csv_id[256];
|
||||
extern boolean timedemo_quit;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
XD_NAMEANDCOLOR = 1,
|
||||
|
|
184
src/dehacked.c
184
src/dehacked.c
|
@ -2089,12 +2089,59 @@ static void readmenu(MYFILE *f, INT32 num)
|
|||
menupres[num].bgcolor = get_number(word2);
|
||||
titlechanged = true;
|
||||
}
|
||||
else if (fastcmp(word, "HIDETITLEPICS") || fastcmp(word, "HIDEPICS"))
|
||||
else if (fastcmp(word, "HIDETITLEPICS") || fastcmp(word, "HIDEPICS") || fastcmp(word, "TITLEPICSHIDE"))
|
||||
{
|
||||
// true by default, except MM_MAIN
|
||||
menupres[num].hidetitlepics = (boolean)(value || word2[0] == 'T' || word2[0] == 'Y');
|
||||
titlechanged = true;
|
||||
}
|
||||
else if (fastcmp(word, "TITLEPICSMODE"))
|
||||
{
|
||||
if (fastcmp(word2, "USER"))
|
||||
menupres[num].ttmode = TTMODE_USER;
|
||||
else if (fastcmp(word2, "ALACROIX"))
|
||||
menupres[num].ttmode = TTMODE_ALACROIX;
|
||||
else if (fastcmp(word2, "HIDE") || fastcmp(word2, "HIDDEN") || fastcmp(word2, "NONE"))
|
||||
{
|
||||
menupres[num].ttmode = TTMODE_USER;
|
||||
menupres[num].ttname[0] = 0;
|
||||
menupres[num].hidetitlepics = true;
|
||||
}
|
||||
else // if (fastcmp(word2, "OLD") || fastcmp(word2, "SSNTAILS"))
|
||||
menupres[num].ttmode = TTMODE_OLD;
|
||||
titlechanged = true;
|
||||
}
|
||||
else if (fastcmp(word, "TITLEPICSSCALE"))
|
||||
{
|
||||
// Don't handle Alacroix special case here; see Maincfg section.
|
||||
menupres[num].ttscale = max(1, min(8, (UINT8)get_number(word2)));
|
||||
titlechanged = true;
|
||||
}
|
||||
else if (fastcmp(word, "TITLEPICSNAME"))
|
||||
{
|
||||
strncpy(menupres[num].ttname, word2, 9);
|
||||
titlechanged = true;
|
||||
}
|
||||
else if (fastcmp(word, "TITLEPICSX"))
|
||||
{
|
||||
menupres[num].ttx = (INT16)get_number(word2);
|
||||
titlechanged = true;
|
||||
}
|
||||
else if (fastcmp(word, "TITLEPICSY"))
|
||||
{
|
||||
menupres[num].tty = (INT16)get_number(word2);
|
||||
titlechanged = true;
|
||||
}
|
||||
else if (fastcmp(word, "TITLEPICSLOOP"))
|
||||
{
|
||||
menupres[num].ttloop = (INT16)get_number(word2);
|
||||
titlechanged = true;
|
||||
}
|
||||
else if (fastcmp(word, "TITLEPICSTICS"))
|
||||
{
|
||||
menupres[num].tttics = (UINT16)get_number(word2);
|
||||
titlechanged = true;
|
||||
}
|
||||
else if (fastcmp(word, "TITLESCROLLSPEED") || fastcmp(word, "TITLESCROLLXSPEED")
|
||||
|| fastcmp(word, "SCROLLSPEED") || fastcmp(word, "SCROLLXSPEED"))
|
||||
{
|
||||
|
@ -2308,6 +2355,7 @@ static actionpointer_t actionpointers[] =
|
|||
{{A_ThrownRing}, "A_THROWNRING"},
|
||||
{{A_SetSolidSteam}, "A_SETSOLIDSTEAM"},
|
||||
{{A_UnsetSolidSteam}, "A_UNSETSOLIDSTEAM"},
|
||||
{{A_SignSpin}, "S_SIGNSPIN"},
|
||||
{{A_SignPlayer}, "A_SIGNPLAYER"},
|
||||
{{A_OverlayThink}, "A_OVERLAYTHINK"},
|
||||
{{A_JetChase}, "A_JETCHASE"},
|
||||
|
@ -3492,11 +3540,78 @@ static void readmaincfg(MYFILE *f)
|
|||
titlemap = (INT16)value;
|
||||
titlechanged = true;
|
||||
}
|
||||
else if (fastcmp(word, "HIDETITLEPICS"))
|
||||
else if (fastcmp(word, "HIDETITLEPICS") || fastcmp(word, "TITLEPICSHIDE"))
|
||||
{
|
||||
hidetitlepics = (boolean)(value || word2[0] == 'T' || word2[0] == 'Y');
|
||||
titlechanged = true;
|
||||
}
|
||||
else if (fastcmp(word, "TITLEPICSMODE"))
|
||||
{
|
||||
if (fastcmp(word2, "USER"))
|
||||
ttmode = TTMODE_USER;
|
||||
else if (fastcmp(word2, "ALACROIX"))
|
||||
ttmode = TTMODE_ALACROIX;
|
||||
else if (fastcmp(word2, "HIDE") || fastcmp(word2, "HIDDEN") || fastcmp(word2, "NONE"))
|
||||
{
|
||||
ttmode = TTMODE_USER;
|
||||
ttname[0] = 0;
|
||||
hidetitlepics = true;
|
||||
}
|
||||
else // if (fastcmp(word2, "OLD") || fastcmp(word2, "SSNTAILS"))
|
||||
ttmode = TTMODE_OLD;
|
||||
titlechanged = true;
|
||||
}
|
||||
else if (fastcmp(word, "TITLEPICSSCALE"))
|
||||
{
|
||||
ttscale = max(1, min(8, (UINT8)get_number(word2)));
|
||||
titlechanged = true;
|
||||
}
|
||||
else if (fastcmp(word, "TITLEPICSSCALESAVAILABLE"))
|
||||
{
|
||||
// SPECIAL CASE for Alacroix: Comma-separated list of resolutions that are available
|
||||
// for gfx loading.
|
||||
ttavailable[0] = ttavailable[1] = ttavailable[2] = ttavailable[3] =\
|
||||
ttavailable[4] = ttavailable[5] = false;
|
||||
|
||||
if (strstr(word2, "1") != NULL)
|
||||
ttavailable[0] = true;
|
||||
if (strstr(word2, "2") != NULL)
|
||||
ttavailable[1] = true;
|
||||
if (strstr(word2, "3") != NULL)
|
||||
ttavailable[2] = true;
|
||||
if (strstr(word2, "4") != NULL)
|
||||
ttavailable[3] = true;
|
||||
if (strstr(word2, "5") != NULL)
|
||||
ttavailable[4] = true;
|
||||
if (strstr(word2, "6") != NULL)
|
||||
ttavailable[5] = true;
|
||||
titlechanged = true;
|
||||
}
|
||||
else if (fastcmp(word, "TITLEPICSNAME"))
|
||||
{
|
||||
strncpy(ttname, word2, 9);
|
||||
titlechanged = true;
|
||||
}
|
||||
else if (fastcmp(word, "TITLEPICSX"))
|
||||
{
|
||||
ttx = (INT16)get_number(word2);
|
||||
titlechanged = true;
|
||||
}
|
||||
else if (fastcmp(word, "TITLEPICSY"))
|
||||
{
|
||||
tty = (INT16)get_number(word2);
|
||||
titlechanged = true;
|
||||
}
|
||||
else if (fastcmp(word, "TITLEPICSLOOP"))
|
||||
{
|
||||
ttloop = (INT16)get_number(word2);
|
||||
titlechanged = true;
|
||||
}
|
||||
else if (fastcmp(word, "TITLEPICSTICS"))
|
||||
{
|
||||
tttics = (UINT16)get_number(word2);
|
||||
titlechanged = true;
|
||||
}
|
||||
else if (fastcmp(word, "TITLESCROLLSPEED") || fastcmp(word, "TITLESCROLLXSPEED"))
|
||||
{
|
||||
titlescrollxspeed = get_number(word2);
|
||||
|
@ -5367,59 +5482,18 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_BUBBLES4",
|
||||
|
||||
// Level End Sign
|
||||
"S_SIGN1",
|
||||
"S_SIGN2",
|
||||
"S_SIGN3",
|
||||
"S_SIGN4",
|
||||
"S_SIGN5",
|
||||
"S_SIGN6",
|
||||
"S_SIGN7",
|
||||
"S_SIGN8",
|
||||
"S_SIGN9",
|
||||
"S_SIGN10",
|
||||
"S_SIGN11",
|
||||
"S_SIGN12",
|
||||
"S_SIGN13",
|
||||
"S_SIGN14",
|
||||
"S_SIGN15",
|
||||
"S_SIGN16",
|
||||
"S_SIGN17",
|
||||
"S_SIGN18",
|
||||
"S_SIGN19",
|
||||
"S_SIGN20",
|
||||
"S_SIGN21",
|
||||
"S_SIGN22",
|
||||
"S_SIGN23",
|
||||
"S_SIGN24",
|
||||
"S_SIGN25",
|
||||
"S_SIGN26",
|
||||
"S_SIGN27",
|
||||
"S_SIGN28",
|
||||
"S_SIGN29",
|
||||
"S_SIGN30",
|
||||
"S_SIGN31",
|
||||
"S_SIGN32",
|
||||
"S_SIGN33",
|
||||
"S_SIGN34",
|
||||
"S_SIGN35",
|
||||
"S_SIGN36",
|
||||
"S_SIGN37",
|
||||
"S_SIGN38",
|
||||
"S_SIGN39",
|
||||
"S_SIGN40",
|
||||
"S_SIGN41",
|
||||
"S_SIGN42",
|
||||
"S_SIGN43",
|
||||
"S_SIGN44",
|
||||
"S_SIGN45",
|
||||
"S_SIGN46",
|
||||
"S_SIGN47",
|
||||
"S_SIGN48",
|
||||
"S_SIGN49",
|
||||
"S_SIGN50",
|
||||
"S_SIGN51",
|
||||
"S_SIGN52", // Eggman
|
||||
"S_SIGN53",
|
||||
"S_SIGN",
|
||||
"S_SIGNSPIN1",
|
||||
"S_SIGNSPIN2",
|
||||
"S_SIGNSPIN3",
|
||||
"S_SIGNSPIN4",
|
||||
"S_SIGNSPIN5",
|
||||
"S_SIGNSPIN6",
|
||||
"S_SIGNPLAYER",
|
||||
"S_SIGNSLOW",
|
||||
"S_SIGNSTOP",
|
||||
"S_SIGNBOARD",
|
||||
"S_EGGMANSIGN",
|
||||
|
||||
// Spike Ball
|
||||
"S_SPIKEBALL1",
|
||||
|
|
|
@ -326,16 +326,18 @@ size_t strlcpy(char *dst, const char *src, size_t siz);
|
|||
|
||||
/* Miscellaneous types that don't fit anywhere else (Can this be changed?) */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT8 red;
|
||||
UINT8 green;
|
||||
UINT8 blue;
|
||||
UINT8 alpha;
|
||||
} byteColor_t;
|
||||
|
||||
union FColorRGBA
|
||||
{
|
||||
UINT32 rgba;
|
||||
struct
|
||||
{
|
||||
UINT8 red;
|
||||
UINT8 green;
|
||||
UINT8 blue;
|
||||
UINT8 alpha;
|
||||
} s;
|
||||
byteColor_t s;
|
||||
} ATTRPACK;
|
||||
typedef union FColorRGBA RGBA_t;
|
||||
|
||||
|
|
1074
src/f_finale.c
1074
src/f_finale.c
File diff suppressed because it is too large
Load diff
|
@ -77,6 +77,28 @@ void F_ContinueDrawer(void);
|
|||
extern INT32 titlescrollxspeed;
|
||||
extern INT32 titlescrollyspeed;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TTMODE_NONE = 0,
|
||||
TTMODE_OLD,
|
||||
TTMODE_ALACROIX,
|
||||
TTMODE_USER
|
||||
} ttmode_enum;
|
||||
|
||||
#define TTMAX_ALACROIX 30 // max frames for SONIC typeface, plus one for NULL terminating entry
|
||||
#define TTMAX_USER 100
|
||||
|
||||
extern ttmode_enum ttmode;
|
||||
extern UINT8 ttscale;
|
||||
// ttmode user vars
|
||||
extern char ttname[9];
|
||||
extern INT16 ttx;
|
||||
extern INT16 tty;
|
||||
extern INT16 ttloop;
|
||||
extern UINT16 tttics;
|
||||
extern boolean ttavailable[6];
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TITLEMAP_OFF = 0,
|
||||
|
@ -89,13 +111,22 @@ typedef enum
|
|||
extern mobj_t *titlemapcameraref;
|
||||
extern char curbgname[9];
|
||||
extern SINT8 curfadevalue;
|
||||
extern boolean curhidepics;
|
||||
extern INT32 curbgcolor;
|
||||
extern INT32 curbgxspeed;
|
||||
extern INT32 curbgyspeed;
|
||||
extern boolean curbghide;
|
||||
extern boolean hidetitlemap;
|
||||
|
||||
extern boolean curhidepics;
|
||||
extern ttmode_enum curttmode;
|
||||
extern UINT8 curttscale;
|
||||
// ttmode user vars
|
||||
extern char curttname[9];
|
||||
extern INT16 curttx;
|
||||
extern INT16 curtty;
|
||||
extern INT16 curttloop;
|
||||
extern UINT16 curtttics;
|
||||
|
||||
#define TITLEBACKGROUNDACTIVE (curfadevalue >= 0 || curbgname[0])
|
||||
|
||||
void F_InitMenuPresValues(void);
|
||||
|
|
50
src/g_game.c
50
src/g_game.c
|
@ -104,7 +104,7 @@ UINT32 demoIdleTime = 3*TICRATE;
|
|||
boolean timingdemo; // if true, exit with report on completion
|
||||
boolean nodrawers; // for comparative timing purposes
|
||||
boolean noblit; // for comparative timing purposes
|
||||
static tic_t demostarttime; // for comparative timing purposes
|
||||
tic_t demostarttime; // for comparative timing purposes
|
||||
|
||||
boolean netgame; // only true if packets are broadcast
|
||||
boolean multiplayer;
|
||||
|
@ -2805,7 +2805,7 @@ void G_AddPlayer(INT32 playernum)
|
|||
|
||||
countplayers++;
|
||||
|
||||
if (!players->exiting)
|
||||
if (!players[i].exiting)
|
||||
notexiting++;
|
||||
|
||||
if (!(cv_coopstarposts.value && (gametype == GT_COOP) && (p->starpostnum < players[i].starpostnum)))
|
||||
|
@ -3360,6 +3360,11 @@ void G_LoadGameData(void)
|
|||
// Allow saving of gamedata beyond this point
|
||||
gamedataloaded = true;
|
||||
|
||||
if (M_CheckParm("-gamedata") && M_IsNextParm())
|
||||
{
|
||||
strlcpy(gamedatafilename, M_GetNextParm(), sizeof gamedatafilename);
|
||||
}
|
||||
|
||||
if (M_CheckParm("-resetdata"))
|
||||
return; // Don't load (essentially, reset).
|
||||
|
||||
|
@ -6378,7 +6383,46 @@ boolean G_CheckDemoStatus(void)
|
|||
timingdemo = false;
|
||||
f1 = (double)demotime;
|
||||
f2 = (double)framecount*TICRATE;
|
||||
CONS_Printf(M_GetText("timed %u gametics in %d realtics\n%f seconds, %f avg fps\n"), leveltime,demotime,f1/TICRATE,f2/f1);
|
||||
|
||||
CONS_Printf(M_GetText("timed %u gametics in %d realtics - %u frames\n%f seconds, %f avg fps\n"),
|
||||
leveltime,demotime,(UINT32)framecount,f1/TICRATE,f2/f1);
|
||||
|
||||
// CSV-readable timedemo results, for external parsing
|
||||
if (timedemo_csv)
|
||||
{
|
||||
FILE *f;
|
||||
const char *csvpath = va("%s"PATHSEP"%s", srb2home, "timedemo.csv");
|
||||
const char *header = "id,demoname,seconds,avgfps,leveltime,demotime,framecount,ticrate,rendermode,vidmode,vidwidth,vidheight,procbits\n";
|
||||
const char *rowformat = "\"%s\",\"%s\",%f,%f,%u,%d,%u,%u,%u,%u,%u,%u,%u\n";
|
||||
boolean headerrow = !FIL_FileExists(csvpath);
|
||||
UINT8 procbits = 0;
|
||||
|
||||
// Bitness
|
||||
if (sizeof(void*) == 4)
|
||||
procbits = 32;
|
||||
else if (sizeof(void*) == 8)
|
||||
procbits = 64;
|
||||
|
||||
f = fopen(csvpath, "a+");
|
||||
|
||||
if (f)
|
||||
{
|
||||
if (headerrow)
|
||||
fputs(header, f);
|
||||
fprintf(f, rowformat,
|
||||
timedemo_csv_id,timedemo_name,f1/TICRATE,f2/f1,leveltime,demotime,(UINT32)framecount,TICRATE,rendermode,vid.modenum,vid.width,vid.height,procbits);
|
||||
fclose(f);
|
||||
CONS_Printf("Timedemo results saved to '%s'\n", csvpath);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Just print the CSV output to console
|
||||
CON_LogMessage(header);
|
||||
CONS_Printf(rowformat,
|
||||
timedemo_csv_id,timedemo_name,f1/TICRATE,f2/f1,leveltime,demotime,(UINT32)framecount,TICRATE,rendermode,vid.modenum,vid.width,vid.height,procbits);
|
||||
}
|
||||
}
|
||||
|
||||
if (restorecv_vidwait != cv_vidwait.value)
|
||||
CV_SetValue(&cv_vidwait, restorecv_vidwait);
|
||||
D_AdvanceDemo();
|
||||
|
|
|
@ -37,6 +37,7 @@ extern boolean playeringame[MAXPLAYERS];
|
|||
|
||||
// demoplaying back and demo recording
|
||||
extern boolean demoplayback, titledemo, demorecording, timingdemo;
|
||||
extern tic_t demostarttime;
|
||||
|
||||
// Quit after playing a demo from cmdline.
|
||||
extern boolean singledemo;
|
||||
|
|
|
@ -505,43 +505,6 @@ static void HWR_ResizeBlock(INT32 originalwidth, INT32 originalheight,
|
|||
if (blockheight < 1)
|
||||
I_Error("3D GenerateTexture : too small");
|
||||
}
|
||||
else if (cv_voodoocompatibility.value)
|
||||
{
|
||||
if (originalwidth > 256 || originalheight > 256)
|
||||
{
|
||||
blockwidth = 256;
|
||||
while (originalwidth < blockwidth)
|
||||
blockwidth >>= 1;
|
||||
if (blockwidth < 1)
|
||||
I_Error("3D GenerateTexture : too small");
|
||||
|
||||
blockheight = 256;
|
||||
while (originalheight < blockheight)
|
||||
blockheight >>= 1;
|
||||
if (blockheight < 1)
|
||||
I_Error("3D GenerateTexture : too small");
|
||||
}
|
||||
else
|
||||
{
|
||||
//size up to nearest power of 2
|
||||
blockwidth = 1;
|
||||
while (blockwidth < originalwidth)
|
||||
blockwidth <<= 1;
|
||||
// scale down the original graphics to fit in 256
|
||||
if (blockwidth > 256)
|
||||
blockwidth = 256;
|
||||
//I_Error("3D GenerateTexture : too big");
|
||||
|
||||
//size up to nearest power of 2
|
||||
blockheight = 1;
|
||||
while (blockheight < originalheight)
|
||||
blockheight <<= 1;
|
||||
// scale down the original graphics to fit in 256
|
||||
if (blockheight > 256)
|
||||
blockheight = 255;
|
||||
//I_Error("3D GenerateTexture : too big");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef GLIDE_API_COMPATIBILITY
|
||||
|
@ -770,18 +733,6 @@ void HWR_MakePatch (const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipm
|
|||
newwidth = blockwidth;
|
||||
newheight = blockheight;
|
||||
}
|
||||
else if (cv_voodoocompatibility.value) // Only scales down textures that exceed 256x256.
|
||||
{
|
||||
// no rounddown, do not size up patches, so they don't look 'scaled'
|
||||
newwidth = min(grPatch->width, blockwidth);
|
||||
newheight = min(grPatch->height, blockheight);
|
||||
|
||||
if (newwidth > 256 || newheight > 256)
|
||||
{
|
||||
newwidth = blockwidth;
|
||||
newheight = blockheight;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// no rounddown, do not size up patches, so they don't look 'scaled'
|
||||
|
@ -825,10 +776,10 @@ static void FreeMipmapColormap(INT32 patchnum, void *patch)
|
|||
{
|
||||
GLPatch_t* const grpatch = patch;
|
||||
(void)patchnum; //unused
|
||||
while (grpatch->mipmap.nextcolormap)
|
||||
while (grpatch->mipmap->nextcolormap)
|
||||
{
|
||||
GLMipmap_t *grmip = grpatch->mipmap.nextcolormap;
|
||||
grpatch->mipmap.nextcolormap = grmip->nextcolormap;
|
||||
GLMipmap_t *grmip = grpatch->mipmap->nextcolormap;
|
||||
grpatch->mipmap->nextcolormap = grmip->nextcolormap;
|
||||
if (grmip->grInfo.data) Z_Free(grmip->grInfo.data);
|
||||
free(grmip);
|
||||
}
|
||||
|
@ -924,29 +875,6 @@ GLTexture_t *HWR_GetTexture(INT32 tex)
|
|||
return grtex;
|
||||
}
|
||||
|
||||
// HWR_RenderPlane and HWR_RenderPolyObjectPlane need this to get the flat dimensions from a patch.
|
||||
lumpnum_t gr_patchflat;
|
||||
|
||||
static void HWR_LoadPatchFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum)
|
||||
{
|
||||
UINT8 *flat;
|
||||
patch_t *patch = (patch_t *)W_CacheLumpNum(flatlumpnum, PU_STATIC);
|
||||
#ifndef NO_PNG_LUMPS
|
||||
size_t lumplength = W_LumpLength(flatlumpnum);
|
||||
|
||||
if (R_IsLumpPNG((UINT8 *)patch, lumplength))
|
||||
patch = R_PNGToPatch((UINT8 *)patch, lumplength, NULL, false);
|
||||
#endif
|
||||
|
||||
grMipmap->width = (UINT16)SHORT(patch->width);
|
||||
grMipmap->height = (UINT16)SHORT(patch->height);
|
||||
|
||||
flat = Z_Malloc(grMipmap->width * grMipmap->height, PU_HWRCACHE, &grMipmap->grInfo.data);
|
||||
memset(flat, TRANSPARENTPIXEL, grMipmap->width * grMipmap->height);
|
||||
|
||||
R_PatchToFlat(patch, flat);
|
||||
}
|
||||
|
||||
static void HWR_CacheFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum)
|
||||
{
|
||||
size_t size, pflatsize;
|
||||
|
@ -987,40 +915,15 @@ static void HWR_CacheFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum)
|
|||
break;
|
||||
}
|
||||
|
||||
if (R_CheckIfPatch(flatlumpnum))
|
||||
HWR_LoadPatchFlat(grMipmap, flatlumpnum);
|
||||
else
|
||||
{
|
||||
grMipmap->width = (UINT16)pflatsize;
|
||||
grMipmap->height = (UINT16)pflatsize;
|
||||
grMipmap->width = (UINT16)pflatsize;
|
||||
grMipmap->height = (UINT16)pflatsize;
|
||||
|
||||
// the flat raw data needn't be converted with palettized textures
|
||||
W_ReadLump(flatlumpnum, Z_Malloc(W_LumpLength(flatlumpnum),
|
||||
PU_HWRCACHE, &grMipmap->grInfo.data));
|
||||
}
|
||||
// the flat raw data needn't be converted with palettized textures
|
||||
W_ReadLump(flatlumpnum, Z_Malloc(W_LumpLength(flatlumpnum),
|
||||
PU_HWRCACHE, &grMipmap->grInfo.data));
|
||||
}
|
||||
|
||||
// Download a Doom 'flat' to the hardware cache and make it ready for use
|
||||
void HWR_GetFlat(lumpnum_t flatlumpnum)
|
||||
{
|
||||
GLMipmap_t *grmip;
|
||||
|
||||
grmip = &HWR_GetCachedGLPatch(flatlumpnum)->mipmap;
|
||||
|
||||
if (!grmip->downloaded && !grmip->grInfo.data)
|
||||
HWR_CacheFlat(grmip, flatlumpnum);
|
||||
|
||||
HWD.pfnSetTexture(grmip);
|
||||
|
||||
// The system-memory data can be purged now.
|
||||
Z_ChangeTag(grmip->grInfo.data, PU_HWRCACHE_UNLOCKED);
|
||||
|
||||
gr_patchflat = 0;
|
||||
if (R_CheckIfPatch(flatlumpnum))
|
||||
gr_patchflat = flatlumpnum;
|
||||
}
|
||||
|
||||
static void HWR_LoadTextureFlat(GLMipmap_t *grMipmap, INT32 texturenum)
|
||||
static void HWR_CacheTextureAsFlat(GLMipmap_t *grMipmap, INT32 texturenum)
|
||||
{
|
||||
UINT8 *flat;
|
||||
|
||||
|
@ -1042,24 +945,53 @@ static void HWR_LoadTextureFlat(GLMipmap_t *grMipmap, INT32 texturenum)
|
|||
R_TextureToFlat(texturenum, flat);
|
||||
}
|
||||
|
||||
void HWR_GetTextureFlat(INT32 texturenum)
|
||||
// Download a Doom 'flat' to the hardware cache and make it ready for use
|
||||
void HWR_LiterallyGetFlat(lumpnum_t flatlumpnum)
|
||||
{
|
||||
GLTexture_t *grtex;
|
||||
#ifdef PARANOIA
|
||||
if ((unsigned)texturenum >= gr_numtextures)
|
||||
I_Error("HWR_GetTextureFlat: texturenum >= numtextures\n");
|
||||
#endif
|
||||
if (texturenum == 0 || texturenum == -1)
|
||||
GLMipmap_t *grmip;
|
||||
if (flatlumpnum == LUMPERROR)
|
||||
return;
|
||||
grtex = &gr_textures2[texturenum];
|
||||
|
||||
if (!grtex->mipmap.grInfo.data && !grtex->mipmap.downloaded)
|
||||
HWR_LoadTextureFlat(&grtex->mipmap, texturenum);
|
||||
grmip = HWR_GetCachedGLPatch(flatlumpnum)->mipmap;
|
||||
if (!grmip->downloaded && !grmip->grInfo.data)
|
||||
HWR_CacheFlat(grmip, flatlumpnum);
|
||||
|
||||
HWD.pfnSetTexture(&grtex->mipmap);
|
||||
HWD.pfnSetTexture(grmip);
|
||||
|
||||
// The system-memory data can be purged now.
|
||||
Z_ChangeTag(grtex->mipmap.grInfo.data, PU_HWRCACHE_UNLOCKED);
|
||||
Z_ChangeTag(grmip->grInfo.data, PU_HWRCACHE_UNLOCKED);
|
||||
}
|
||||
|
||||
void HWR_GetLevelFlat(levelflat_t *levelflat)
|
||||
{
|
||||
// Who knows?
|
||||
if (levelflat == NULL)
|
||||
return;
|
||||
|
||||
if (levelflat->type == LEVELFLAT_FLAT)
|
||||
HWR_LiterallyGetFlat(levelflat->u.flat.lumpnum);
|
||||
else if (levelflat->type == LEVELFLAT_TEXTURE)
|
||||
{
|
||||
GLTexture_t *grtex;
|
||||
INT32 texturenum = levelflat->u.texture.num;
|
||||
#ifdef PARANOIA
|
||||
if ((unsigned)texturenum >= gr_numtextures)
|
||||
I_Error("HWR_GetLevelFlat: texturenum >= numtextures\n");
|
||||
#endif
|
||||
if (texturenum == 0 || texturenum == -1)
|
||||
return;
|
||||
grtex = &gr_textures2[texturenum];
|
||||
|
||||
if (!grtex->mipmap.grInfo.data && !grtex->mipmap.downloaded)
|
||||
HWR_CacheTextureAsFlat(&grtex->mipmap, texturenum);
|
||||
|
||||
HWD.pfnSetTexture(&grtex->mipmap);
|
||||
|
||||
// The system-memory data can be purged now.
|
||||
Z_ChangeTag(grtex->mipmap.grInfo.data, PU_HWRCACHE_UNLOCKED);
|
||||
}
|
||||
else // set no texture
|
||||
HWD.pfnSetTexture(NULL);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -1088,22 +1020,22 @@ static void HWR_LoadMappedPatch(GLMipmap_t *grmip, GLPatch_t *gpatch)
|
|||
void HWR_GetPatch(GLPatch_t *gpatch)
|
||||
{
|
||||
// is it in hardware cache
|
||||
if (!gpatch->mipmap.downloaded && !gpatch->mipmap.grInfo.data)
|
||||
if (!gpatch->mipmap->downloaded && !gpatch->mipmap->grInfo.data)
|
||||
{
|
||||
// load the software patch, PU_STATIC or the Z_Malloc for hardware patch will
|
||||
// flush the software patch before the conversion! oh yeah I suffered
|
||||
patch_t *ptr = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC);
|
||||
HWR_MakePatch(ptr, gpatch, &gpatch->mipmap, true);
|
||||
HWR_MakePatch(ptr, gpatch, gpatch->mipmap, true);
|
||||
|
||||
// this is inefficient.. but the hardware patch in heap is purgeable so it should
|
||||
// not fragment memory, and besides the REAL cache here is the hardware memory
|
||||
Z_Free(ptr);
|
||||
}
|
||||
|
||||
HWD.pfnSetTexture(&gpatch->mipmap);
|
||||
HWD.pfnSetTexture(gpatch->mipmap);
|
||||
|
||||
// The system-memory patch data can be purged now.
|
||||
Z_ChangeTag(gpatch->mipmap.grInfo.data, PU_HWRCACHE_UNLOCKED);
|
||||
Z_ChangeTag(gpatch->mipmap->grInfo.data, PU_HWRCACHE_UNLOCKED);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1123,7 +1055,7 @@ void HWR_GetMappedPatch(GLPatch_t *gpatch, const UINT8 *colormap)
|
|||
|
||||
// search for the mimmap
|
||||
// skip the first (no colormap translated)
|
||||
for (grmip = &gpatch->mipmap; grmip->nextcolormap; )
|
||||
for (grmip = gpatch->mipmap; grmip->nextcolormap; )
|
||||
{
|
||||
grmip = grmip->nextcolormap;
|
||||
if (grmip->colormap == colormap)
|
||||
|
@ -1153,7 +1085,7 @@ void HWR_UnlockCachedPatch(GLPatch_t *gpatch)
|
|||
if (!gpatch)
|
||||
return;
|
||||
|
||||
Z_ChangeTag(gpatch->mipmap.grInfo.data, PU_HWRCACHE_UNLOCKED);
|
||||
Z_ChangeTag(gpatch->mipmap->grInfo.data, PU_HWRCACHE_UNLOCKED);
|
||||
Z_ChangeTag(gpatch, PU_HWRPATCHINFO_UNLOCKED);
|
||||
}
|
||||
|
||||
|
@ -1241,7 +1173,7 @@ GLPatch_t *HWR_GetPic(lumpnum_t lumpnum)
|
|||
|
||||
grpatch = HWR_GetCachedGLPatch(lumpnum);
|
||||
|
||||
if (!grpatch->mipmap.downloaded && !grpatch->mipmap.grInfo.data)
|
||||
if (!grpatch->mipmap->downloaded && !grpatch->mipmap->grInfo.data)
|
||||
{
|
||||
pic_t *pic;
|
||||
UINT8 *block;
|
||||
|
@ -1257,19 +1189,19 @@ GLPatch_t *HWR_GetPic(lumpnum_t lumpnum)
|
|||
grpatch->topoffset = 0;
|
||||
|
||||
// find the good 3dfx size (boring spec)
|
||||
HWR_ResizeBlock (grpatch->width, grpatch->height, &grpatch->mipmap.grInfo);
|
||||
grpatch->mipmap.width = (UINT16)blockwidth;
|
||||
grpatch->mipmap.height = (UINT16)blockheight;
|
||||
HWR_ResizeBlock (grpatch->width, grpatch->height, &grpatch->mipmap->grInfo);
|
||||
grpatch->mipmap->width = (UINT16)blockwidth;
|
||||
grpatch->mipmap->height = (UINT16)blockheight;
|
||||
|
||||
if (pic->mode == PALETTE)
|
||||
grpatch->mipmap.grInfo.format = textureformat; // can be set by driver
|
||||
grpatch->mipmap->grInfo.format = textureformat; // can be set by driver
|
||||
else
|
||||
grpatch->mipmap.grInfo.format = picmode2GR[pic->mode];
|
||||
grpatch->mipmap->grInfo.format = picmode2GR[pic->mode];
|
||||
|
||||
Z_Free(grpatch->mipmap.grInfo.data);
|
||||
Z_Free(grpatch->mipmap->grInfo.data);
|
||||
|
||||
// allocate block
|
||||
block = MakeBlock(&grpatch->mipmap);
|
||||
block = MakeBlock(grpatch->mipmap);
|
||||
|
||||
// if rounddown, rounddown patches as well as textures
|
||||
if (cv_grrounddown.value)
|
||||
|
@ -1277,18 +1209,6 @@ GLPatch_t *HWR_GetPic(lumpnum_t lumpnum)
|
|||
newwidth = blockwidth;
|
||||
newheight = blockheight;
|
||||
}
|
||||
else if (cv_voodoocompatibility.value) // Only scales down textures that exceed 256x256.
|
||||
{
|
||||
// no rounddown, do not size up patches, so they don't look 'scaled'
|
||||
newwidth = min(SHORT(pic->width),blockwidth);
|
||||
newheight = min(SHORT(pic->height),blockheight);
|
||||
|
||||
if (newwidth > 256 || newheight > 256)
|
||||
{
|
||||
newwidth = blockwidth;
|
||||
newheight = blockheight;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// no rounddown, do not size up patches, so they don't look 'scaled'
|
||||
|
@ -1299,25 +1219,25 @@ GLPatch_t *HWR_GetPic(lumpnum_t lumpnum)
|
|||
|
||||
if (grpatch->width == blockwidth &&
|
||||
grpatch->height == blockheight &&
|
||||
format2bpp[grpatch->mipmap.grInfo.format] == format2bpp[picmode2GR[pic->mode]])
|
||||
format2bpp[grpatch->mipmap->grInfo.format] == format2bpp[picmode2GR[pic->mode]])
|
||||
{
|
||||
// no conversion needed
|
||||
M_Memcpy(grpatch->mipmap.grInfo.data, pic->data,len);
|
||||
M_Memcpy(grpatch->mipmap->grInfo.data, pic->data,len);
|
||||
}
|
||||
else
|
||||
HWR_DrawPicInCache(block, newwidth, newheight,
|
||||
blockwidth*format2bpp[grpatch->mipmap.grInfo.format],
|
||||
blockwidth*format2bpp[grpatch->mipmap->grInfo.format],
|
||||
pic,
|
||||
format2bpp[grpatch->mipmap.grInfo.format]);
|
||||
format2bpp[grpatch->mipmap->grInfo.format]);
|
||||
|
||||
Z_Unlock(pic);
|
||||
Z_ChangeTag(block, PU_HWRCACHE_UNLOCKED);
|
||||
|
||||
grpatch->mipmap.flags = 0;
|
||||
grpatch->mipmap->flags = 0;
|
||||
grpatch->max_s = (float)newwidth / (float)blockwidth;
|
||||
grpatch->max_t = (float)newheight / (float)blockheight;
|
||||
}
|
||||
HWD.pfnSetTexture(&grpatch->mipmap);
|
||||
HWD.pfnSetTexture(grpatch->mipmap);
|
||||
//CONS_Debug(DBG_RENDER, "picloaded at %x as texture %d\n",grpatch->mipmap.grInfo.data, grpatch->mipmap.downloaded);
|
||||
|
||||
return grpatch;
|
||||
|
@ -1333,6 +1253,7 @@ GLPatch_t *HWR_GetCachedGLPatchPwad(UINT16 wadnum, UINT16 lumpnum)
|
|||
grpatch = Z_Calloc(sizeof(GLPatch_t), PU_HWRPATCHINFO, NULL);
|
||||
grpatch->wadnum = wadnum;
|
||||
grpatch->lumpnum = lumpnum;
|
||||
grpatch->mipmap = Z_Calloc(sizeof(GLMipmap_t), PU_HWRPATCHINFO, NULL);
|
||||
M_AATreeSet(hwrcache, lumpnum, grpatch);
|
||||
}
|
||||
|
||||
|
@ -1436,7 +1357,7 @@ void HWR_GetFadeMask(lumpnum_t fademasklumpnum)
|
|||
{
|
||||
GLMipmap_t *grmip;
|
||||
|
||||
grmip = &HWR_GetCachedGLPatch(fademasklumpnum)->mipmap;
|
||||
grmip = HWR_GetCachedGLPatch(fademasklumpnum)->mipmap;
|
||||
|
||||
if (!grmip->downloaded && !grmip->grInfo.data)
|
||||
HWR_CacheFadeMask(grmip, fademasklumpnum);
|
||||
|
|
|
@ -77,8 +77,8 @@
|
|||
#include "r_opengl/r_opengl.h"
|
||||
|
||||
#ifdef HAVE_SPHEREFRUSTRUM
|
||||
static GLdouble viewMatrix[16];
|
||||
static GLdouble projMatrix[16];
|
||||
static GLfloat viewMatrix[16];
|
||||
static GLfloat projMatrix[16];
|
||||
float frustum[6][4];
|
||||
#endif
|
||||
|
||||
|
@ -380,8 +380,8 @@ void gld_FrustrumSetup(void)
|
|||
float t;
|
||||
float clip[16];
|
||||
|
||||
pglGetDoublev(GL_PROJECTION_MATRIX, projMatrix);
|
||||
pglGetDoublev(GL_MODELVIEW_MATRIX, viewMatrix);
|
||||
pglGeFloatv(GL_PROJECTION_MATRIX, projMatrix);
|
||||
pglGetFloatv(GL_MODELVIEW_MATRIX, viewMatrix);
|
||||
|
||||
clip[0] = CALCMATRIX(0, 0, 1, 4, 2, 8, 3, 12);
|
||||
clip[1] = CALCMATRIX(0, 1, 1, 5, 2, 9, 3, 13);
|
||||
|
|
|
@ -83,8 +83,8 @@ struct GLPatch_s
|
|||
float max_s,max_t;
|
||||
UINT16 wadnum; // the software patch lump num for when the hardware patch
|
||||
UINT16 lumpnum; // was flushed, and we need to re-create it
|
||||
GLMipmap_t mipmap;
|
||||
};
|
||||
GLMipmap_t *mipmap;
|
||||
} ATTRPACK;
|
||||
typedef struct GLPatch_s GLPatch_t;
|
||||
|
||||
#endif //_HWR_DATA_
|
||||
|
|
|
@ -95,14 +95,29 @@ typedef struct
|
|||
|
||||
//Hurdler: Transform (coords + angles)
|
||||
//BP: transform order : scale(rotation_x(rotation_y(translation(v))))
|
||||
|
||||
// Kart features
|
||||
//#define USE_FTRANSFORM_ANGLEZ
|
||||
//#define USE_FTRANSFORM_MIRROR
|
||||
|
||||
// Vanilla features
|
||||
#define USE_MODEL_NEXTFRAME
|
||||
|
||||
typedef struct
|
||||
{
|
||||
FLOAT x,y,z; // position
|
||||
#ifdef USE_FTRANSFORM_ANGLEZ
|
||||
FLOAT anglex,angley,anglez; // aimingangle / viewangle
|
||||
#else
|
||||
FLOAT anglex,angley; // aimingangle / viewangle
|
||||
#endif
|
||||
FLOAT scalex,scaley,scalez;
|
||||
FLOAT fovxangle, fovyangle;
|
||||
INT32 splitscreen;
|
||||
UINT8 splitscreen;
|
||||
boolean flip; // screenflip
|
||||
#ifdef USE_FTRANSFORM_MIRROR
|
||||
boolean mirror; // SRB2Kart: Encore Mode
|
||||
#endif
|
||||
} FTransform;
|
||||
|
||||
// Transformed vector, as passed to HWR API
|
||||
|
@ -145,7 +160,7 @@ enum EPolyFlags
|
|||
// When set, pass the color constant into the FSurfaceInfo -> FlatColor
|
||||
PF_NoTexture = 0x00002000, // Use the small white texture
|
||||
PF_Corona = 0x00004000, // Tell the rendrer we are drawing a corona
|
||||
PF_MD2 = 0x00008000, // Tell the rendrer we are drawing an MD2
|
||||
PF_Unused = 0x00008000, // Unused
|
||||
PF_RemoveYWrap = 0x00010000, // Force clamp texture on Y
|
||||
PF_ForceWrapX = 0x00020000, // Force repeat texture on X
|
||||
PF_ForceWrapY = 0x00040000, // Force repeat texture on Y
|
||||
|
@ -203,8 +218,6 @@ enum hwdsetspecialstate
|
|||
HWD_SET_FOG_COLOR,
|
||||
HWD_SET_FOG_DENSITY,
|
||||
HWD_SET_FOV,
|
||||
HWD_SET_POLYGON_SMOOTH,
|
||||
HWD_SET_PALETTECOLOR,
|
||||
HWD_SET_TEXTUREFILTERMODE,
|
||||
HWD_SET_TEXTUREANISOTROPICMODE,
|
||||
HWD_NUMSTATE
|
||||
|
|
|
@ -647,7 +647,7 @@ void HWR_DrawFlatFill (INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatlumpnum
|
|||
v[0].tow = v[1].tow = (float)((y & flatflag)/dflatsize);
|
||||
v[2].tow = v[3].tow = (float)(v[0].tow + h/dflatsize);
|
||||
|
||||
HWR_GetFlat(flatlumpnum);
|
||||
HWR_LiterallyGetFlat(flatlumpnum);
|
||||
|
||||
//Hurdler: Boris, the same comment as above... but maybe for pics
|
||||
// it not a problem since they don't have any transparent pixel
|
||||
|
|
|
@ -59,20 +59,18 @@ EXPORT void HWRAPI(ClearMipMapCache) (void);
|
|||
EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value);
|
||||
|
||||
//Hurdler: added for new development
|
||||
EXPORT void HWRAPI(DrawMD2) (INT32 *gl_cmd_buffer, md2_frame_t *frame, FTransform *pos, float scale);
|
||||
EXPORT void HWRAPI(DrawMD2i) (INT32 *gl_cmd_buffer, md2_frame_t *frame, INT32 duration, INT32 tics, md2_frame_t *nextframe, FTransform *pos, float scale, UINT8 flipped, UINT8 *color);
|
||||
EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 *color);
|
||||
EXPORT void HWRAPI(CreateModelVBOs) (model_t *model);
|
||||
EXPORT void HWRAPI(SetTransform) (FTransform *ptransform);
|
||||
EXPORT INT32 HWRAPI(GetTextureUsed) (void);
|
||||
EXPORT INT32 HWRAPI(GetRenderVersion) (void);
|
||||
|
||||
#ifdef SHUFFLE
|
||||
#define SCREENVERTS 10
|
||||
EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]);
|
||||
#endif
|
||||
EXPORT void HWRAPI(FlushScreenTextures) (void);
|
||||
EXPORT void HWRAPI(StartScreenWipe) (void);
|
||||
EXPORT void HWRAPI(EndScreenWipe) (void);
|
||||
EXPORT void HWRAPI(DoScreenWipe) (float alpha);
|
||||
EXPORT void HWRAPI(DoScreenWipe) (void);
|
||||
EXPORT void HWRAPI(DrawIntermissionBG) (void);
|
||||
EXPORT void HWRAPI(MakeScreenTexture) (void);
|
||||
EXPORT void HWRAPI(MakeScreenFinalTexture) (void);
|
||||
|
@ -98,8 +96,8 @@ struct hwdriver_s
|
|||
GClipRect pfnGClipRect;
|
||||
ClearMipMapCache pfnClearMipMapCache;
|
||||
SetSpecialState pfnSetSpecialState;//Hurdler: added for backward compatibility
|
||||
DrawMD2 pfnDrawMD2;
|
||||
DrawMD2i pfnDrawMD2i;
|
||||
DrawModel pfnDrawModel;
|
||||
CreateModelVBOs pfnCreateModelVBOs;
|
||||
SetTransform pfnSetTransform;
|
||||
GetTextureUsed pfnGetTextureUsed;
|
||||
GetRenderVersion pfnGetRenderVersion;
|
||||
|
@ -109,9 +107,7 @@ struct hwdriver_s
|
|||
#ifndef HAVE_SDL
|
||||
Shutdown pfnShutdown;
|
||||
#endif
|
||||
#ifdef SHUFFLE
|
||||
PostImgRedraw pfnPostImgRedraw;
|
||||
#endif
|
||||
FlushScreenTextures pfnFlushScreenTextures;
|
||||
StartScreenWipe pfnStartScreenWipe;
|
||||
EndScreenWipe pfnEndScreenWipe;
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "hw_defs.h"
|
||||
#include "hw_main.h"
|
||||
#include "../m_misc.h"
|
||||
#include "../p_setup.h"
|
||||
|
||||
// the original aspect ratio of Doom graphics isn't square
|
||||
#define ORIGINAL_ASPECT (320.0f/200.0f)
|
||||
|
@ -100,8 +101,8 @@ void HWR_InitTextureCache(void);
|
|||
void HWR_FreeTextureCache(void);
|
||||
void HWR_FreeExtraSubsectors(void);
|
||||
|
||||
void HWR_GetFlat(lumpnum_t flatlumpnum);
|
||||
void HWR_GetTextureFlat(INT32 texturenum);
|
||||
void HWR_GetLevelFlat(levelflat_t *levelflat);
|
||||
void HWR_LiterallyGetFlat(lumpnum_t flatlumpnum);
|
||||
GLTexture_t *HWR_GetTexture(INT32 tex);
|
||||
void HWR_GetPatch(GLPatch_t *gpatch);
|
||||
void HWR_GetMappedPatch(GLPatch_t *gpatch, const UINT8 *colormap);
|
||||
|
@ -115,8 +116,6 @@ void HWR_GetFadeMask(lumpnum_t fademasklumpnum);
|
|||
// --------
|
||||
// hw_draw.c
|
||||
// --------
|
||||
extern lumpnum_t gr_patchflat;
|
||||
|
||||
extern float gr_patch_scalex;
|
||||
extern float gr_patch_scaley;
|
||||
|
||||
|
|
|
@ -1205,7 +1205,8 @@ void HWR_DL_AddLight(gr_vissprite_t *spr, GLPatch_t *patch)
|
|||
dynlights->nb++;
|
||||
}
|
||||
|
||||
static GLPatch_t lightmappatch;
|
||||
static GLMipmap_t lightmappatchmipmap;
|
||||
static GLPatch_t lightmappatch = { .mipmap = &lightmappatchmipmap };
|
||||
|
||||
void HWR_InitLight(void)
|
||||
{
|
||||
|
@ -1215,7 +1216,7 @@ void HWR_InitLight(void)
|
|||
for (i = 0;i < NUMLIGHTS;i++)
|
||||
lspr[i].dynamic_sqrradius = lspr[i].dynamic_radius*lspr[i].dynamic_radius;
|
||||
|
||||
lightmappatch.mipmap.downloaded = false;
|
||||
lightmappatch.mipmap->downloaded = false;
|
||||
coronalumpnum = W_CheckNumForName("CORONA");
|
||||
}
|
||||
|
||||
|
@ -1226,10 +1227,10 @@ static void HWR_SetLight(void)
|
|||
{
|
||||
int i, j;
|
||||
|
||||
if (!lightmappatch.mipmap.downloaded && !lightmappatch.mipmap.grInfo.data)
|
||||
if (!lightmappatch.mipmap->downloaded && !lightmappatch.mipmap->grInfo.data)
|
||||
{
|
||||
|
||||
UINT16 *Data = Z_Malloc(129*128*sizeof (UINT16), PU_HWRCACHE, &lightmappatch.mipmap.grInfo.data);
|
||||
UINT16 *Data = Z_Malloc(129*128*sizeof (UINT16), PU_HWRCACHE, &lightmappatch.mipmap->grInfo.data);
|
||||
|
||||
for (i = 0; i < 128; i++)
|
||||
{
|
||||
|
@ -1242,23 +1243,23 @@ static void HWR_SetLight(void)
|
|||
Data[i*128+j] = 0;
|
||||
}
|
||||
}
|
||||
lightmappatch.mipmap.grInfo.format = GR_TEXFMT_ALPHA_INTENSITY_88;
|
||||
lightmappatch.mipmap->grInfo.format = GR_TEXFMT_ALPHA_INTENSITY_88;
|
||||
|
||||
lightmappatch.width = 128;
|
||||
lightmappatch.height = 128;
|
||||
lightmappatch.mipmap.width = 128;
|
||||
lightmappatch.mipmap.height = 128;
|
||||
lightmappatch.mipmap->width = 128;
|
||||
lightmappatch.mipmap->height = 128;
|
||||
#ifdef GLIDE_API_COMPATIBILITY
|
||||
lightmappatch.mipmap.grInfo.smallLodLog2 = GR_LOD_LOG2_128;
|
||||
lightmappatch.mipmap.grInfo.largeLodLog2 = GR_LOD_LOG2_128;
|
||||
lightmappatch.mipmap.grInfo.aspectRatioLog2 = GR_ASPECT_LOG2_1x1;
|
||||
lightmappatch.mipmap->grInfo.smallLodLog2 = GR_LOD_LOG2_128;
|
||||
lightmappatch.mipmap->grInfo.largeLodLog2 = GR_LOD_LOG2_128;
|
||||
lightmappatch.mipmap->grInfo.aspectRatioLog2 = GR_ASPECT_LOG2_1x1;
|
||||
#endif
|
||||
lightmappatch.mipmap.flags = 0; //TF_WRAPXY; // DEBUG: view the overdraw !
|
||||
lightmappatch.mipmap->flags = 0; //TF_WRAPXY; // DEBUG: view the overdraw !
|
||||
}
|
||||
HWD.pfnSetTexture(&lightmappatch.mipmap);
|
||||
HWD.pfnSetTexture(lightmappatch.mipmap);
|
||||
|
||||
// The system-memory data can be purged now.
|
||||
Z_ChangeTag(lightmappatch.mipmap.grInfo.data, PU_HWRCACHE_UNLOCKED);
|
||||
Z_ChangeTag(lightmappatch.mipmap->grInfo.data, PU_HWRCACHE_UNLOCKED);
|
||||
}
|
||||
|
||||
//**********************************************************
|
||||
|
|
|
@ -70,12 +70,12 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing);
|
|||
#endif
|
||||
|
||||
#ifdef SORTING
|
||||
void HWR_AddTransparentFloor(lumpnum_t lumpnum, INT32 texturenum, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight,
|
||||
void HWR_AddTransparentFloor(levelflat_t *levelflat, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight,
|
||||
INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, extracolormap_t *planecolormap);
|
||||
void HWR_AddTransparentPolyobjectFloor(lumpnum_t lumpnum, INT32 texturenum, polyobj_t *polysector, boolean isceiling, fixed_t fixedheight,
|
||||
void HWR_AddTransparentPolyobjectFloor(levelflat_t *levelflat, polyobj_t *polysector, boolean isceiling, fixed_t fixedheight,
|
||||
INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, extracolormap_t *planecolormap);
|
||||
#else
|
||||
static void HWR_Add3DWater(lumpnum_t lumpnum, extrasubsector_t *xsub, fixed_t fixedheight,
|
||||
static void HWR_Add3DWater(levelflat_t *levelflat, extrasubsector_t *xsub, fixed_t fixedheight,
|
||||
INT32 lightlevel, INT32 alpha, sector_t *FOFSector);
|
||||
static void HWR_Render3DWater(void);
|
||||
static void HWR_RenderTransparentWalls(void);
|
||||
|
@ -522,7 +522,7 @@ static UINT8 HWR_FogBlockAlpha(INT32 light, UINT32 color) // Let's see if this c
|
|||
// HWR_RenderPlane : Render a floor or ceiling convex polygon
|
||||
// -----------------+
|
||||
static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight,
|
||||
FBITFIELD PolyFlags, INT32 lightlevel, lumpnum_t lumpnum, INT32 texturenum, sector_t *FOFsector, UINT8 alpha, boolean fogplane, extracolormap_t *planecolormap)
|
||||
FBITFIELD PolyFlags, INT32 lightlevel, levelflat_t *levelflat, sector_t *FOFsector, UINT8 alpha, boolean fogplane, extracolormap_t *planecolormap)
|
||||
{
|
||||
polyvertex_t * pv;
|
||||
float height; //constant y for all points on the convex flat polygon
|
||||
|
@ -530,9 +530,9 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is
|
|||
INT32 nrPlaneVerts; //verts original define of convex flat polygon
|
||||
INT32 i;
|
||||
float flatxref,flatyref;
|
||||
float fflatwidth, fflatheight;
|
||||
INT32 flatflag;
|
||||
boolean texflat = true;
|
||||
float fflatwidth = 64.0f, fflatheight = 64.0f;
|
||||
INT32 flatflag = 63;
|
||||
boolean texflat = false;
|
||||
size_t len;
|
||||
float scrollx = 0.0f, scrolly = 0.0f;
|
||||
angle_t angle = 0;
|
||||
|
@ -541,7 +541,6 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is
|
|||
#ifdef ESLOPE
|
||||
pslope_t *slope = NULL;
|
||||
#endif
|
||||
patch_t *patch;
|
||||
|
||||
static FOutVector *planeVerts = NULL;
|
||||
static UINT16 numAllocedPlaneVerts = 0;
|
||||
|
@ -597,48 +596,49 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is
|
|||
Z_Malloc(numAllocedPlaneVerts * sizeof (FOutVector), PU_LEVEL, &planeVerts);
|
||||
}
|
||||
|
||||
len = W_LumpLength(lumpnum);
|
||||
|
||||
switch (len)
|
||||
// set texture for polygon
|
||||
if (levelflat != NULL)
|
||||
{
|
||||
case 4194304: // 2048x2048 lump
|
||||
fflatwidth = fflatheight = 2048.0f;
|
||||
break;
|
||||
case 1048576: // 1024x1024 lump
|
||||
fflatwidth = fflatheight = 1024.0f;
|
||||
break;
|
||||
case 262144:// 512x512 lump
|
||||
fflatwidth = fflatheight = 512.0f;
|
||||
break;
|
||||
case 65536: // 256x256 lump
|
||||
fflatwidth = fflatheight = 256.0f;
|
||||
break;
|
||||
case 16384: // 128x128 lump
|
||||
fflatwidth = fflatheight = 128.0f;
|
||||
break;
|
||||
case 1024: // 32x32 lump
|
||||
fflatwidth = fflatheight = 32.0f;
|
||||
break;
|
||||
default: // 64x64 lump
|
||||
fflatwidth = fflatheight = 64.0f;
|
||||
break;
|
||||
}
|
||||
if (levelflat->type == LEVELFLAT_TEXTURE)
|
||||
{
|
||||
fflatwidth = textures[levelflat->u.texture.num]->width;
|
||||
fflatheight = textures[levelflat->u.texture.num]->height;
|
||||
texflat = true;
|
||||
}
|
||||
else if (levelflat->type == LEVELFLAT_FLAT)
|
||||
{
|
||||
len = W_LumpLength(levelflat->u.flat.lumpnum);
|
||||
|
||||
flatflag = ((INT32)fflatwidth)-1;
|
||||
switch (len)
|
||||
{
|
||||
case 4194304: // 2048x2048 lump
|
||||
fflatwidth = fflatheight = 2048.0f;
|
||||
break;
|
||||
case 1048576: // 1024x1024 lump
|
||||
fflatwidth = fflatheight = 1024.0f;
|
||||
break;
|
||||
case 262144:// 512x512 lump
|
||||
fflatwidth = fflatheight = 512.0f;
|
||||
break;
|
||||
case 65536: // 256x256 lump
|
||||
fflatwidth = fflatheight = 256.0f;
|
||||
break;
|
||||
case 16384: // 128x128 lump
|
||||
fflatwidth = fflatheight = 128.0f;
|
||||
break;
|
||||
case 1024: // 32x32 lump
|
||||
fflatwidth = fflatheight = 32.0f;
|
||||
break;
|
||||
default: // 64x64 lump
|
||||
fflatwidth = fflatheight = 64.0f;
|
||||
break;
|
||||
}
|
||||
|
||||
if (texturenum != 0 && texturenum != -1)
|
||||
{
|
||||
fflatwidth = textures[texturenum]->width;
|
||||
fflatheight = textures[texturenum]->height;
|
||||
flatflag = ((INT32)fflatwidth)-1;
|
||||
}
|
||||
}
|
||||
else if (gr_patchflat && R_CheckIfPatch(gr_patchflat)) // Just in case?
|
||||
{
|
||||
patch = (patch_t *)W_CacheLumpNum(gr_patchflat, PU_STATIC);
|
||||
fflatwidth = SHORT(patch->width);
|
||||
fflatheight = SHORT(patch->height);
|
||||
}
|
||||
else
|
||||
texflat = false;
|
||||
else // set no texture
|
||||
HWD.pfnSetTexture(NULL);
|
||||
|
||||
// reference point for flat texture coord for each vertex around the polygon
|
||||
flatxref = (float)(((fixed_t)pv->x & (~flatflag)) / fflatwidth);
|
||||
|
@ -1972,7 +1972,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
|
|||
{
|
||||
// Single sided line... Deal only with the middletexture (if one exists)
|
||||
gr_midtexture = R_GetTextureNum(gr_sidedef->midtexture);
|
||||
if (gr_midtexture)
|
||||
if (gr_midtexture && gr_linedef->special != 41) // Ignore horizon line for OGL
|
||||
{
|
||||
{
|
||||
fixed_t texturevpeg;
|
||||
|
@ -3183,23 +3183,22 @@ static inline void HWR_AddPolyObjectSegs(void)
|
|||
|
||||
#ifdef POLYOBJECTS_PLANES
|
||||
static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, fixed_t fixedheight,
|
||||
FBITFIELD blendmode, UINT8 lightlevel, lumpnum_t lumpnum, INT32 texturenum, sector_t *FOFsector,
|
||||
FBITFIELD blendmode, UINT8 lightlevel, levelflat_t *levelflat, sector_t *FOFsector,
|
||||
UINT8 alpha, extracolormap_t *planecolormap)
|
||||
{
|
||||
float height; //constant y for all points on the convex flat polygon
|
||||
FOutVector *v3d;
|
||||
INT32 i;
|
||||
float flatxref,flatyref;
|
||||
float fflatwidth, fflatheight;
|
||||
INT32 flatflag;
|
||||
boolean texflat = true;
|
||||
float fflatwidth = 64.0f, fflatheight = 64.0f;
|
||||
INT32 flatflag = 63;
|
||||
boolean texflat = false;
|
||||
size_t len;
|
||||
float scrollx = 0.0f, scrolly = 0.0f;
|
||||
angle_t angle = 0;
|
||||
FSurfaceInfo Surf;
|
||||
fixed_t tempxsow, tempytow;
|
||||
size_t nrPlaneVerts;
|
||||
patch_t *patch;
|
||||
|
||||
static FOutVector *planeVerts = NULL;
|
||||
static UINT16 numAllocedPlaneVerts = 0;
|
||||
|
@ -3225,48 +3224,49 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling,
|
|||
Z_Malloc(numAllocedPlaneVerts * sizeof (FOutVector), PU_LEVEL, &planeVerts);
|
||||
}
|
||||
|
||||
len = W_LumpLength(lumpnum);
|
||||
|
||||
switch (len)
|
||||
// set texture for polygon
|
||||
if (levelflat != NULL)
|
||||
{
|
||||
case 4194304: // 2048x2048 lump
|
||||
fflatwidth = fflatheight = 2048.0f;
|
||||
break;
|
||||
case 1048576: // 1024x1024 lump
|
||||
fflatwidth = fflatheight = 1024.0f;
|
||||
break;
|
||||
case 262144:// 512x512 lump
|
||||
fflatwidth = fflatheight = 512.0f;
|
||||
break;
|
||||
case 65536: // 256x256 lump
|
||||
fflatwidth = fflatheight = 256.0f;
|
||||
break;
|
||||
case 16384: // 128x128 lump
|
||||
fflatwidth = fflatheight = 128.0f;
|
||||
break;
|
||||
case 1024: // 32x32 lump
|
||||
fflatwidth = fflatheight = 32.0f;
|
||||
break;
|
||||
default: // 64x64 lump
|
||||
fflatwidth = fflatheight = 64.0f;
|
||||
break;
|
||||
}
|
||||
if (levelflat->type == LEVELFLAT_TEXTURE)
|
||||
{
|
||||
fflatwidth = textures[levelflat->u.texture.num]->width;
|
||||
fflatheight = textures[levelflat->u.texture.num]->height;
|
||||
texflat = true;
|
||||
}
|
||||
else if (levelflat->type == LEVELFLAT_FLAT)
|
||||
{
|
||||
len = W_LumpLength(levelflat->u.flat.lumpnum);
|
||||
|
||||
flatflag = ((INT32)fflatwidth)-1;
|
||||
switch (len)
|
||||
{
|
||||
case 4194304: // 2048x2048 lump
|
||||
fflatwidth = fflatheight = 2048.0f;
|
||||
break;
|
||||
case 1048576: // 1024x1024 lump
|
||||
fflatwidth = fflatheight = 1024.0f;
|
||||
break;
|
||||
case 262144:// 512x512 lump
|
||||
fflatwidth = fflatheight = 512.0f;
|
||||
break;
|
||||
case 65536: // 256x256 lump
|
||||
fflatwidth = fflatheight = 256.0f;
|
||||
break;
|
||||
case 16384: // 128x128 lump
|
||||
fflatwidth = fflatheight = 128.0f;
|
||||
break;
|
||||
case 1024: // 32x32 lump
|
||||
fflatwidth = fflatheight = 32.0f;
|
||||
break;
|
||||
default: // 64x64 lump
|
||||
fflatwidth = fflatheight = 64.0f;
|
||||
break;
|
||||
}
|
||||
|
||||
if (texturenum != 0 && texturenum != -1)
|
||||
{
|
||||
fflatwidth = textures[texturenum]->width;
|
||||
fflatheight = textures[texturenum]->height;
|
||||
flatflag = ((INT32)fflatwidth)-1;
|
||||
}
|
||||
}
|
||||
else if (gr_patchflat && R_CheckIfPatch(gr_patchflat)) // Just in case?
|
||||
{
|
||||
patch = (patch_t *)W_CacheLumpNum(gr_patchflat, PU_STATIC);
|
||||
fflatwidth = SHORT(patch->width);
|
||||
fflatheight = SHORT(patch->height);
|
||||
}
|
||||
else
|
||||
texflat = false;
|
||||
else // set no texture
|
||||
HWD.pfnSetTexture(NULL);
|
||||
|
||||
// reference point for flat texture coord for each vertex around the polygon
|
||||
flatxref = (float)((polysector->origVerts[0].x & (~flatflag)) / fflatwidth);
|
||||
|
@ -3400,15 +3400,14 @@ static void HWR_AddPolyObjectPlanes(void)
|
|||
FBITFIELD blendmode;
|
||||
memset(&Surf, 0x00, sizeof(Surf));
|
||||
blendmode = HWR_TranstableToAlpha(po_ptrs[i]->translucency, &Surf);
|
||||
HWR_AddTransparentPolyobjectFloor(levelflats[polyobjsector->floorpic].lumpnum, levelflats[polyobjsector->floorpic].texturenum, po_ptrs[i], false, polyobjsector->floorheight,
|
||||
HWR_AddTransparentPolyobjectFloor(&levelflats[polyobjsector->floorpic], po_ptrs[i], false, polyobjsector->floorheight,
|
||||
(light == -1 ? gr_frontsector->lightlevel : *gr_frontsector->lightlist[light].lightlevel), Surf.FlatColor.s.alpha, polyobjsector, blendmode, (light == -1 ? gr_frontsector->extra_colormap : *gr_frontsector->lightlist[light].extra_colormap));
|
||||
}
|
||||
else
|
||||
{
|
||||
HWR_GetFlat(levelflats[polyobjsector->floorpic].lumpnum);
|
||||
HWR_GetTextureFlat(levelflats[polyobjsector->floorpic].texturenum);
|
||||
HWR_GetLevelFlat(&levelflats[polyobjsector->floorpic]);
|
||||
HWR_RenderPolyObjectPlane(po_ptrs[i], false, polyobjsector->floorheight, PF_Occlude,
|
||||
(light == -1 ? gr_frontsector->lightlevel : *gr_frontsector->lightlist[light].lightlevel), levelflats[polyobjsector->floorpic].lumpnum, levelflats[polyobjsector->floorpic].texturenum,
|
||||
(light == -1 ? gr_frontsector->lightlevel : *gr_frontsector->lightlist[light].lightlevel), &levelflats[polyobjsector->floorpic],
|
||||
polyobjsector, 255, (light == -1 ? gr_frontsector->extra_colormap : *gr_frontsector->lightlist[light].extra_colormap));
|
||||
}
|
||||
}
|
||||
|
@ -3424,15 +3423,14 @@ static void HWR_AddPolyObjectPlanes(void)
|
|||
FBITFIELD blendmode;
|
||||
memset(&Surf, 0x00, sizeof(Surf));
|
||||
blendmode = HWR_TranstableToAlpha(po_ptrs[i]->translucency, &Surf);
|
||||
HWR_AddTransparentPolyobjectFloor(levelflats[polyobjsector->ceilingpic].lumpnum, levelflats[polyobjsector->floorpic].texturenum, po_ptrs[i], true, polyobjsector->ceilingheight,
|
||||
HWR_AddTransparentPolyobjectFloor(&levelflats[polyobjsector->ceilingpic], po_ptrs[i], true, polyobjsector->ceilingheight,
|
||||
(light == -1 ? gr_frontsector->lightlevel : *gr_frontsector->lightlist[light].lightlevel), Surf.FlatColor.s.alpha, polyobjsector, blendmode, (light == -1 ? gr_frontsector->extra_colormap : *gr_frontsector->lightlist[light].extra_colormap));
|
||||
}
|
||||
else
|
||||
{
|
||||
HWR_GetFlat(levelflats[polyobjsector->ceilingpic].lumpnum);
|
||||
HWR_GetTextureFlat(levelflats[polyobjsector->ceilingpic].texturenum);
|
||||
HWR_GetLevelFlat(&levelflats[polyobjsector->ceilingpic]);
|
||||
HWR_RenderPolyObjectPlane(po_ptrs[i], true, polyobjsector->ceilingheight, PF_Occlude,
|
||||
(light == -1 ? gr_frontsector->lightlevel : *gr_frontsector->lightlist[light].lightlevel), levelflats[polyobjsector->floorpic].lumpnum, levelflats[polyobjsector->floorpic].texturenum,
|
||||
(light == -1 ? gr_frontsector->lightlevel : *gr_frontsector->lightlist[light].lightlevel), &levelflats[polyobjsector->floorpic],
|
||||
polyobjsector, 255, (light == -1 ? gr_frontsector->extra_colormap : *gr_frontsector->lightlist[light].extra_colormap));
|
||||
}
|
||||
}
|
||||
|
@ -3583,13 +3581,12 @@ static void HWR_Subsector(size_t num)
|
|||
{
|
||||
if (sub->validcount != validcount)
|
||||
{
|
||||
HWR_GetFlat(levelflats[gr_frontsector->floorpic].lumpnum);
|
||||
HWR_GetTextureFlat(levelflats[gr_frontsector->floorpic].texturenum);
|
||||
HWR_GetLevelFlat(&levelflats[gr_frontsector->floorpic]);
|
||||
HWR_RenderPlane(gr_frontsector, &extrasubsectors[num], false,
|
||||
// Hack to make things continue to work around slopes.
|
||||
locFloorHeight == cullFloorHeight ? locFloorHeight : gr_frontsector->floorheight,
|
||||
// We now return you to your regularly scheduled rendering.
|
||||
PF_Occlude, floorlightlevel, levelflats[gr_frontsector->floorpic].lumpnum, levelflats[gr_frontsector->floorpic].texturenum, NULL, 255, false, floorcolormap);
|
||||
PF_Occlude, floorlightlevel, &levelflats[gr_frontsector->floorpic], NULL, 255, false, floorcolormap);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -3606,13 +3603,12 @@ static void HWR_Subsector(size_t num)
|
|||
{
|
||||
if (sub->validcount != validcount)
|
||||
{
|
||||
HWR_GetFlat(levelflats[gr_frontsector->ceilingpic].lumpnum);
|
||||
HWR_GetTextureFlat(levelflats[gr_frontsector->ceilingpic].texturenum);
|
||||
HWR_GetLevelFlat(&levelflats[gr_frontsector->ceilingpic]);
|
||||
HWR_RenderPlane(NULL, &extrasubsectors[num], true,
|
||||
// Hack to make things continue to work around slopes.
|
||||
locCeilingHeight == cullCeilingHeight ? locCeilingHeight : gr_frontsector->ceilingheight,
|
||||
// We now return you to your regularly scheduled rendering.
|
||||
PF_Occlude, ceilinglightlevel, levelflats[gr_frontsector->ceilingpic].lumpnum, levelflats[gr_frontsector->ceilingpic].texturenum, NULL, 255, false, ceilingcolormap);
|
||||
PF_Occlude, ceilinglightlevel, &levelflats[gr_frontsector->ceilingpic], NULL, 255, false, ceilingcolormap);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -3671,7 +3667,7 @@ static void HWR_Subsector(size_t num)
|
|||
else
|
||||
alpha = HWR_FogBlockAlpha(*gr_frontsector->lightlist[light].lightlevel, NORMALFOG);
|
||||
|
||||
HWR_AddTransparentFloor(0, 0,
|
||||
HWR_AddTransparentFloor(NULL,
|
||||
&extrasubsectors[num],
|
||||
false,
|
||||
*rover->bottomheight,
|
||||
|
@ -3683,14 +3679,13 @@ static void HWR_Subsector(size_t num)
|
|||
{
|
||||
light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false);
|
||||
#ifndef SORTING
|
||||
HWR_Add3DWater(levelflats[*rover->bottompic].lumpnum,
|
||||
HWR_Add3DWater(&levelflats[*rover->bottompic],
|
||||
&extrasubsectors[num],
|
||||
*rover->bottomheight,
|
||||
*gr_frontsector->lightlist[light].lightlevel,
|
||||
rover->alpha-1, rover->master->frontsector);
|
||||
#else
|
||||
HWR_AddTransparentFloor(levelflats[*rover->bottompic].lumpnum,
|
||||
levelflats[*rover->bottompic].texturenum,
|
||||
HWR_AddTransparentFloor(&levelflats[*rover->bottompic],
|
||||
&extrasubsectors[num],
|
||||
false,
|
||||
*rover->bottomheight,
|
||||
|
@ -3701,10 +3696,9 @@ static void HWR_Subsector(size_t num)
|
|||
}
|
||||
else
|
||||
{
|
||||
HWR_GetFlat(levelflats[*rover->bottompic].lumpnum);
|
||||
HWR_GetTextureFlat(levelflats[*rover->bottompic].texturenum);
|
||||
HWR_GetLevelFlat(&levelflats[*rover->bottompic]);
|
||||
light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false);
|
||||
HWR_RenderPlane(NULL, &extrasubsectors[num], false, *rover->bottomheight, PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, levelflats[*rover->bottompic].lumpnum, levelflats[*rover->bottompic].texturenum,
|
||||
HWR_RenderPlane(NULL, &extrasubsectors[num], false, *rover->bottomheight, PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, &levelflats[*rover->bottompic],
|
||||
rover->master->frontsector, 255, false, *gr_frontsector->lightlist[light].extra_colormap);
|
||||
}
|
||||
}
|
||||
|
@ -3736,7 +3730,7 @@ static void HWR_Subsector(size_t num)
|
|||
else
|
||||
alpha = HWR_FogBlockAlpha(*gr_frontsector->lightlist[light].lightlevel, NORMALFOG);
|
||||
|
||||
HWR_AddTransparentFloor(0, 0,
|
||||
HWR_AddTransparentFloor(NULL,
|
||||
&extrasubsectors[num],
|
||||
true,
|
||||
*rover->topheight,
|
||||
|
@ -3748,14 +3742,13 @@ static void HWR_Subsector(size_t num)
|
|||
{
|
||||
light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false);
|
||||
#ifndef SORTING
|
||||
HWR_Add3DWater(levelflats[*rover->toppic].lumpnum,
|
||||
HWR_Add3DWater(&levelflats[*rover->toppic],
|
||||
&extrasubsectors[num],
|
||||
*rover->topheight,
|
||||
*gr_frontsector->lightlist[light].lightlevel,
|
||||
rover->alpha-1, rover->master->frontsector);
|
||||
#else
|
||||
HWR_AddTransparentFloor(levelflats[*rover->toppic].lumpnum,
|
||||
levelflats[*rover->bottompic].texturenum,
|
||||
HWR_AddTransparentFloor(&levelflats[*rover->toppic],
|
||||
&extrasubsectors[num],
|
||||
true,
|
||||
*rover->topheight,
|
||||
|
@ -3767,10 +3760,9 @@ static void HWR_Subsector(size_t num)
|
|||
}
|
||||
else
|
||||
{
|
||||
HWR_GetFlat(levelflats[*rover->toppic].lumpnum);
|
||||
HWR_GetTextureFlat(levelflats[*rover->toppic].texturenum);
|
||||
HWR_GetLevelFlat(&levelflats[*rover->toppic]);
|
||||
light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false);
|
||||
HWR_RenderPlane(NULL, &extrasubsectors[num], true, *rover->topheight, PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, levelflats[*rover->toppic].lumpnum, levelflats[*rover->toppic].texturenum,
|
||||
HWR_RenderPlane(NULL, &extrasubsectors[num], true, *rover->topheight, PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, &levelflats[*rover->toppic],
|
||||
rover->master->frontsector, 255, false, *gr_frontsector->lightlist[light].extra_colormap);
|
||||
}
|
||||
}
|
||||
|
@ -5098,8 +5090,7 @@ typedef struct
|
|||
boolean isceiling;
|
||||
fixed_t fixedheight;
|
||||
INT32 lightlevel;
|
||||
lumpnum_t lumpnum;
|
||||
INT32 texturenum;
|
||||
levelflat_t *levelflat;
|
||||
INT32 alpha;
|
||||
sector_t *FOFSector;
|
||||
FBITFIELD blend;
|
||||
|
@ -5117,8 +5108,7 @@ typedef struct
|
|||
boolean isceiling;
|
||||
fixed_t fixedheight;
|
||||
INT32 lightlevel;
|
||||
lumpnum_t lumpnum;
|
||||
INT32 texturenum;
|
||||
levelflat_t *levelflat;
|
||||
INT32 alpha;
|
||||
sector_t *FOFSector;
|
||||
FBITFIELD blend;
|
||||
|
@ -5149,7 +5139,7 @@ static INT32 drawcount = 0;
|
|||
#define MAX_TRANSPARENTFLOOR 512
|
||||
|
||||
// This will likely turn into a copy of HWR_Add3DWater and replace it.
|
||||
void HWR_AddTransparentFloor(lumpnum_t lumpnum, INT32 texturenum, extrasubsector_t *xsub, boolean isceiling,
|
||||
void HWR_AddTransparentFloor(levelflat_t *levelflat, extrasubsector_t *xsub, boolean isceiling,
|
||||
fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, extracolormap_t *planecolormap)
|
||||
{
|
||||
static size_t allocedplanes = 0;
|
||||
|
@ -5167,8 +5157,7 @@ void HWR_AddTransparentFloor(lumpnum_t lumpnum, INT32 texturenum, extrasubsector
|
|||
planeinfo[numplanes].isceiling = isceiling;
|
||||
planeinfo[numplanes].fixedheight = fixedheight;
|
||||
planeinfo[numplanes].lightlevel = lightlevel;
|
||||
planeinfo[numplanes].lumpnum = lumpnum;
|
||||
planeinfo[numplanes].texturenum = texturenum;
|
||||
planeinfo[numplanes].levelflat = levelflat;
|
||||
planeinfo[numplanes].xsub = xsub;
|
||||
planeinfo[numplanes].alpha = alpha;
|
||||
planeinfo[numplanes].FOFSector = FOFSector;
|
||||
|
@ -5182,7 +5171,7 @@ void HWR_AddTransparentFloor(lumpnum_t lumpnum, INT32 texturenum, extrasubsector
|
|||
|
||||
// Adding this for now until I can create extrasubsector info for polyobjects
|
||||
// When that happens it'll just be done through HWR_AddTransparentFloor and HWR_RenderPlane
|
||||
void HWR_AddTransparentPolyobjectFloor(lumpnum_t lumpnum, INT32 texturenum, polyobj_t *polysector, boolean isceiling,
|
||||
void HWR_AddTransparentPolyobjectFloor(levelflat_t *levelflat, polyobj_t *polysector, boolean isceiling,
|
||||
fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, extracolormap_t *planecolormap)
|
||||
{
|
||||
static size_t allocedpolyplanes = 0;
|
||||
|
@ -5200,8 +5189,7 @@ void HWR_AddTransparentPolyobjectFloor(lumpnum_t lumpnum, INT32 texturenum, poly
|
|||
polyplaneinfo[numpolyplanes].isceiling = isceiling;
|
||||
polyplaneinfo[numpolyplanes].fixedheight = fixedheight;
|
||||
polyplaneinfo[numpolyplanes].lightlevel = lightlevel;
|
||||
polyplaneinfo[numpolyplanes].lumpnum = lumpnum;
|
||||
polyplaneinfo[numpolyplanes].texturenum = texturenum;
|
||||
polyplaneinfo[numpolyplanes].levelflat = levelflat;
|
||||
polyplaneinfo[numpolyplanes].polysector = polysector;
|
||||
polyplaneinfo[numpolyplanes].alpha = alpha;
|
||||
polyplaneinfo[numpolyplanes].FOFSector = FOFSector;
|
||||
|
@ -5363,12 +5351,9 @@ static void HWR_CreateDrawNodes(void)
|
|||
gr_frontsector = NULL;
|
||||
|
||||
if (!(sortnode[sortindex[i]].plane->blend & PF_NoTexture))
|
||||
{
|
||||
HWR_GetFlat(sortnode[sortindex[i]].plane->lumpnum);
|
||||
HWR_GetTextureFlat(sortnode[sortindex[i]].plane->texturenum);
|
||||
}
|
||||
HWR_GetLevelFlat(sortnode[sortindex[i]].plane->levelflat);
|
||||
HWR_RenderPlane(NULL, sortnode[sortindex[i]].plane->xsub, sortnode[sortindex[i]].plane->isceiling, sortnode[sortindex[i]].plane->fixedheight, sortnode[sortindex[i]].plane->blend, sortnode[sortindex[i]].plane->lightlevel,
|
||||
sortnode[sortindex[i]].plane->lumpnum, sortnode[sortindex[i]].plane->texturenum, sortnode[sortindex[i]].plane->FOFSector, sortnode[sortindex[i]].plane->alpha, sortnode[sortindex[i]].plane->fogplane, sortnode[sortindex[i]].plane->planecolormap);
|
||||
sortnode[sortindex[i]].plane->levelflat, sortnode[sortindex[i]].plane->FOFSector, sortnode[sortindex[i]].plane->alpha, sortnode[sortindex[i]].plane->fogplane, sortnode[sortindex[i]].plane->planecolormap);
|
||||
}
|
||||
else if (sortnode[sortindex[i]].polyplane)
|
||||
{
|
||||
|
@ -5376,12 +5361,9 @@ static void HWR_CreateDrawNodes(void)
|
|||
gr_frontsector = NULL;
|
||||
|
||||
if (!(sortnode[sortindex[i]].polyplane->blend & PF_NoTexture))
|
||||
{
|
||||
HWR_GetFlat(sortnode[sortindex[i]].polyplane->lumpnum);
|
||||
HWR_GetTextureFlat(sortnode[sortindex[i]].polyplane->texturenum);
|
||||
}
|
||||
HWR_GetLevelFlat(sortnode[sortindex[i]].polyplane->levelflat);
|
||||
HWR_RenderPolyObjectPlane(sortnode[sortindex[i]].polyplane->polysector, sortnode[sortindex[i]].polyplane->isceiling, sortnode[sortindex[i]].polyplane->fixedheight, sortnode[sortindex[i]].polyplane->blend, sortnode[sortindex[i]].polyplane->lightlevel,
|
||||
sortnode[sortindex[i]].polyplane->lumpnum, sortnode[sortindex[i]].polyplane->texturenum, sortnode[sortindex[i]].polyplane->FOFSector, sortnode[sortindex[i]].polyplane->alpha, sortnode[sortindex[i]].polyplane->planecolormap);
|
||||
sortnode[sortindex[i]].polyplane->levelflat, sortnode[sortindex[i]].polyplane->FOFSector, sortnode[sortindex[i]].polyplane->alpha, sortnode[sortindex[i]].polyplane->planecolormap);
|
||||
}
|
||||
else if (sortnode[sortindex[i]].wall)
|
||||
{
|
||||
|
@ -5426,17 +5408,17 @@ static void HWR_DrawSprites(void)
|
|||
#endif
|
||||
if (spr->mobj && spr->mobj->skin && spr->mobj->sprite == SPR_PLAY)
|
||||
{
|
||||
if (!cv_grmd2.value || md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound || md2_playermodels[(skin_t*)spr->mobj->skin-skins].scale < 0.0f)
|
||||
if (!cv_grmodels.value || md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound || md2_playermodels[(skin_t*)spr->mobj->skin-skins].scale < 0.0f)
|
||||
HWR_DrawSprite(spr);
|
||||
else
|
||||
HWR_DrawMD2(spr);
|
||||
HWR_DrawModel(spr);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!cv_grmd2.value || md2_models[spr->mobj->sprite].notfound || md2_models[spr->mobj->sprite].scale < 0.0f)
|
||||
if (!cv_grmodels.value || md2_models[spr->mobj->sprite].notfound || md2_models[spr->mobj->sprite].scale < 0.0f)
|
||||
HWR_DrawSprite(spr);
|
||||
else
|
||||
HWR_DrawMD2(spr);
|
||||
HWR_DrawModel(spr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5564,7 +5546,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
tz = (tr_x * gr_viewcos) + (tr_y * gr_viewsin);
|
||||
|
||||
// thing is behind view plane?
|
||||
if (tz < ZCLIP_PLANE && !papersprite && (!cv_grmd2.value || md2_models[thing->sprite].notfound == true)) //Yellow: Only MD2's dont disappear
|
||||
if (tz < ZCLIP_PLANE && !papersprite && (!cv_grmodels.value || md2_models[thing->sprite].notfound == true)) //Yellow: Only MD2's dont disappear
|
||||
return;
|
||||
|
||||
// The above can stay as it works for cutting sprites that are too close
|
||||
|
@ -5755,6 +5737,15 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
// New colormap stuff for skins Tails 06-07-2002
|
||||
if (thing->colorized)
|
||||
vis->colormap = R_GetTranslationColormap(TC_RAINBOW, thing->color, GTC_CACHE);
|
||||
else if (thing->player && thing->player->dashmode >= DASHMODE_THRESHOLD
|
||||
&& (thing->player->charflags & SF_DASHMODE)
|
||||
&& ((leveltime/2) & 1))
|
||||
{
|
||||
if (thing->player->charflags & SF_MACHINE)
|
||||
vis->colormap = R_GetTranslationColormap(TC_DASHMODE, 0, GTC_CACHE);
|
||||
else
|
||||
vis->colormap = R_GetTranslationColormap(TC_RAINBOW, thing->color, GTC_CACHE);
|
||||
}
|
||||
else if (thing->skin && thing->sprite == SPR_PLAY) // This thing is a player!
|
||||
{
|
||||
size_t skinnum = (skin_t*)thing->skin-skins;
|
||||
|
@ -6307,6 +6298,7 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player)
|
|||
|
||||
// note: sets viewangle, viewx, viewy, viewz
|
||||
R_SetupFrame(player);
|
||||
framecount++; // timedemo
|
||||
|
||||
// copy view cam position for local use
|
||||
dup_viewx = viewx;
|
||||
|
@ -6603,13 +6595,13 @@ void HWR_Startup(void)
|
|||
// do this once
|
||||
if (!startupdone)
|
||||
{
|
||||
CONS_Printf("HWR_Startup()\n");
|
||||
CONS_Printf("HWR_Startup()...\n");
|
||||
HWR_InitPolyPool();
|
||||
// add console cmds & vars
|
||||
HWR_AddEngineCommands();
|
||||
HWR_InitTextureCache();
|
||||
|
||||
HWR_InitMD2();
|
||||
HWR_InitModels();
|
||||
|
||||
#ifdef ALAM_LIGHTING
|
||||
HWR_InitLight();
|
||||
|
@ -6660,10 +6652,11 @@ void transform(float *cx, float *cy, float *cz)
|
|||
|
||||
|
||||
//Hurdler: 3D Water stuff
|
||||
#ifndef SORTING
|
||||
|
||||
#define MAX_3DWATER 512
|
||||
|
||||
#ifndef SORTING
|
||||
static void HWR_Add3DWater(lumpnum_t lumpnum, extrasubsector_t *xsub,
|
||||
static void HWR_Add3DWater(levelflat_t *levelflat, extrasubsector_t *xsub,
|
||||
fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector)
|
||||
{
|
||||
static size_t allocedplanes = 0;
|
||||
|
@ -6679,17 +6672,15 @@ static void HWR_Add3DWater(lumpnum_t lumpnum, extrasubsector_t *xsub,
|
|||
}
|
||||
planeinfo[numfloors].fixedheight = fixedheight;
|
||||
planeinfo[numfloors].lightlevel = lightlevel;
|
||||
planeinfo[numfloors].lumpnum = lumpnum;
|
||||
planeinfo[numfloors].levelflat = levelflat;
|
||||
planeinfo[numfloors].xsub = xsub;
|
||||
planeinfo[numfloors].alpha = alpha;
|
||||
planeinfo[numfloors].FOFSector = FOFSector;
|
||||
numfloors++;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define DIST_PLANE(i) ABS(planeinfo[(i)].fixedheight-dup_viewz)
|
||||
|
||||
#if 0
|
||||
static void HWR_QuickSortPlane(INT32 start, INT32 finish)
|
||||
{
|
||||
INT32 left = start;
|
||||
|
@ -6719,9 +6710,7 @@ static void HWR_QuickSortPlane(INT32 start, INT32 finish)
|
|||
if (start < right) HWR_QuickSortPlane(start, right);
|
||||
if (left < finish) HWR_QuickSortPlane(left, finish);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef SORTING
|
||||
static void HWR_Render3DWater(void)
|
||||
{
|
||||
size_t i;
|
||||
|
@ -6752,8 +6741,8 @@ static void HWR_Render3DWater(void)
|
|||
gr_frontsector = NULL; //Hurdler: gr_fronsector is no longer valid
|
||||
for (i = 0; i < numfloors; i++)
|
||||
{
|
||||
HWR_GetFlat(planeinfo[i].lumpnum);
|
||||
HWR_RenderPlane(NULL, planeinfo[i].xsub, planeinfo[i].isceiling, planeinfo[i].fixedheight, PF_Translucent, planeinfo[i].lightlevel, planeinfo[i].lumpnum,
|
||||
HWR_GetLevelFlat(planeinfo[i].levelflat);
|
||||
HWR_RenderPlane(NULL, planeinfo[i].xsub, planeinfo[i].isceiling, planeinfo[i].fixedheight, PF_Translucent, planeinfo[i].lightlevel, planeinfo[i].levelflat,
|
||||
planeinfo[i].FOFSector, planeinfo[i].alpha, planeinfo[i].fogplane, planeinfo[i].planecolormap);
|
||||
}
|
||||
numfloors = 0;
|
||||
|
@ -6786,6 +6775,7 @@ static void HWR_AddTransparentWall(wallVert3D *wallVerts, FSurfaceInfo *pSurf, I
|
|||
wallinfo[numwalls].wallcolormap = wallcolormap;
|
||||
numwalls++;
|
||||
}
|
||||
|
||||
#ifndef SORTING
|
||||
static void HWR_RenderTransparentWalls(void)
|
||||
{
|
||||
|
@ -6818,6 +6808,7 @@ static void HWR_RenderTransparentWalls(void)
|
|||
numwalls = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void HWR_RenderWall(wallVert3D *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blend, boolean fogwall, INT32 lightlevel, extracolormap_t *wallcolormap)
|
||||
{
|
||||
FOutVector trVerts[4];
|
||||
|
@ -6876,11 +6867,6 @@ static void HWR_RenderWall(wallVert3D *wallVerts, FSurfaceInfo *pSurf, FBITFIE
|
|||
#endif
|
||||
}
|
||||
|
||||
void HWR_SetPaletteColor(INT32 palcolor)
|
||||
{
|
||||
HWD.pfnSetSpecialState(HWD_SET_PALETTECOLOR, palcolor);
|
||||
}
|
||||
|
||||
INT32 HWR_GetTextureUsed(void)
|
||||
{
|
||||
return HWD.pfnGetTextureUsed();
|
||||
|
@ -6927,7 +6913,6 @@ void HWR_DoPostProcessor(player_t *player)
|
|||
if (splitscreen) // Not supported in splitscreen - someone want to add support?
|
||||
return;
|
||||
|
||||
#ifdef SHUFFLE
|
||||
// Drunken vision! WooOOooo~
|
||||
if (*type == postimg_water || *type == postimg_heat)
|
||||
{
|
||||
|
@ -6970,7 +6955,6 @@ void HWR_DoPostProcessor(player_t *player)
|
|||
HWD.pfnMakeScreenTexture();
|
||||
}
|
||||
// Flipping of the screen isn't done here anymore
|
||||
#endif // SHUFFLE
|
||||
}
|
||||
|
||||
void HWR_StartScreenWipe(void)
|
||||
|
@ -7017,7 +7001,7 @@ void HWR_DoWipe(UINT8 wipenum, UINT8 scrnnum)
|
|||
|
||||
HWR_GetFadeMask(lumpnum);
|
||||
|
||||
HWD.pfnDoScreenWipe(HWRWipeCounter); // Still send in wipecounter since old stuff might not support multitexturing
|
||||
HWD.pfnDoScreenWipe();
|
||||
|
||||
HWRWipeCounter += 0.05f; // increase opacity of end screen
|
||||
|
||||
|
|
|
@ -60,7 +60,6 @@ void HWR_AddCommands(void);
|
|||
void HWR_CorrectSWTricks(void);
|
||||
void transform(float *cx, float *cy, float *cz);
|
||||
FBITFIELD HWR_TranstableToAlpha(INT32 transtablenum, FSurfaceInfo *pSurf);
|
||||
void HWR_SetPaletteColor(INT32 palcolor);
|
||||
INT32 HWR_GetTextureUsed(void);
|
||||
void HWR_DoPostProcessor(player_t *player);
|
||||
void HWR_StartScreenWipe(void);
|
||||
|
@ -83,7 +82,8 @@ extern consvar_t cv_grcoronas;
|
|||
extern consvar_t cv_grcoronasize;
|
||||
#endif
|
||||
extern consvar_t cv_grfov;
|
||||
extern consvar_t cv_grmd2;
|
||||
extern consvar_t cv_grmodels;
|
||||
extern consvar_t cv_grmodelinterpolation;
|
||||
extern consvar_t cv_grfog;
|
||||
extern consvar_t cv_grfogcolor;
|
||||
extern consvar_t cv_grfogdensity;
|
||||
|
@ -94,7 +94,6 @@ extern consvar_t cv_grgammablue;
|
|||
extern consvar_t cv_grfiltermode;
|
||||
extern consvar_t cv_granisotropicmode;
|
||||
extern consvar_t cv_grcorrecttricks;
|
||||
extern consvar_t cv_voodoocompatibility;
|
||||
extern consvar_t cv_grfovchange;
|
||||
extern consvar_t cv_grsolvetjoin;
|
||||
extern consvar_t cv_grspritebillboarding;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -22,104 +22,7 @@
|
|||
#define _HW_MD2_H_
|
||||
|
||||
#include "hw_glob.h"
|
||||
#include "../info.h"
|
||||
|
||||
// magic number "IDP2" or 844121161
|
||||
#define MD2_IDENT (INT32)(('2' << 24) + ('P' << 16) + ('D' << 8) + 'I')
|
||||
// model version
|
||||
#define MD2_VERSION 8
|
||||
|
||||
// magic number "IDP2" or 844121161
|
||||
#define MD2_IDENT (INT32)(('2' << 24) + ('P' << 16) + ('D' << 8) + 'I')
|
||||
// model version
|
||||
#define MD2_VERSION 8
|
||||
|
||||
#define MD2_MAX_TRIANGLES 8192
|
||||
#define MD2_MAX_VERTICES 4096
|
||||
#define MD2_MAX_TEXCOORDS 4096
|
||||
#define MD2_MAX_FRAMES 512
|
||||
#define MD2_MAX_SKINS 32
|
||||
#define MD2_MAX_FRAMESIZE (MD2_MAX_VERTICES * 4 + 128)
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma pack(1)
|
||||
#endif
|
||||
typedef struct
|
||||
{
|
||||
UINT32 magic;
|
||||
UINT32 version;
|
||||
UINT32 skinWidth;
|
||||
UINT32 skinHeight;
|
||||
UINT32 frameSize;
|
||||
UINT32 numSkins;
|
||||
UINT32 numVertices;
|
||||
UINT32 numTexCoords;
|
||||
UINT32 numTriangles;
|
||||
UINT32 numGlCommands;
|
||||
UINT32 numFrames;
|
||||
UINT32 offsetSkins;
|
||||
UINT32 offsetTexCoords;
|
||||
UINT32 offsetTriangles;
|
||||
UINT32 offsetFrames;
|
||||
UINT32 offsetGlCommands;
|
||||
UINT32 offsetEnd;
|
||||
} ATTRPACK md2_header_t; //NOTE: each of md2_header's members are 4 unsigned bytes
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT8 vertex[3];
|
||||
UINT8 lightNormalIndex;
|
||||
} ATTRPACK md2_alias_triangleVertex_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float vertex[3];
|
||||
float normal[3];
|
||||
} ATTRPACK md2_triangleVertex_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
INT16 vertexIndices[3];
|
||||
INT16 textureIndices[3];
|
||||
} ATTRPACK md2_triangle_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
INT16 s, t;
|
||||
} ATTRPACK md2_textureCoordinate_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float scale[3];
|
||||
float translate[3];
|
||||
char name[16];
|
||||
md2_alias_triangleVertex_t alias_vertices[1];
|
||||
} ATTRPACK md2_alias_frame_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char name[16];
|
||||
md2_triangleVertex_t *vertices;
|
||||
} ATTRPACK md2_frame_t;
|
||||
|
||||
typedef char md2_skin_t[64];
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float s, t;
|
||||
INT32 vertexIndex;
|
||||
} ATTRPACK md2_glCommandVertex_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
md2_header_t header;
|
||||
md2_skin_t *skins;
|
||||
md2_textureCoordinate_t *texCoords;
|
||||
md2_triangle_t *triangles;
|
||||
md2_frame_t *frames;
|
||||
size_t *spr2frames; // size_t spr2frames[2*NUMPLAYERSPRITES][2];
|
||||
INT32 *glCommandBuffer;
|
||||
} ATTRPACK md2_model_t;
|
||||
#include "hw_model.h"
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma pack()
|
||||
|
@ -130,7 +33,7 @@ typedef struct
|
|||
char filename[32];
|
||||
float scale;
|
||||
float offset;
|
||||
md2_model_t *model;
|
||||
model_t *model;
|
||||
void *grpatch;
|
||||
void *blendgrpatch;
|
||||
boolean notfound;
|
||||
|
@ -141,9 +44,9 @@ typedef struct
|
|||
extern md2_t md2_models[NUMSPRITES];
|
||||
extern md2_t md2_playermodels[MAXSKINS];
|
||||
|
||||
void HWR_InitMD2(void);
|
||||
void HWR_DrawMD2(gr_vissprite_t *spr);
|
||||
void HWR_AddPlayerMD2(INT32 skin);
|
||||
void HWR_AddSpriteMD2(size_t spritenum);
|
||||
void HWR_InitModels(void);
|
||||
void HWR_DrawModel(gr_vissprite_t *spr);
|
||||
void HWR_AddPlayerModel(INT32 skin);
|
||||
void HWR_AddSpriteModel(size_t spritenum);
|
||||
|
||||
#endif // _HW_MD2_H_
|
||||
|
|
576
src/hardware/hw_md2load.c
Normal file
576
src/hardware/hw_md2load.c
Normal file
|
@ -0,0 +1,576 @@
|
|||
/*
|
||||
From the 'Wizard2' engine by Spaddlewit Inc. ( http://www.spaddlewit.com )
|
||||
An experimental work-in-progress.
|
||||
|
||||
Donated to Sonic Team Junior and adapted to work with
|
||||
Sonic Robo Blast 2. The license of this code matches whatever
|
||||
the licensing is for Sonic Robo Blast 2.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "../doomdef.h"
|
||||
#include "hw_md2load.h"
|
||||
#include "hw_model.h"
|
||||
#include "../z_zone.h"
|
||||
|
||||
#define NUMVERTEXNORMALS 162
|
||||
|
||||
// Quake 2 normals are indexed. Use avertexnormals[normalindex][x/y/z] and
|
||||
// you'll have your normals.
|
||||
float avertexnormals[NUMVERTEXNORMALS][3] = {
|
||||
{-0.525731f, 0.000000f, 0.850651f},
|
||||
{-0.442863f, 0.238856f, 0.864188f},
|
||||
{-0.295242f, 0.000000f, 0.955423f},
|
||||
{-0.309017f, 0.500000f, 0.809017f},
|
||||
{-0.162460f, 0.262866f, 0.951056f},
|
||||
{0.000000f, 0.000000f, 1.000000f},
|
||||
{0.000000f, 0.850651f, 0.525731f},
|
||||
{-0.147621f, 0.716567f, 0.681718f},
|
||||
{0.147621f, 0.716567f, 0.681718f},
|
||||
{0.000000f, 0.525731f, 0.850651f},
|
||||
{0.309017f, 0.500000f, 0.809017f},
|
||||
{0.525731f, 0.000000f, 0.850651f},
|
||||
{0.295242f, 0.000000f, 0.955423f},
|
||||
{0.442863f, 0.238856f, 0.864188f},
|
||||
{0.162460f, 0.262866f, 0.951056f},
|
||||
{-0.681718f, 0.147621f, 0.716567f},
|
||||
{-0.809017f, 0.309017f, 0.500000f},
|
||||
{-0.587785f, 0.425325f, 0.688191f},
|
||||
{-0.850651f, 0.525731f, 0.000000f},
|
||||
{-0.864188f, 0.442863f, 0.238856f},
|
||||
{-0.716567f, 0.681718f, 0.147621f},
|
||||
{-0.688191f, 0.587785f, 0.425325f},
|
||||
{-0.500000f, 0.809017f, 0.309017f},
|
||||
{-0.238856f, 0.864188f, 0.442863f},
|
||||
{-0.425325f, 0.688191f, 0.587785f},
|
||||
{-0.716567f, 0.681718f, -0.147621f},
|
||||
{-0.500000f, 0.809017f, -0.309017f},
|
||||
{-0.525731f, 0.850651f, 0.000000f},
|
||||
{0.000000f, 0.850651f, -0.525731f},
|
||||
{-0.238856f, 0.864188f, -0.442863f},
|
||||
{0.000000f, 0.955423f, -0.295242f},
|
||||
{-0.262866f, 0.951056f, -0.162460f},
|
||||
{0.000000f, 1.000000f, 0.000000f},
|
||||
{0.000000f, 0.955423f, 0.295242f},
|
||||
{-0.262866f, 0.951056f, 0.162460f},
|
||||
{0.238856f, 0.864188f, 0.442863f},
|
||||
{0.262866f, 0.951056f, 0.162460f},
|
||||
{0.500000f, 0.809017f, 0.309017f},
|
||||
{0.238856f, 0.864188f, -0.442863f},
|
||||
{0.262866f, 0.951056f, -0.162460f},
|
||||
{0.500000f, 0.809017f, -0.309017f},
|
||||
{0.850651f, 0.525731f, 0.000000f},
|
||||
{0.716567f, 0.681718f, 0.147621f},
|
||||
{0.716567f, 0.681718f, -0.147621f},
|
||||
{0.525731f, 0.850651f, 0.000000f},
|
||||
{0.425325f, 0.688191f, 0.587785f},
|
||||
{0.864188f, 0.442863f, 0.238856f},
|
||||
{0.688191f, 0.587785f, 0.425325f},
|
||||
{0.809017f, 0.309017f, 0.500000f},
|
||||
{0.681718f, 0.147621f, 0.716567f},
|
||||
{0.587785f, 0.425325f, 0.688191f},
|
||||
{0.955423f, 0.295242f, 0.000000f},
|
||||
{1.000000f, 0.000000f, 0.000000f},
|
||||
{0.951056f, 0.162460f, 0.262866f},
|
||||
{0.850651f, -0.525731f, 0.000000f},
|
||||
{0.955423f, -0.295242f, 0.000000f},
|
||||
{0.864188f, -0.442863f, 0.238856f},
|
||||
{0.951056f, -0.162460f, 0.262866f},
|
||||
{0.809017f, -0.309017f, 0.500000f},
|
||||
{0.681718f, -0.147621f, 0.716567f},
|
||||
{0.850651f, 0.000000f, 0.525731f},
|
||||
{0.864188f, 0.442863f, -0.238856f},
|
||||
{0.809017f, 0.309017f, -0.500000f},
|
||||
{0.951056f, 0.162460f, -0.262866f},
|
||||
{0.525731f, 0.000000f, -0.850651f},
|
||||
{0.681718f, 0.147621f, -0.716567f},
|
||||
{0.681718f, -0.147621f, -0.716567f},
|
||||
{0.850651f, 0.000000f, -0.525731f},
|
||||
{0.809017f, -0.309017f, -0.500000f},
|
||||
{0.864188f, -0.442863f, -0.238856f},
|
||||
{0.951056f, -0.162460f, -0.262866f},
|
||||
{0.147621f, 0.716567f, -0.681718f},
|
||||
{0.309017f, 0.500000f, -0.809017f},
|
||||
{0.425325f, 0.688191f, -0.587785f},
|
||||
{0.442863f, 0.238856f, -0.864188f},
|
||||
{0.587785f, 0.425325f, -0.688191f},
|
||||
{0.688191f, 0.587785f, -0.425325f},
|
||||
{-0.147621f, 0.716567f, -0.681718f},
|
||||
{-0.309017f, 0.500000f, -0.809017f},
|
||||
{0.000000f, 0.525731f, -0.850651f},
|
||||
{-0.525731f, 0.000000f, -0.850651f},
|
||||
{-0.442863f, 0.238856f, -0.864188f},
|
||||
{-0.295242f, 0.000000f, -0.955423f},
|
||||
{-0.162460f, 0.262866f, -0.951056f},
|
||||
{0.000000f, 0.000000f, -1.000000f},
|
||||
{0.295242f, 0.000000f, -0.955423f},
|
||||
{0.162460f, 0.262866f, -0.951056f},
|
||||
{-0.442863f, -0.238856f, -0.864188f},
|
||||
{-0.309017f, -0.500000f, -0.809017f},
|
||||
{-0.162460f, -0.262866f, -0.951056f},
|
||||
{0.000000f, -0.850651f, -0.525731f},
|
||||
{-0.147621f, -0.716567f, -0.681718f},
|
||||
{0.147621f, -0.716567f, -0.681718f},
|
||||
{0.000000f, -0.525731f, -0.850651f},
|
||||
{0.309017f, -0.500000f, -0.809017f},
|
||||
{0.442863f, -0.238856f, -0.864188f},
|
||||
{0.162460f, -0.262866f, -0.951056f},
|
||||
{0.238856f, -0.864188f, -0.442863f},
|
||||
{0.500000f, -0.809017f, -0.309017f},
|
||||
{0.425325f, -0.688191f, -0.587785f},
|
||||
{0.716567f, -0.681718f, -0.147621f},
|
||||
{0.688191f, -0.587785f, -0.425325f},
|
||||
{0.587785f, -0.425325f, -0.688191f},
|
||||
{0.000000f, -0.955423f, -0.295242f},
|
||||
{0.000000f, -1.000000f, 0.000000f},
|
||||
{0.262866f, -0.951056f, -0.162460f},
|
||||
{0.000000f, -0.850651f, 0.525731f},
|
||||
{0.000000f, -0.955423f, 0.295242f},
|
||||
{0.238856f, -0.864188f, 0.442863f},
|
||||
{0.262866f, -0.951056f, 0.162460f},
|
||||
{0.500000f, -0.809017f, 0.309017f},
|
||||
{0.716567f, -0.681718f, 0.147621f},
|
||||
{0.525731f, -0.850651f, 0.000000f},
|
||||
{-0.238856f, -0.864188f, -0.442863f},
|
||||
{-0.500000f, -0.809017f, -0.309017f},
|
||||
{-0.262866f, -0.951056f, -0.162460f},
|
||||
{-0.850651f, -0.525731f, 0.000000f},
|
||||
{-0.716567f, -0.681718f, -0.147621f},
|
||||
{-0.716567f, -0.681718f, 0.147621f},
|
||||
{-0.525731f, -0.850651f, 0.000000f},
|
||||
{-0.500000f, -0.809017f, 0.309017f},
|
||||
{-0.238856f, -0.864188f, 0.442863f},
|
||||
{-0.262866f, -0.951056f, 0.162460f},
|
||||
{-0.864188f, -0.442863f, 0.238856f},
|
||||
{-0.809017f, -0.309017f, 0.500000f},
|
||||
{-0.688191f, -0.587785f, 0.425325f},
|
||||
{-0.681718f, -0.147621f, 0.716567f},
|
||||
{-0.442863f, -0.238856f, 0.864188f},
|
||||
{-0.587785f, -0.425325f, 0.688191f},
|
||||
{-0.309017f, -0.500000f, 0.809017f},
|
||||
{-0.147621f, -0.716567f, 0.681718f},
|
||||
{-0.425325f, -0.688191f, 0.587785f},
|
||||
{-0.162460f, -0.262866f, 0.951056f},
|
||||
{0.442863f, -0.238856f, 0.864188f},
|
||||
{0.162460f, -0.262866f, 0.951056f},
|
||||
{0.309017f, -0.500000f, 0.809017f},
|
||||
{0.147621f, -0.716567f, 0.681718f},
|
||||
{0.000000f, -0.525731f, 0.850651f},
|
||||
{0.425325f, -0.688191f, 0.587785f},
|
||||
{0.587785f, -0.425325f, 0.688191f},
|
||||
{0.688191f, -0.587785f, 0.425325f},
|
||||
{-0.955423f, 0.295242f, 0.000000f},
|
||||
{-0.951056f, 0.162460f, 0.262866f},
|
||||
{-1.000000f, 0.000000f, 0.000000f},
|
||||
{-0.850651f, 0.000000f, 0.525731f},
|
||||
{-0.955423f, -0.295242f, 0.000000f},
|
||||
{-0.951056f, -0.162460f, 0.262866f},
|
||||
{-0.864188f, 0.442863f, -0.238856f},
|
||||
{-0.951056f, 0.162460f, -0.262866f},
|
||||
{-0.809017f, 0.309017f, -0.500000f},
|
||||
{-0.864188f, -0.442863f, -0.238856f},
|
||||
{-0.951056f, -0.162460f, -0.262866f},
|
||||
{-0.809017f, -0.309017f, -0.500000f},
|
||||
{-0.681718f, 0.147621f, -0.716567f},
|
||||
{-0.681718f, -0.147621f, -0.716567f},
|
||||
{-0.850651f, 0.000000f, -0.525731f},
|
||||
{-0.688191f, 0.587785f, -0.425325f},
|
||||
{-0.587785f, 0.425325f, -0.688191f},
|
||||
{-0.425325f, 0.688191f, -0.587785f},
|
||||
{-0.425325f, -0.688191f, -0.587785f},
|
||||
{-0.587785f, -0.425325f, -0.688191f},
|
||||
{-0.688191f, -0.587785f, -0.425325f},
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int ident; // A "magic number" that's used to identify the .md2 file
|
||||
int version; // The version of the file, always 8
|
||||
int skinwidth; // Width of the skin(s) in pixels
|
||||
int skinheight; // Height of the skin(s) in pixels
|
||||
int framesize; // Size of each frame in bytes
|
||||
int numSkins; // Number of skins with the model
|
||||
int numXYZ; // Number of vertices in each frame
|
||||
int numST; // Number of texture coordinates in each frame.
|
||||
int numTris; // Number of triangles in each frame
|
||||
int numGLcmds; // Number of dwords (4 bytes) in the gl command list.
|
||||
int numFrames; // Number of frames
|
||||
int offsetSkins; // Offset, in bytes from the start of the file, to the list of skin names.
|
||||
int offsetST; // Offset, in bytes from the start of the file, to the list of texture coordinates
|
||||
int offsetTris; // Offset, in bytes from the start of the file, to the list of triangles
|
||||
int offsetFrames; // Offset, in bytes from the start of the file, to the list of frames
|
||||
int offsetGLcmds; // Offset, in bytes from the start of the file, to the list of gl commands
|
||||
int offsetEnd; // Offset, in bytes from the start of the file, to the end of the file (filesize)
|
||||
} md2header_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned short meshIndex[3]; // indices into the array of vertices in each frames
|
||||
unsigned short stIndex[3]; // indices into the array of texture coordinates
|
||||
} md2triangle_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
short s;
|
||||
short t;
|
||||
} md2texcoord_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char v[3]; // Scaled vertices. You'll need to multiply them with scale[x] to make them normal.
|
||||
unsigned char lightNormalIndex; // Index to the array of normals
|
||||
} md2vertex_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float scale[3]; // Used by the v member in the md2framePoint structure
|
||||
float translate[3]; // Used by the v member in the md2framePoint structure
|
||||
char name[16]; // Name of the frame
|
||||
} md2frame_t;
|
||||
|
||||
// Load the model
|
||||
model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat)
|
||||
{
|
||||
FILE *f;
|
||||
|
||||
model_t *retModel = NULL;
|
||||
md2header_t *header;
|
||||
|
||||
size_t fileLen;
|
||||
int i, j;
|
||||
size_t namelen;
|
||||
char *texturefilename;
|
||||
const char *texPos;
|
||||
|
||||
char *buffer;
|
||||
|
||||
const float WUNITS = 1.0f;
|
||||
float dataScale = WUNITS;
|
||||
|
||||
md2triangle_t *tris;
|
||||
md2texcoord_t *texcoords;
|
||||
md2frame_t *frames;
|
||||
char *fname = NULL;
|
||||
int foffset = 0;
|
||||
|
||||
int t;
|
||||
|
||||
// MD2 currently does not work with tinyframes, so force useFloat = true
|
||||
//
|
||||
// <SSNTails>
|
||||
// the UV coordinates in MD2 are not compatible with glDrawElements like MD3 is. So they need to be loaded as full float.
|
||||
//
|
||||
// MD2 is intended to be draw in triangle strips and fans
|
||||
// not very compatible with a modern GL implementation, either
|
||||
// so the idea would be to full float expand it, and put it in a vertex buffer object
|
||||
// I'm sure there's a way to convert the UVs to 'tinyframes', but maybe that's a job for someone else.
|
||||
// You'd have to decompress the model, then recompress, reindexing the triangles and weeding out duplicate coordinates
|
||||
// I already have the decompression work done
|
||||
|
||||
useFloat = true;
|
||||
|
||||
f = fopen(fileName, "rb");
|
||||
|
||||
if (!f)
|
||||
return NULL;
|
||||
|
||||
retModel = (model_t*)Z_Calloc(sizeof(model_t), ztag, 0);
|
||||
|
||||
//size_t fileLen;
|
||||
|
||||
//int i, j;
|
||||
|
||||
//size_t namelen;
|
||||
//char *texturefilename;
|
||||
texPos = strchr(fileName, '/');
|
||||
|
||||
if (texPos)
|
||||
{
|
||||
texPos++;
|
||||
namelen = strlen(texPos) + 1;
|
||||
texturefilename = (char*)Z_Malloc(namelen, PU_CACHE, 0);
|
||||
strcpy(texturefilename, texPos);
|
||||
}
|
||||
else
|
||||
{
|
||||
namelen = strlen(fileName) + 1;
|
||||
texturefilename = (char*)Z_Malloc(namelen, PU_CACHE, 0);
|
||||
strcpy(texturefilename, fileName);
|
||||
}
|
||||
|
||||
texturefilename[namelen - 2] = 'z';
|
||||
texturefilename[namelen - 3] = 'u';
|
||||
texturefilename[namelen - 4] = 'b';
|
||||
|
||||
// find length of file
|
||||
fseek(f, 0, SEEK_END);
|
||||
fileLen = ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
|
||||
// read in file
|
||||
buffer = malloc(fileLen);
|
||||
if (fread(buffer, fileLen, 1, f)) { } // squash ignored fread error
|
||||
fclose(f);
|
||||
|
||||
// get pointer to file header
|
||||
header = (md2header_t*)buffer;
|
||||
|
||||
retModel->numMeshes = 1; // MD2 only has one mesh
|
||||
retModel->meshes = (mesh_t*)Z_Calloc(sizeof(mesh_t) * retModel->numMeshes, ztag, 0);
|
||||
retModel->meshes[0].numFrames = header->numFrames;
|
||||
// const float WUNITS = 1.0f;
|
||||
// float dataScale = WUNITS;
|
||||
|
||||
// Tris and ST are simple structures that can be straight-copied
|
||||
tris = (md2triangle_t*)&buffer[header->offsetTris];
|
||||
texcoords = (md2texcoord_t*)&buffer[header->offsetST];
|
||||
frames = (md2frame_t*)&buffer[header->offsetFrames];
|
||||
|
||||
retModel->framenames = (char*)Z_Calloc(header->numFrames*16, ztag, 0);
|
||||
fname = retModel->framenames;
|
||||
for (i = 0; i < header->numFrames; i++)
|
||||
{
|
||||
md2frame_t *fr = (md2frame_t*)&buffer[header->offsetFrames + foffset];
|
||||
memcpy(fname, fr->name, 16);
|
||||
foffset += sizeof(md2frame_t) + (sizeof(md2vertex_t) * header->numXYZ);
|
||||
fname += 16;
|
||||
}
|
||||
|
||||
// Read in textures
|
||||
retModel->numMaterials = header->numSkins;
|
||||
|
||||
if (retModel->numMaterials <= 0) // Always at least one skin, duh
|
||||
retModel->numMaterials = 1;
|
||||
|
||||
retModel->materials = (material_t*)Z_Calloc(sizeof(material_t)*retModel->numMaterials, ztag, 0);
|
||||
|
||||
// int t;
|
||||
for (t = 0; t < retModel->numMaterials; t++)
|
||||
{
|
||||
retModel->materials[t].ambient[0] = 0.8f;
|
||||
retModel->materials[t].ambient[1] = 0.8f;
|
||||
retModel->materials[t].ambient[2] = 0.8f;
|
||||
retModel->materials[t].ambient[3] = 1.0f;
|
||||
retModel->materials[t].diffuse[0] = 0.8f;
|
||||
retModel->materials[t].diffuse[1] = 0.8f;
|
||||
retModel->materials[t].diffuse[2] = 0.8f;
|
||||
retModel->materials[t].diffuse[3] = 1.0f;
|
||||
retModel->materials[t].emissive[0] = 0.0f;
|
||||
retModel->materials[t].emissive[1] = 0.0f;
|
||||
retModel->materials[t].emissive[2] = 0.0f;
|
||||
retModel->materials[t].emissive[3] = 1.0f;
|
||||
retModel->materials[t].specular[0] = 0.0f;
|
||||
retModel->materials[t].specular[1] = 0.0f;
|
||||
retModel->materials[t].specular[2] = 0.0f;
|
||||
retModel->materials[t].specular[3] = 1.0f;
|
||||
retModel->materials[t].shininess = 0.0f;
|
||||
retModel->materials[t].spheremap = false;
|
||||
|
||||
/* retModel->materials[t].texture = Texture::ReadTexture((char*)texturefilename, ZT_TEXTURE);
|
||||
|
||||
if (!systemSucks)
|
||||
{
|
||||
// Check for a normal map...??
|
||||
char openfilename[1024];
|
||||
char normalMapName[1024];
|
||||
strcpy(normalMapName, texturefilename);
|
||||
size_t len = strlen(normalMapName);
|
||||
char *ptr = &normalMapName[len];
|
||||
ptr--; // z
|
||||
ptr--; // u
|
||||
ptr--; // b
|
||||
ptr--; // .
|
||||
*ptr++ = '_';
|
||||
*ptr++ = 'n';
|
||||
*ptr++ = '.';
|
||||
*ptr++ = 'b';
|
||||
*ptr++ = 'u';
|
||||
*ptr++ = 'z';
|
||||
*ptr++ = '\0';
|
||||
|
||||
sprintf(openfilename, "%s/%s", "textures", normalMapName);
|
||||
// Convert backslashes to forward slashes
|
||||
for (int k = 0; k < 1024; k++)
|
||||
{
|
||||
if (openfilename[k] == '\0')
|
||||
break;
|
||||
|
||||
if (openfilename[k] == '\\')
|
||||
openfilename[k] = '/';
|
||||
}
|
||||
|
||||
Resource::resource_t *res = Resource::Open(openfilename);
|
||||
if (res)
|
||||
{
|
||||
Resource::Close(res);
|
||||
retModel->materials[t].lightmap = Texture::ReadTexture(normalMapName, ZT_TEXTURE);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
retModel->meshes[0].numTriangles = header->numTris;
|
||||
|
||||
if (!useFloat) // Decompress to MD3 'tinyframe' space
|
||||
{
|
||||
char *ptr;
|
||||
|
||||
md2triangle_t *trisPtr;
|
||||
unsigned short *indexptr;
|
||||
float *uvptr;
|
||||
|
||||
dataScale = 0.015624f; // 1 / 64.0f
|
||||
retModel->meshes[0].tinyframes = (tinyframe_t*)Z_Calloc(sizeof(tinyframe_t)*header->numFrames, ztag, 0);
|
||||
retModel->meshes[0].numVertices = header->numXYZ;
|
||||
retModel->meshes[0].uvs = (float*)Z_Malloc(sizeof(float) * 2 * retModel->meshes[0].numVertices, ztag, 0);
|
||||
|
||||
ptr = (char*)frames;
|
||||
for (i = 0; i < header->numFrames; i++, ptr += header->framesize)
|
||||
{
|
||||
short *vertptr;
|
||||
char *normptr;
|
||||
// char *tanptr;
|
||||
|
||||
md2vertex_t *vertex;
|
||||
|
||||
md2frame_t *framePtr = (md2frame_t*)ptr;
|
||||
retModel->meshes[0].tinyframes[i].vertices = (short*)Z_Malloc(sizeof(short) * 3 * header->numXYZ, ztag, 0);
|
||||
retModel->meshes[0].tinyframes[i].normals = (char*)Z_Malloc(sizeof(char) * 3 * header->numXYZ, ztag, 0);
|
||||
|
||||
// if (retModel->materials[0].lightmap)
|
||||
// retModel->meshes[0].tinyframes[i].tangents = (char*)malloc(sizeof(char));//(char*)Z_Malloc(sizeof(char)*3*header->numVerts, ztag);
|
||||
retModel->meshes[0].indices = (unsigned short*)Z_Malloc(sizeof(unsigned short) * 3 * header->numTris, ztag, 0);
|
||||
|
||||
vertptr = retModel->meshes[0].tinyframes[i].vertices;
|
||||
normptr = retModel->meshes[0].tinyframes[i].normals;
|
||||
|
||||
// tanptr = retModel->meshes[0].tinyframes[i].tangents;
|
||||
retModel->meshes[0].tinyframes[i].material = &retModel->materials[0];
|
||||
|
||||
framePtr++; // Advance to vertex list
|
||||
vertex = (md2vertex_t*)framePtr;
|
||||
framePtr--;
|
||||
for (j = 0; j < header->numXYZ; j++, vertex++)
|
||||
{
|
||||
*vertptr = (short)(((vertex->v[0] * framePtr->scale[0]) + framePtr->translate[0]) / dataScale);
|
||||
vertptr++;
|
||||
*vertptr = (short)(((vertex->v[2] * framePtr->scale[2]) + framePtr->translate[2]) / dataScale);
|
||||
vertptr++;
|
||||
*vertptr = -1.0f * (short)(((vertex->v[1] * framePtr->scale[1]) + framePtr->translate[1]) / dataScale);
|
||||
vertptr++;
|
||||
|
||||
// Normal
|
||||
*normptr++ = (char)(avertexnormals[vertex->lightNormalIndex][0] * 127);
|
||||
*normptr++ = (char)(avertexnormals[vertex->lightNormalIndex][2] * 127);
|
||||
*normptr++ = (char)(avertexnormals[vertex->lightNormalIndex][1] * 127);
|
||||
}
|
||||
}
|
||||
|
||||
// This doesn't need to be done every frame!
|
||||
trisPtr = tris;
|
||||
indexptr = retModel->meshes[0].indices;
|
||||
uvptr = (float*)retModel->meshes[0].uvs;
|
||||
for (j = 0; j < header->numTris; j++, trisPtr++)
|
||||
{
|
||||
*indexptr = trisPtr->meshIndex[0];
|
||||
indexptr++;
|
||||
*indexptr = trisPtr->meshIndex[1];
|
||||
indexptr++;
|
||||
*indexptr = trisPtr->meshIndex[2];
|
||||
indexptr++;
|
||||
|
||||
uvptr[trisPtr->meshIndex[0] * 2] = texcoords[trisPtr->stIndex[0]].s / (float)header->skinwidth;
|
||||
uvptr[trisPtr->meshIndex[0] * 2 + 1] = (texcoords[trisPtr->stIndex[0]].t / (float)header->skinheight);
|
||||
uvptr[trisPtr->meshIndex[1] * 2] = texcoords[trisPtr->stIndex[1]].s / (float)header->skinwidth;
|
||||
uvptr[trisPtr->meshIndex[1] * 2 + 1] = (texcoords[trisPtr->stIndex[1]].t / (float)header->skinheight);
|
||||
uvptr[trisPtr->meshIndex[2] * 2] = texcoords[trisPtr->stIndex[2]].s / (float)header->skinwidth;
|
||||
uvptr[trisPtr->meshIndex[2] * 2 + 1] = (texcoords[trisPtr->stIndex[2]].t / (float)header->skinheight);
|
||||
}
|
||||
}
|
||||
else // Full float loading method
|
||||
{
|
||||
md2triangle_t *trisPtr;
|
||||
float *uvptr;
|
||||
|
||||
char *ptr;
|
||||
|
||||
retModel->meshes[0].numVertices = header->numTris * 3;
|
||||
retModel->meshes[0].frames = (mdlframe_t*)Z_Calloc(sizeof(mdlframe_t)*header->numFrames, ztag, 0);
|
||||
retModel->meshes[0].uvs = (float*)Z_Malloc(sizeof(float) * 2 * retModel->meshes[0].numVertices, ztag, 0);
|
||||
|
||||
trisPtr = tris;
|
||||
uvptr = retModel->meshes[0].uvs;
|
||||
for (i = 0; i < retModel->meshes[0].numTriangles; i++, trisPtr++)
|
||||
{
|
||||
*uvptr++ = texcoords[trisPtr->stIndex[0]].s / (float)header->skinwidth;
|
||||
*uvptr++ = (texcoords[trisPtr->stIndex[0]].t / (float)header->skinheight);
|
||||
*uvptr++ = texcoords[trisPtr->stIndex[1]].s / (float)header->skinwidth;
|
||||
*uvptr++ = (texcoords[trisPtr->stIndex[1]].t / (float)header->skinheight);
|
||||
*uvptr++ = texcoords[trisPtr->stIndex[2]].s / (float)header->skinwidth;
|
||||
*uvptr++ = (texcoords[trisPtr->stIndex[2]].t / (float)header->skinheight);
|
||||
}
|
||||
|
||||
ptr = (char*)frames;
|
||||
for (i = 0; i < header->numFrames; i++, ptr += header->framesize)
|
||||
{
|
||||
float *vertptr, *normptr;
|
||||
|
||||
md2vertex_t *vertex;
|
||||
|
||||
md2frame_t *framePtr = (md2frame_t*)ptr;
|
||||
retModel->meshes[0].frames[i].normals = (float*)Z_Malloc(sizeof(float) * 3 * header->numTris * 3, ztag, 0);
|
||||
retModel->meshes[0].frames[i].vertices = (float*)Z_Malloc(sizeof(float) * 3 * header->numTris * 3, ztag, 0);
|
||||
// if (retModel->materials[0].lightmap)
|
||||
// retModel->meshes[0].frames[i].tangents = (float*)malloc(sizeof(float));//(float*)Z_Malloc(sizeof(float)*3*header->numTris*3, ztag);
|
||||
//float *vertptr, *normptr;
|
||||
normptr = (float*)retModel->meshes[0].frames[i].normals;
|
||||
vertptr = (float*)retModel->meshes[0].frames[i].vertices;
|
||||
trisPtr = tris;
|
||||
|
||||
retModel->meshes[0].frames[i].material = &retModel->materials[0];
|
||||
|
||||
framePtr++; // Advance to vertex list
|
||||
vertex = (md2vertex_t*)framePtr;
|
||||
framePtr--;
|
||||
for (j = 0; j < header->numTris; j++, trisPtr++)
|
||||
{
|
||||
*vertptr = ((vertex[trisPtr->meshIndex[0]].v[0] * framePtr->scale[0]) + framePtr->translate[0]) * WUNITS;
|
||||
vertptr++;
|
||||
*vertptr = ((vertex[trisPtr->meshIndex[0]].v[2] * framePtr->scale[2]) + framePtr->translate[2]) * WUNITS;
|
||||
vertptr++;
|
||||
*vertptr = -1.0f * ((vertex[trisPtr->meshIndex[0]].v[1] * framePtr->scale[1]) + framePtr->translate[1]) * WUNITS;
|
||||
vertptr++;
|
||||
|
||||
*vertptr = ((vertex[trisPtr->meshIndex[1]].v[0] * framePtr->scale[0]) + framePtr->translate[0]) * WUNITS;
|
||||
vertptr++;
|
||||
*vertptr = ((vertex[trisPtr->meshIndex[1]].v[2] * framePtr->scale[2]) + framePtr->translate[2]) * WUNITS;
|
||||
vertptr++;
|
||||
*vertptr = -1.0f * ((vertex[trisPtr->meshIndex[1]].v[1] * framePtr->scale[1]) + framePtr->translate[1]) * WUNITS;
|
||||
vertptr++;
|
||||
|
||||
*vertptr = ((vertex[trisPtr->meshIndex[2]].v[0] * framePtr->scale[0]) + framePtr->translate[0]) * WUNITS;
|
||||
vertptr++;
|
||||
*vertptr = ((vertex[trisPtr->meshIndex[2]].v[2] * framePtr->scale[2]) + framePtr->translate[2]) * WUNITS;
|
||||
vertptr++;
|
||||
*vertptr = -1.0f * ((vertex[trisPtr->meshIndex[2]].v[1] * framePtr->scale[1]) + framePtr->translate[1]) * WUNITS;
|
||||
vertptr++;
|
||||
|
||||
*normptr++ = avertexnormals[vertex[trisPtr->meshIndex[0]].lightNormalIndex][0];
|
||||
*normptr++ = avertexnormals[vertex[trisPtr->meshIndex[0]].lightNormalIndex][2];
|
||||
*normptr++ = avertexnormals[vertex[trisPtr->meshIndex[0]].lightNormalIndex][1];
|
||||
|
||||
*normptr++ = avertexnormals[vertex[trisPtr->meshIndex[1]].lightNormalIndex][0];
|
||||
*normptr++ = avertexnormals[vertex[trisPtr->meshIndex[1]].lightNormalIndex][2];
|
||||
*normptr++ = avertexnormals[vertex[trisPtr->meshIndex[1]].lightNormalIndex][1];
|
||||
|
||||
*normptr++ = avertexnormals[vertex[trisPtr->meshIndex[2]].lightNormalIndex][0];
|
||||
*normptr++ = avertexnormals[vertex[trisPtr->meshIndex[2]].lightNormalIndex][2];
|
||||
*normptr++ = avertexnormals[vertex[trisPtr->meshIndex[2]].lightNormalIndex][1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(buffer);
|
||||
return retModel;
|
||||
}
|
19
src/hardware/hw_md2load.h
Normal file
19
src/hardware/hw_md2load.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
From the 'Wizard2' engine by Spaddlewit Inc. ( http://www.spaddlewit.com )
|
||||
An experimental work-in-progress.
|
||||
|
||||
Donated to Sonic Team Junior and adapted to work with
|
||||
Sonic Robo Blast 2. The license of this code matches whatever
|
||||
the licensing is for Sonic Robo Blast 2.
|
||||
*/
|
||||
|
||||
#ifndef _HW_MD2LOAD_H_
|
||||
#define _HW_MD2LOAD_H_
|
||||
|
||||
#include "hw_model.h"
|
||||
#include "../doomtype.h"
|
||||
|
||||
// Load the Model
|
||||
model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat);
|
||||
|
||||
#endif
|
522
src/hardware/hw_md3load.c
Normal file
522
src/hardware/hw_md3load.c
Normal file
|
@ -0,0 +1,522 @@
|
|||
/*
|
||||
From the 'Wizard2' engine by Spaddlewit Inc. ( http://www.spaddlewit.com )
|
||||
An experimental work-in-progress.
|
||||
|
||||
Donated to Sonic Team Junior and adapted to work with
|
||||
Sonic Robo Blast 2. The license of this code matches whatever
|
||||
the licensing is for Sonic Robo Blast 2.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "../doomdef.h"
|
||||
#include "hw_md3load.h"
|
||||
#include "hw_model.h"
|
||||
#include "../z_zone.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int ident; // A "magic number" that's used to identify the .md3 file
|
||||
int version; // The version of the file, always 15
|
||||
char name[64];
|
||||
int flags;
|
||||
int numFrames; // Number of frames
|
||||
int numTags;
|
||||
int numSurfaces;
|
||||
int numSkins; // Number of skins with the model
|
||||
int offsetFrames;
|
||||
int offsetTags;
|
||||
int offsetSurfaces;
|
||||
int offsetEnd; // Offset, in bytes from the start of the file, to the end of the file (filesize)
|
||||
} md3modelHeader;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float minBounds[3]; // First corner of the bounding box
|
||||
float maxBounds[3]; // Second corner of the bounding box
|
||||
float localOrigin[3]; // Local origin, usually (0, 0, 0)
|
||||
float radius; // Radius of bounding sphere
|
||||
char name[16]; // Name of frame
|
||||
} md3Frame;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char name[64]; // Name of tag
|
||||
float origin[3]; // Coordinates of tag
|
||||
float axis[9]; // Orientation of tag object
|
||||
} md3Tag;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int ident;
|
||||
char name[64]; // Name of this surface
|
||||
int flags;
|
||||
int numFrames; // # of keyframes
|
||||
int numShaders; // # of shaders
|
||||
int numVerts; // # of vertices
|
||||
int numTriangles; // # of triangles
|
||||
int offsetTriangles; // Relative offset from start of this struct to where the list of Triangles start
|
||||
int offsetShaders; // Relative offset from start of this struct to where the list of Shaders start
|
||||
int offsetST; // Relative offset from start of this struct to where the list of tex coords start
|
||||
int offsetXYZNormal; // Relative offset from start of this struct to where the list of vertices start
|
||||
int offsetEnd; // Relative offset from start of this struct to where this surface ends
|
||||
} md3Surface;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char name[64]; // Name of this shader
|
||||
int shaderIndex; // Shader index number
|
||||
} md3Shader;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int index[3]; // List of offset values into the list of Vertex objects that constitute the corners of the Triangle object.
|
||||
} md3Triangle;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float st[2];
|
||||
} md3TexCoord;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
short x, y, z, n;
|
||||
} md3Vertex;
|
||||
|
||||
static float latlnglookup[256][256][3];
|
||||
|
||||
static void GetNormalFromLatLong(short latlng, float *out)
|
||||
{
|
||||
float *lookup = latlnglookup[(unsigned char)(latlng >> 8)][(unsigned char)(latlng & 255)];
|
||||
|
||||
out[0] = *lookup++;
|
||||
out[1] = *lookup++;
|
||||
out[2] = *lookup++;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void NormalToLatLng(float *n, short *out)
|
||||
{
|
||||
// Special cases
|
||||
if (0.0f == n[0] && 0.0f == n[1])
|
||||
{
|
||||
if (n[2] > 0.0f)
|
||||
*out = 0;
|
||||
else
|
||||
*out = 128;
|
||||
}
|
||||
else
|
||||
{
|
||||
char x, y;
|
||||
|
||||
x = (char)(57.2957795f * (atan2(n[1], n[0])) * (255.0f / 360.0f));
|
||||
y = (char)(57.2957795f * (acos(n[2])) * (255.0f / 360.0f));
|
||||
|
||||
*out = (x << 8) + y;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void LatLngToNormal(short n, float *out)
|
||||
{
|
||||
const float PI = (3.1415926535897932384626433832795f);
|
||||
float lat = (float)(n >> 8);
|
||||
float lng = (float)(n & 255);
|
||||
|
||||
lat *= PI / 128.0f;
|
||||
lng *= PI / 128.0f;
|
||||
|
||||
out[0] = cosf(lat) * sinf(lng);
|
||||
out[1] = sinf(lat) * sinf(lng);
|
||||
out[2] = cosf(lng);
|
||||
}
|
||||
|
||||
static void LatLngInit(void)
|
||||
{
|
||||
int i, j;
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
for (j = 0; j < 256; j++)
|
||||
LatLngToNormal((short)((i << 8) + j), latlnglookup[i][j]);
|
||||
}
|
||||
}
|
||||
|
||||
static boolean latlnginit = false;
|
||||
|
||||
model_t *MD3_LoadModel(const char *fileName, int ztag, boolean useFloat)
|
||||
{
|
||||
const float WUNITS = 1.0f;
|
||||
model_t *retModel = NULL;
|
||||
md3Frame *frames = NULL;
|
||||
char *fname = NULL;
|
||||
md3modelHeader *mdh;
|
||||
long fileLen;
|
||||
long fileReadLen;
|
||||
char *buffer;
|
||||
int surfEnd;
|
||||
int i, t;
|
||||
int matCount;
|
||||
FILE *f;
|
||||
|
||||
if (!latlnginit)
|
||||
{
|
||||
LatLngInit();
|
||||
latlnginit = true;
|
||||
}
|
||||
|
||||
f = fopen(fileName, "rb");
|
||||
|
||||
if (!f)
|
||||
return NULL;
|
||||
|
||||
retModel = (model_t*)Z_Calloc(sizeof(model_t), ztag, 0);
|
||||
|
||||
// find length of file
|
||||
fseek(f, 0, SEEK_END);
|
||||
fileLen = ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
|
||||
// read in file
|
||||
buffer = malloc(fileLen);
|
||||
fileReadLen = fread(buffer, fileLen, 1, f);
|
||||
fclose(f);
|
||||
|
||||
(void)fileReadLen; // intentionally ignore return value, per buildbot
|
||||
|
||||
// get pointer to file header
|
||||
mdh = (md3modelHeader*)buffer;
|
||||
|
||||
retModel->numMeshes = mdh->numSurfaces;
|
||||
|
||||
retModel->numMaterials = 0;
|
||||
surfEnd = 0;
|
||||
for (i = 0; i < mdh->numSurfaces; i++)
|
||||
{
|
||||
md3Surface *mdS = (md3Surface*)&buffer[mdh->offsetSurfaces];
|
||||
surfEnd += mdS->offsetEnd;
|
||||
|
||||
retModel->numMaterials += mdS->numShaders;
|
||||
}
|
||||
|
||||
// Initialize materials
|
||||
if (retModel->numMaterials <= 0) // Always at least one skin, duh
|
||||
retModel->numMaterials = 1;
|
||||
|
||||
retModel->materials = (material_t*)Z_Calloc(sizeof(material_t)*retModel->numMaterials, ztag, 0);
|
||||
|
||||
for (t = 0; t < retModel->numMaterials; t++)
|
||||
{
|
||||
retModel->materials[t].ambient[0] = 0.3686f;
|
||||
retModel->materials[t].ambient[1] = 0.3684f;
|
||||
retModel->materials[t].ambient[2] = 0.3684f;
|
||||
retModel->materials[t].ambient[3] = 1.0f;
|
||||
retModel->materials[t].diffuse[0] = 0.8863f;
|
||||
retModel->materials[t].diffuse[1] = 0.8850f;
|
||||
retModel->materials[t].diffuse[2] = 0.8850f;
|
||||
retModel->materials[t].diffuse[3] = 1.0f;
|
||||
retModel->materials[t].emissive[0] = 0.0f;
|
||||
retModel->materials[t].emissive[1] = 0.0f;
|
||||
retModel->materials[t].emissive[2] = 0.0f;
|
||||
retModel->materials[t].emissive[3] = 1.0f;
|
||||
retModel->materials[t].specular[0] = 0.4902f;
|
||||
retModel->materials[t].specular[1] = 0.4887f;
|
||||
retModel->materials[t].specular[2] = 0.4887f;
|
||||
retModel->materials[t].specular[3] = 1.0f;
|
||||
retModel->materials[t].shininess = 25.0f;
|
||||
retModel->materials[t].spheremap = false;
|
||||
}
|
||||
|
||||
retModel->meshes = (mesh_t*)Z_Calloc(sizeof(mesh_t)*retModel->numMeshes, ztag, 0);
|
||||
|
||||
frames = (md3Frame*)&buffer[mdh->offsetFrames];
|
||||
retModel->framenames = (char*)Z_Calloc(mdh->numFrames*16, ztag, 0);
|
||||
fname = retModel->framenames;
|
||||
for (i = 0; i < mdh->numFrames; i++)
|
||||
{
|
||||
memcpy(fname, frames->name, 16);
|
||||
fname += 16;
|
||||
frames++;
|
||||
}
|
||||
|
||||
matCount = 0;
|
||||
for (i = 0, surfEnd = 0; i < mdh->numSurfaces; i++)
|
||||
{
|
||||
int j;
|
||||
md3Shader *mdShader;
|
||||
md3Surface *mdS = (md3Surface*)&buffer[mdh->offsetSurfaces + surfEnd];
|
||||
surfEnd += mdS->offsetEnd;
|
||||
|
||||
mdShader = (md3Shader*)((char*)mdS + mdS->offsetShaders);
|
||||
|
||||
for (j = 0; j < mdS->numShaders; j++, matCount++)
|
||||
{
|
||||
size_t len = strlen(mdShader[j].name);
|
||||
mdShader[j].name[len-1] = 'z';
|
||||
mdShader[j].name[len-2] = 'u';
|
||||
mdShader[j].name[len-3] = 'b';
|
||||
|
||||
// Load material
|
||||
/* retModel->materials[matCount].texture = Texture::ReadTexture(mdShader[j].name, ZT_TEXTURE);
|
||||
|
||||
if (!systemSucks)
|
||||
{
|
||||
// Check for a normal map...??
|
||||
char openfilename[1024];
|
||||
char normalMapName[1024];
|
||||
strcpy(normalMapName, mdShader[j].name);
|
||||
len = strlen(normalMapName);
|
||||
char *ptr = &normalMapName[len];
|
||||
ptr--; // z
|
||||
ptr--; // u
|
||||
ptr--; // b
|
||||
ptr--; // .
|
||||
*ptr++ = '_';
|
||||
*ptr++ = 'n';
|
||||
*ptr++ = '.';
|
||||
*ptr++ = 'b';
|
||||
*ptr++ = 'u';
|
||||
*ptr++ = 'z';
|
||||
*ptr++ = '\0';
|
||||
|
||||
sprintf(openfilename, "%s/%s", "textures", normalMapName);
|
||||
// Convert backslashes to forward slashes
|
||||
for (int k = 0; k < 1024; k++)
|
||||
{
|
||||
if (openfilename[k] == '\0')
|
||||
break;
|
||||
|
||||
if (openfilename[k] == '\\')
|
||||
openfilename[k] = '/';
|
||||
}
|
||||
|
||||
Resource::resource_t *res = Resource::Open(openfilename);
|
||||
if (res)
|
||||
{
|
||||
Resource::Close(res);
|
||||
retModel->materials[matCount].lightmap = Texture::ReadTexture(normalMapName, ZT_TEXTURE);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
retModel->meshes[i].numFrames = mdS->numFrames;
|
||||
retModel->meshes[i].numTriangles = mdS->numTriangles;
|
||||
|
||||
if (!useFloat) // 'tinyframe' mode with indices
|
||||
{
|
||||
float tempNormal[3];
|
||||
float *uvptr;
|
||||
md3TexCoord *mdST;
|
||||
unsigned short *indexptr;
|
||||
md3Triangle *mdT;
|
||||
|
||||
retModel->meshes[i].tinyframes = (tinyframe_t*)Z_Calloc(sizeof(tinyframe_t)*mdS->numFrames, ztag, 0);
|
||||
retModel->meshes[i].numVertices = mdS->numVerts;
|
||||
retModel->meshes[i].uvs = (float*)Z_Malloc(sizeof(float)*2*mdS->numVerts, ztag, 0);
|
||||
for (j = 0; j < mdS->numFrames; j++)
|
||||
{
|
||||
short *vertptr;
|
||||
char *normptr;
|
||||
// char *tanptr;
|
||||
int k;
|
||||
md3Vertex *mdV = (md3Vertex*)((char*)mdS + mdS->offsetXYZNormal + (mdS->numVerts*j*sizeof(md3Vertex)));
|
||||
retModel->meshes[i].tinyframes[j].vertices = (short*)Z_Malloc(sizeof(short)*3*mdS->numVerts, ztag, 0);
|
||||
retModel->meshes[i].tinyframes[j].normals = (char*)Z_Malloc(sizeof(char)*3*mdS->numVerts, ztag, 0);
|
||||
|
||||
// if (retModel->materials[0].lightmap)
|
||||
// retModel->meshes[i].tinyframes[j].tangents = (char*)malloc(sizeof(char));//(char*)Z_Malloc(sizeof(char)*3*mdS->numVerts, ztag);
|
||||
retModel->meshes[i].indices = (unsigned short*)Z_Malloc(sizeof(unsigned short) * 3 * mdS->numTriangles, ztag, 0);
|
||||
vertptr = retModel->meshes[i].tinyframes[j].vertices;
|
||||
normptr = retModel->meshes[i].tinyframes[j].normals;
|
||||
|
||||
// tanptr = retModel->meshes[i].tinyframes[j].tangents;
|
||||
retModel->meshes[i].tinyframes[j].material = &retModel->materials[i];
|
||||
|
||||
for (k = 0; k < mdS->numVerts; k++)
|
||||
{
|
||||
// Vertex
|
||||
*vertptr = mdV[k].x;
|
||||
vertptr++;
|
||||
*vertptr = mdV[k].z;
|
||||
vertptr++;
|
||||
*vertptr = 1.0f - mdV[k].y;
|
||||
vertptr++;
|
||||
|
||||
// Normal
|
||||
GetNormalFromLatLong(mdV[k].n, tempNormal);
|
||||
*normptr = (char)(tempNormal[0] * 127);
|
||||
normptr++;
|
||||
*normptr = (char)(tempNormal[2] * 127);
|
||||
normptr++;
|
||||
*normptr = (char)(tempNormal[1] * 127);
|
||||
normptr++;
|
||||
}
|
||||
}
|
||||
|
||||
uvptr = (float*)retModel->meshes[i].uvs;
|
||||
mdST = (md3TexCoord*)((char*)mdS + mdS->offsetST);
|
||||
for (j = 0; j < mdS->numVerts; j++)
|
||||
{
|
||||
*uvptr = mdST[j].st[0];
|
||||
uvptr++;
|
||||
*uvptr = mdST[j].st[1];
|
||||
uvptr++;
|
||||
}
|
||||
|
||||
indexptr = retModel->meshes[i].indices;
|
||||
mdT = (md3Triangle*)((char*)mdS + mdS->offsetTriangles);
|
||||
for (j = 0; j < mdS->numTriangles; j++, mdT++)
|
||||
{
|
||||
// Indices
|
||||
*indexptr = (unsigned short)mdT->index[0];
|
||||
indexptr++;
|
||||
*indexptr = (unsigned short)mdT->index[1];
|
||||
indexptr++;
|
||||
*indexptr = (unsigned short)mdT->index[2];
|
||||
indexptr++;
|
||||
}
|
||||
}
|
||||
else // Traditional full-float loading method
|
||||
{
|
||||
float dataScale = 0.015624f * WUNITS;
|
||||
float tempNormal[3];
|
||||
md3TexCoord *mdST;
|
||||
md3Triangle *mdT;
|
||||
float *uvptr;
|
||||
int k;
|
||||
|
||||
retModel->meshes[i].numVertices = mdS->numTriangles * 3;//mdS->numVerts;
|
||||
retModel->meshes[i].frames = (mdlframe_t*)Z_Calloc(sizeof(mdlframe_t)*mdS->numFrames, ztag, 0);
|
||||
retModel->meshes[i].uvs = (float*)Z_Malloc(sizeof(float)*2*mdS->numTriangles*3, ztag, 0);
|
||||
|
||||
for (j = 0; j < mdS->numFrames; j++)
|
||||
{
|
||||
float *vertptr;
|
||||
float *normptr;
|
||||
md3Vertex *mdV = (md3Vertex*)((char*)mdS + mdS->offsetXYZNormal + (mdS->numVerts*j*sizeof(md3Vertex)));
|
||||
retModel->meshes[i].frames[j].vertices = (float*)Z_Malloc(sizeof(float)*3*mdS->numTriangles*3, ztag, 0);
|
||||
retModel->meshes[i].frames[j].normals = (float*)Z_Malloc(sizeof(float)*3*mdS->numTriangles*3, ztag, 0);
|
||||
// if (retModel->materials[i].lightmap)
|
||||
// retModel->meshes[i].frames[j].tangents = (float*)malloc(sizeof(float));//(float*)Z_Malloc(sizeof(float)*3*mdS->numTriangles*3, ztag);
|
||||
vertptr = retModel->meshes[i].frames[j].vertices;
|
||||
normptr = retModel->meshes[i].frames[j].normals;
|
||||
retModel->meshes[i].frames[j].material = &retModel->materials[i];
|
||||
|
||||
mdT = (md3Triangle*)((char*)mdS + mdS->offsetTriangles);
|
||||
|
||||
for (k = 0; k < mdS->numTriangles; k++)
|
||||
{
|
||||
// Vertex 1
|
||||
*vertptr = mdV[mdT->index[0]].x * dataScale;
|
||||
vertptr++;
|
||||
*vertptr = mdV[mdT->index[0]].z * dataScale;
|
||||
vertptr++;
|
||||
*vertptr = 1.0f - mdV[mdT->index[0]].y * dataScale;
|
||||
vertptr++;
|
||||
|
||||
GetNormalFromLatLong(mdV[mdT->index[0]].n, tempNormal);
|
||||
*normptr = tempNormal[0];
|
||||
normptr++;
|
||||
*normptr = tempNormal[2];
|
||||
normptr++;
|
||||
*normptr = tempNormal[1];
|
||||
normptr++;
|
||||
|
||||
// Vertex 2
|
||||
*vertptr = mdV[mdT->index[1]].x * dataScale;
|
||||
vertptr++;
|
||||
*vertptr = mdV[mdT->index[1]].z * dataScale;
|
||||
vertptr++;
|
||||
*vertptr = 1.0f - mdV[mdT->index[1]].y * dataScale;
|
||||
vertptr++;
|
||||
|
||||
GetNormalFromLatLong(mdV[mdT->index[1]].n, tempNormal);
|
||||
*normptr = tempNormal[0];
|
||||
normptr++;
|
||||
*normptr = tempNormal[2];
|
||||
normptr++;
|
||||
*normptr = tempNormal[1];
|
||||
normptr++;
|
||||
|
||||
// Vertex 3
|
||||
*vertptr = mdV[mdT->index[2]].x * dataScale;
|
||||
vertptr++;
|
||||
*vertptr = mdV[mdT->index[2]].z * dataScale;
|
||||
vertptr++;
|
||||
*vertptr = 1.0f - mdV[mdT->index[2]].y * dataScale;
|
||||
vertptr++;
|
||||
|
||||
GetNormalFromLatLong(mdV[mdT->index[2]].n, tempNormal);
|
||||
*normptr = tempNormal[0];
|
||||
normptr++;
|
||||
*normptr = tempNormal[2];
|
||||
normptr++;
|
||||
*normptr = tempNormal[1];
|
||||
normptr++;
|
||||
|
||||
mdT++; // Advance to next triangle
|
||||
}
|
||||
}
|
||||
|
||||
mdST = (md3TexCoord*)((char*)mdS + mdS->offsetST);
|
||||
uvptr = (float*)retModel->meshes[i].uvs;
|
||||
mdT = (md3Triangle*)((char*)mdS + mdS->offsetTriangles);
|
||||
|
||||
for (k = 0; k < mdS->numTriangles; k++)
|
||||
{
|
||||
*uvptr = mdST[mdT->index[0]].st[0];
|
||||
uvptr++;
|
||||
*uvptr = mdST[mdT->index[0]].st[1];
|
||||
uvptr++;
|
||||
|
||||
*uvptr = mdST[mdT->index[1]].st[0];
|
||||
uvptr++;
|
||||
*uvptr = mdST[mdT->index[1]].st[1];
|
||||
uvptr++;
|
||||
|
||||
*uvptr = mdST[mdT->index[2]].st[0];
|
||||
uvptr++;
|
||||
*uvptr = mdST[mdT->index[2]].st[1];
|
||||
uvptr++;
|
||||
|
||||
mdT++; // Advance to next triangle
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
// Tags?
|
||||
retModel->numTags = mdh->numTags;
|
||||
retModel->maxNumFrames = mdh->numFrames;
|
||||
retModel->tags = (tag_t*)Z_Calloc(sizeof(tag_t) * retModel->numTags * mdh->numFrames, ztag);
|
||||
md3Tag *mdTag = (md3Tag*)&buffer[mdh->offsetTags];
|
||||
tag_t *curTag = retModel->tags;
|
||||
for (i = 0; i < mdh->numFrames; i++)
|
||||
{
|
||||
int j;
|
||||
for (j = 0; j < retModel->numTags; j++, mdTag++)
|
||||
{
|
||||
strcpys(curTag->name, mdTag->name, sizeof(curTag->name) / sizeof(char));
|
||||
curTag->transform.m[0][0] = mdTag->axis[0];
|
||||
curTag->transform.m[0][1] = mdTag->axis[1];
|
||||
curTag->transform.m[0][2] = mdTag->axis[2];
|
||||
curTag->transform.m[1][0] = mdTag->axis[3];
|
||||
curTag->transform.m[1][1] = mdTag->axis[4];
|
||||
curTag->transform.m[1][2] = mdTag->axis[5];
|
||||
curTag->transform.m[2][0] = mdTag->axis[6];
|
||||
curTag->transform.m[2][1] = mdTag->axis[7];
|
||||
curTag->transform.m[2][2] = mdTag->axis[8];
|
||||
curTag->transform.m[3][0] = mdTag->origin[0] * WUNITS;
|
||||
curTag->transform.m[3][1] = mdTag->origin[1] * WUNITS;
|
||||
curTag->transform.m[3][2] = mdTag->origin[2] * WUNITS;
|
||||
curTag->transform.m[3][3] = 1.0f;
|
||||
|
||||
Matrix::Rotate(&curTag->transform, 90.0f, &Vector::Xaxis);
|
||||
curTag++;
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
free(buffer);
|
||||
|
||||
return retModel;
|
||||
}
|
19
src/hardware/hw_md3load.h
Normal file
19
src/hardware/hw_md3load.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
From the 'Wizard2' engine by Spaddlewit Inc. ( http://www.spaddlewit.com )
|
||||
An experimental work-in-progress.
|
||||
|
||||
Donated to Sonic Team Junior and adapted to work with
|
||||
Sonic Robo Blast 2. The license of this code matches whatever
|
||||
the licensing is for Sonic Robo Blast 2.
|
||||
*/
|
||||
|
||||
#ifndef _HW_MD3LOAD_H_
|
||||
#define _HW_MD3LOAD_H_
|
||||
|
||||
#include "hw_model.h"
|
||||
#include "../doomtype.h"
|
||||
|
||||
// Load the Model
|
||||
model_t *MD3_LoadModel(const char *fileName, int ztag, boolean useFloat);
|
||||
|
||||
#endif
|
737
src/hardware/hw_model.c
Normal file
737
src/hardware/hw_model.c
Normal file
|
@ -0,0 +1,737 @@
|
|||
/*
|
||||
From the 'Wizard2' engine by Spaddlewit Inc. ( http://www.spaddlewit.com )
|
||||
An experimental work-in-progress.
|
||||
|
||||
Donated to Sonic Team Junior and adapted to work with
|
||||
Sonic Robo Blast 2. The license of this code matches whatever
|
||||
the licensing is for Sonic Robo Blast 2.
|
||||
*/
|
||||
|
||||
#include "../doomdef.h"
|
||||
#include "../doomtype.h"
|
||||
#include "../info.h"
|
||||
#include "../z_zone.h"
|
||||
#include "hw_model.h"
|
||||
#include "hw_md2load.h"
|
||||
#include "hw_md3load.h"
|
||||
#include "hw_md2.h"
|
||||
#include "u_list.h"
|
||||
#include <string.h>
|
||||
|
||||
static float PI = (3.1415926535897932384626433832795f);
|
||||
static float U_Deg2Rad(float deg)
|
||||
{
|
||||
return deg * ((float)PI / 180.0f);
|
||||
}
|
||||
|
||||
vector_t vectorXaxis = { 1.0f, 0.0f, 0.0f };
|
||||
vector_t vectorYaxis = { 0.0f, 1.0f, 0.0f };
|
||||
vector_t vectorZaxis = { 0.0f, 0.0f, 1.0f };
|
||||
|
||||
void VectorRotate(vector_t *rotVec, const vector_t *axisVec, float angle)
|
||||
{
|
||||
float ux, uy, uz, vx, vy, vz, wx, wy, wz, sa, ca;
|
||||
|
||||
angle = U_Deg2Rad(angle);
|
||||
|
||||
// Rotate the point (x,y,z) around the vector (u,v,w)
|
||||
ux = axisVec->x * rotVec->x;
|
||||
uy = axisVec->x * rotVec->y;
|
||||
uz = axisVec->x * rotVec->z;
|
||||
vx = axisVec->y * rotVec->x;
|
||||
vy = axisVec->y * rotVec->y;
|
||||
vz = axisVec->y * rotVec->z;
|
||||
wx = axisVec->z * rotVec->x;
|
||||
wy = axisVec->z * rotVec->y;
|
||||
wz = axisVec->z * rotVec->z;
|
||||
sa = sinf(angle);
|
||||
ca = cosf(angle);
|
||||
|
||||
rotVec->x = axisVec->x*(ux + vy + wz) + (rotVec->x*(axisVec->y*axisVec->y + axisVec->z*axisVec->z) - axisVec->x*(vy + wz))*ca + (-wy + vz)*sa;
|
||||
rotVec->y = axisVec->y*(ux + vy + wz) + (rotVec->y*(axisVec->x*axisVec->x + axisVec->z*axisVec->z) - axisVec->y*(ux + wz))*ca + (wx - uz)*sa;
|
||||
rotVec->z = axisVec->z*(ux + vy + wz) + (rotVec->z*(axisVec->x*axisVec->x + axisVec->y*axisVec->y) - axisVec->z*(ux + vy))*ca + (-vx + uy)*sa;
|
||||
}
|
||||
|
||||
void UnloadModel(model_t *model)
|
||||
{
|
||||
// Wouldn't it be great if C just had destructors?
|
||||
int i;
|
||||
for (i = 0; i < model->numMeshes; i++)
|
||||
{
|
||||
mesh_t *mesh = &model->meshes[i];
|
||||
|
||||
if (mesh->frames)
|
||||
{
|
||||
int j;
|
||||
for (j = 0; j < mesh->numFrames; j++)
|
||||
{
|
||||
if (mesh->frames[j].normals)
|
||||
Z_Free(mesh->frames[j].normals);
|
||||
|
||||
if (mesh->frames[j].tangents)
|
||||
Z_Free(mesh->frames[j].tangents);
|
||||
|
||||
if (mesh->frames[j].vertices)
|
||||
Z_Free(mesh->frames[j].vertices);
|
||||
|
||||
if (mesh->frames[j].colors)
|
||||
Z_Free(mesh->frames[j].colors);
|
||||
}
|
||||
|
||||
Z_Free(mesh->frames);
|
||||
}
|
||||
else if (mesh->tinyframes)
|
||||
{
|
||||
int j;
|
||||
for (j = 0; j < mesh->numFrames; j++)
|
||||
{
|
||||
if (mesh->tinyframes[j].normals)
|
||||
Z_Free(mesh->tinyframes[j].normals);
|
||||
|
||||
if (mesh->tinyframes[j].tangents)
|
||||
Z_Free(mesh->tinyframes[j].tangents);
|
||||
|
||||
if (mesh->tinyframes[j].vertices)
|
||||
Z_Free(mesh->tinyframes[j].vertices);
|
||||
}
|
||||
|
||||
if (mesh->indices)
|
||||
Z_Free(mesh->indices);
|
||||
|
||||
Z_Free(mesh->tinyframes);
|
||||
}
|
||||
|
||||
if (mesh->uvs)
|
||||
Z_Free(mesh->uvs);
|
||||
|
||||
if (mesh->lightuvs)
|
||||
Z_Free(mesh->lightuvs);
|
||||
}
|
||||
|
||||
if (model->meshes)
|
||||
Z_Free(model->meshes);
|
||||
|
||||
if (model->tags)
|
||||
Z_Free(model->tags);
|
||||
|
||||
if (model->materials)
|
||||
Z_Free(model->materials);
|
||||
|
||||
DeleteVBOs(model);
|
||||
Z_Free(model);
|
||||
}
|
||||
|
||||
tag_t *GetTagByName(model_t *model, char *name, int frame)
|
||||
{
|
||||
if (frame < model->maxNumFrames)
|
||||
{
|
||||
tag_t *iterator = &model->tags[frame * model->numTags];
|
||||
|
||||
int i;
|
||||
for (i = 0; i < model->numTags; i++)
|
||||
{
|
||||
if (!stricmp(iterator[i].name, name))
|
||||
return &iterator[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// LoadModel
|
||||
//
|
||||
// Load a model and
|
||||
// convert it to the
|
||||
// internal format.
|
||||
//
|
||||
model_t *LoadModel(const char *filename, int ztag)
|
||||
{
|
||||
model_t *model;
|
||||
|
||||
// What type of file?
|
||||
const char *extension = NULL;
|
||||
int i;
|
||||
for (i = (int)strlen(filename)-1; i >= 0; i--)
|
||||
{
|
||||
if (filename[i] != '.')
|
||||
continue;
|
||||
|
||||
extension = &filename[i];
|
||||
break;
|
||||
}
|
||||
|
||||
if (!extension)
|
||||
{
|
||||
CONS_Printf("Model %s is lacking a file extension, unable to determine type!\n", filename);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!strcmp(extension, ".md3"))
|
||||
{
|
||||
if (!(model = MD3_LoadModel(filename, ztag, false)))
|
||||
return NULL;
|
||||
}
|
||||
else if (!strcmp(extension, ".md3s")) // MD3 that will be converted in memory to use full floats
|
||||
{
|
||||
if (!(model = MD3_LoadModel(filename, ztag, true)))
|
||||
return NULL;
|
||||
}
|
||||
else if (!strcmp(extension, ".md2"))
|
||||
{
|
||||
if (!(model = MD2_LoadModel(filename, ztag, false)))
|
||||
return NULL;
|
||||
}
|
||||
else if (!strcmp(extension, ".md2s"))
|
||||
{
|
||||
if (!(model = MD2_LoadModel(filename, ztag, true)))
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
CONS_Printf("Unknown model format: %s\n", extension);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
model->mdlFilename = (char*)Z_Malloc(strlen(filename)+1, ztag, 0);
|
||||
strcpy(model->mdlFilename, filename);
|
||||
|
||||
Optimize(model);
|
||||
GeneratePolygonNormals(model, ztag);
|
||||
LoadModelSprite2(model);
|
||||
if (!model->spr2frames)
|
||||
LoadModelInterpolationSettings(model);
|
||||
|
||||
// Default material properties
|
||||
for (i = 0 ; i < model->numMaterials; i++)
|
||||
{
|
||||
material_t *material = &model->materials[i];
|
||||
material->ambient[0] = 0.7686f;
|
||||
material->ambient[1] = 0.7686f;
|
||||
material->ambient[2] = 0.7686f;
|
||||
material->ambient[3] = 1.0f;
|
||||
material->diffuse[0] = 0.5863f;
|
||||
material->diffuse[1] = 0.5863f;
|
||||
material->diffuse[2] = 0.5863f;
|
||||
material->diffuse[3] = 1.0f;
|
||||
material->specular[0] = 0.4902f;
|
||||
material->specular[1] = 0.4902f;
|
||||
material->specular[2] = 0.4902f;
|
||||
material->specular[3] = 1.0f;
|
||||
material->shininess = 25.0f;
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
void HWR_ReloadModels(void)
|
||||
{
|
||||
size_t i;
|
||||
INT32 s;
|
||||
|
||||
for (s = 0; s < MAXSKINS; s++)
|
||||
{
|
||||
if (md2_playermodels[s].model)
|
||||
LoadModelSprite2(md2_playermodels[s].model);
|
||||
}
|
||||
|
||||
for (i = 0; i < NUMSPRITES; i++)
|
||||
{
|
||||
if (md2_models[i].model)
|
||||
LoadModelInterpolationSettings(md2_models[i].model);
|
||||
}
|
||||
}
|
||||
|
||||
void LoadModelInterpolationSettings(model_t *model)
|
||||
{
|
||||
INT32 i;
|
||||
INT32 numframes = model->meshes[0].numFrames;
|
||||
char *framename = model->framenames;
|
||||
|
||||
if (!framename)
|
||||
return;
|
||||
|
||||
#define GET_OFFSET \
|
||||
memcpy(&interpolation_flag, framename + offset, 2); \
|
||||
model->interpolate[i] = (!memcmp(interpolation_flag, MODEL_INTERPOLATION_FLAG, 2));
|
||||
|
||||
for (i = 0; i < numframes; i++)
|
||||
{
|
||||
int offset = (strlen(framename) - 4);
|
||||
char interpolation_flag[3];
|
||||
memset(&interpolation_flag, 0x00, 3);
|
||||
|
||||
// find the +i on the frame name
|
||||
// ANIM+i00
|
||||
// so the offset is (frame name length - 4)
|
||||
GET_OFFSET;
|
||||
|
||||
// maybe the frame had three digits?
|
||||
// ANIM+i000
|
||||
// so the offset is (frame name length - 5)
|
||||
if (!model->interpolate[i])
|
||||
{
|
||||
offset--;
|
||||
GET_OFFSET;
|
||||
}
|
||||
|
||||
framename += 16;
|
||||
}
|
||||
|
||||
#undef GET_OFFSET
|
||||
}
|
||||
|
||||
void LoadModelSprite2(model_t *model)
|
||||
{
|
||||
INT32 i;
|
||||
modelspr2frames_t *spr2frames = NULL;
|
||||
INT32 numframes = model->meshes[0].numFrames;
|
||||
char *framename = model->framenames;
|
||||
|
||||
if (!framename)
|
||||
return;
|
||||
|
||||
for (i = 0; i < numframes; i++)
|
||||
{
|
||||
char prefix[6];
|
||||
char name[5];
|
||||
char interpolation_flag[3];
|
||||
char framechars[4];
|
||||
UINT8 frame = 0;
|
||||
UINT8 spr2idx;
|
||||
boolean interpolate = false;
|
||||
|
||||
memset(&prefix, 0x00, 6);
|
||||
memset(&name, 0x00, 5);
|
||||
memset(&interpolation_flag, 0x00, 3);
|
||||
memset(&framechars, 0x00, 4);
|
||||
|
||||
if (strlen(framename) >= 9)
|
||||
{
|
||||
boolean super;
|
||||
char *modelframename = framename;
|
||||
memcpy(&prefix, modelframename, 5);
|
||||
modelframename += 5;
|
||||
memcpy(&name, modelframename, 4);
|
||||
modelframename += 4;
|
||||
// Oh look
|
||||
memcpy(&interpolation_flag, modelframename, 2);
|
||||
if (!memcmp(interpolation_flag, MODEL_INTERPOLATION_FLAG, 2))
|
||||
{
|
||||
interpolate = true;
|
||||
modelframename += 2;
|
||||
}
|
||||
memcpy(&framechars, modelframename, 3);
|
||||
|
||||
if ((super = (!memcmp(prefix, "SUPER", 5))) || (!memcmp(prefix, "SPR2_", 5)))
|
||||
{
|
||||
spr2idx = 0;
|
||||
while (spr2idx < free_spr2)
|
||||
{
|
||||
if (!memcmp(spr2names[spr2idx], name, 4))
|
||||
{
|
||||
if (!spr2frames)
|
||||
spr2frames = (modelspr2frames_t*)Z_Calloc(sizeof(modelspr2frames_t)*NUMPLAYERSPRITES*2, PU_STATIC, NULL);
|
||||
if (super)
|
||||
spr2idx |= FF_SPR2SUPER;
|
||||
if (framechars[0])
|
||||
{
|
||||
frame = atoi(framechars);
|
||||
if (spr2frames[spr2idx].numframes < frame+1)
|
||||
spr2frames[spr2idx].numframes = frame+1;
|
||||
}
|
||||
else
|
||||
{
|
||||
frame = spr2frames[spr2idx].numframes;
|
||||
spr2frames[spr2idx].numframes++;
|
||||
}
|
||||
spr2frames[spr2idx].frames[frame] = i;
|
||||
spr2frames[spr2idx].interpolate = interpolate;
|
||||
break;
|
||||
}
|
||||
spr2idx++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
framename += 16;
|
||||
}
|
||||
|
||||
if (model->spr2frames)
|
||||
Z_Free(model->spr2frames);
|
||||
model->spr2frames = spr2frames;
|
||||
}
|
||||
|
||||
//
|
||||
// GenerateVertexNormals
|
||||
//
|
||||
// Creates a new normal for a vertex using the average of all of the polygons it belongs to.
|
||||
//
|
||||
void GenerateVertexNormals(model_t *model)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < model->numMeshes; i++)
|
||||
{
|
||||
int j;
|
||||
|
||||
mesh_t *mesh = &model->meshes[i];
|
||||
|
||||
if (!mesh->frames)
|
||||
continue;
|
||||
|
||||
for (j = 0; j < mesh->numFrames; j++)
|
||||
{
|
||||
mdlframe_t *frame = &mesh->frames[j];
|
||||
int memTag = PU_STATIC;
|
||||
float *newNormals = (float*)Z_Malloc(sizeof(float)*3*mesh->numTriangles*3, memTag, 0);
|
||||
int k;
|
||||
float *vertPtr = frame->vertices;
|
||||
float *oldNormals;
|
||||
|
||||
M_Memcpy(newNormals, frame->normals, sizeof(float)*3*mesh->numTriangles*3);
|
||||
|
||||
/* if (!systemSucks)
|
||||
{
|
||||
memTag = Z_GetTag(frame->tangents);
|
||||
float *newTangents = (float*)Z_Malloc(sizeof(float)*3*mesh->numTriangles*3, memTag);
|
||||
M_Memcpy(newTangents, frame->tangents, sizeof(float)*3*mesh->numTriangles*3);
|
||||
}*/
|
||||
|
||||
for (k = 0; k < mesh->numVertices; k++)
|
||||
{
|
||||
float x, y, z;
|
||||
int vCount = 0;
|
||||
vector_t normal;
|
||||
int l;
|
||||
float *testPtr = frame->vertices;
|
||||
|
||||
x = *vertPtr++;
|
||||
y = *vertPtr++;
|
||||
z = *vertPtr++;
|
||||
|
||||
normal.x = normal.y = normal.z = 0;
|
||||
|
||||
for (l = 0; l < mesh->numVertices; l++)
|
||||
{
|
||||
float testX, testY, testZ;
|
||||
testX = *testPtr++;
|
||||
testY = *testPtr++;
|
||||
testZ = *testPtr++;
|
||||
|
||||
if (fabsf(x - testX) > FLT_EPSILON
|
||||
|| fabsf(y - testY) > FLT_EPSILON
|
||||
|| fabsf(z - testZ) > FLT_EPSILON)
|
||||
continue;
|
||||
|
||||
// Found a vertex match! Add it...
|
||||
normal.x += frame->normals[3 * l + 0];
|
||||
normal.y += frame->normals[3 * l + 1];
|
||||
normal.z += frame->normals[3 * l + 2];
|
||||
vCount++;
|
||||
}
|
||||
|
||||
if (vCount > 1)
|
||||
{
|
||||
// Vector::Normalize(&normal);
|
||||
newNormals[3 * k + 0] = (float)normal.x;
|
||||
newNormals[3 * k + 1] = (float)normal.y;
|
||||
newNormals[3 * k + 2] = (float)normal.z;
|
||||
|
||||
/* if (!systemSucks)
|
||||
{
|
||||
Vector::vector_t tangent;
|
||||
Vector::Tangent(&normal, &tangent);
|
||||
newTangents[3 * k + 0] = tangent.x;
|
||||
newTangents[3 * k + 1] = tangent.y;
|
||||
newTangents[3 * k + 2] = tangent.z;
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
oldNormals = frame->normals;
|
||||
frame->normals = newNormals;
|
||||
Z_Free(oldNormals);
|
||||
|
||||
/* if (!systemSucks)
|
||||
{
|
||||
float *oldTangents = frame->tangents;
|
||||
frame->tangents = newTangents;
|
||||
Z_Free(oldTangents);
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct materiallist_s
|
||||
{
|
||||
struct materiallist_s *next;
|
||||
struct materiallist_s *prev;
|
||||
material_t *material;
|
||||
} materiallist_t;
|
||||
|
||||
static boolean AddMaterialToList(materiallist_t **head, material_t *material)
|
||||
{
|
||||
materiallist_t *node, *newMatNode;
|
||||
for (node = *head; node; node = node->next)
|
||||
{
|
||||
if (node->material == material)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Didn't find it, so add to the list
|
||||
newMatNode = (materiallist_t*)Z_Malloc(sizeof(materiallist_t), PU_CACHE, 0);
|
||||
newMatNode->material = material;
|
||||
ListAdd(newMatNode, (listitem_t**)head);
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// Optimize
|
||||
//
|
||||
// Groups triangles from meshes in the model
|
||||
// Only works for models with 1 frame
|
||||
//
|
||||
void Optimize(model_t *model)
|
||||
{
|
||||
int numMeshes = 0;
|
||||
int i;
|
||||
materiallist_t *matListHead = NULL;
|
||||
int memTag;
|
||||
mesh_t *newMeshes;
|
||||
materiallist_t *node;
|
||||
|
||||
if (model->numMeshes <= 1)
|
||||
return; // No need
|
||||
|
||||
for (i = 0; i < model->numMeshes; i++)
|
||||
{
|
||||
mesh_t *curMesh = &model->meshes[i];
|
||||
|
||||
if (curMesh->numFrames > 1)
|
||||
return; // Can't optimize models with > 1 frame
|
||||
|
||||
if (!curMesh->frames)
|
||||
return; // Don't optimize tinyframe models (no need)
|
||||
|
||||
// We are condensing to 1 mesh per material, so
|
||||
// the # of materials we use will be the new
|
||||
// # of meshes
|
||||
if (AddMaterialToList(&matListHead, curMesh->frames[0].material))
|
||||
numMeshes++;
|
||||
}
|
||||
|
||||
memTag = PU_STATIC;
|
||||
newMeshes = (mesh_t*)Z_Calloc(sizeof(mesh_t) * numMeshes, memTag, 0);
|
||||
|
||||
i = 0;
|
||||
for (node = matListHead; node; node = node->next)
|
||||
{
|
||||
material_t *curMat = node->material;
|
||||
mesh_t *newMesh = &newMeshes[i];
|
||||
mdlframe_t *curFrame;
|
||||
int uvCount;
|
||||
int vertCount;
|
||||
int colorCount;
|
||||
|
||||
// Find all triangles with this material and count them
|
||||
int numTriangles = 0;
|
||||
int j;
|
||||
for (j = 0; j < model->numMeshes; j++)
|
||||
{
|
||||
mesh_t *curMesh = &model->meshes[j];
|
||||
|
||||
if (curMesh->frames[0].material == curMat)
|
||||
numTriangles += curMesh->numTriangles;
|
||||
}
|
||||
|
||||
newMesh->numFrames = 1;
|
||||
newMesh->numTriangles = numTriangles;
|
||||
newMesh->numVertices = numTriangles * 3;
|
||||
newMesh->uvs = (float*)Z_Malloc(sizeof(float)*2*numTriangles*3, memTag, 0);
|
||||
// if (node->material->lightmap)
|
||||
// newMesh->lightuvs = (float*)Z_Malloc(sizeof(float)*2*numTriangles*3, memTag, 0);
|
||||
newMesh->frames = (mdlframe_t*)Z_Calloc(sizeof(mdlframe_t), memTag, 0);
|
||||
curFrame = &newMesh->frames[0];
|
||||
|
||||
curFrame->material = curMat;
|
||||
curFrame->normals = (float*)Z_Malloc(sizeof(float)*3*numTriangles*3, memTag, 0);
|
||||
// if (!systemSucks)
|
||||
// curFrame->tangents = (float*)Z_Malloc(sizeof(float)*3*numTriangles*3, memTag, 0);
|
||||
curFrame->vertices = (float*)Z_Malloc(sizeof(float)*3*numTriangles*3, memTag, 0);
|
||||
curFrame->colors = (char*)Z_Malloc(sizeof(char)*4*numTriangles*3, memTag, 0);
|
||||
|
||||
// Now traverse the meshes of the model, adding in
|
||||
// vertices/normals/uvs that match the current material
|
||||
uvCount = 0;
|
||||
vertCount = 0;
|
||||
colorCount = 0;
|
||||
for (j = 0; j < model->numMeshes; j++)
|
||||
{
|
||||
mesh_t *curMesh = &model->meshes[j];
|
||||
|
||||
if (curMesh->frames[0].material == curMat)
|
||||
{
|
||||
float *dest;
|
||||
float *src;
|
||||
char *destByte;
|
||||
char *srcByte;
|
||||
|
||||
M_Memcpy(&newMesh->uvs[uvCount],
|
||||
curMesh->uvs,
|
||||
sizeof(float)*2*curMesh->numTriangles*3);
|
||||
|
||||
/* if (node->material->lightmap)
|
||||
{
|
||||
M_Memcpy(&newMesh->lightuvs[uvCount],
|
||||
curMesh->lightuvs,
|
||||
sizeof(float)*2*curMesh->numTriangles*3);
|
||||
}*/
|
||||
uvCount += 2*curMesh->numTriangles*3;
|
||||
|
||||
dest = (float*)newMesh->frames[0].vertices;
|
||||
src = (float*)curMesh->frames[0].vertices;
|
||||
M_Memcpy(&dest[vertCount],
|
||||
src,
|
||||
sizeof(float)*3*curMesh->numTriangles*3);
|
||||
|
||||
dest = (float*)newMesh->frames[0].normals;
|
||||
src = (float*)curMesh->frames[0].normals;
|
||||
M_Memcpy(&dest[vertCount],
|
||||
src,
|
||||
sizeof(float)*3*curMesh->numTriangles*3);
|
||||
|
||||
/* if (!systemSucks)
|
||||
{
|
||||
dest = (float*)newMesh->frames[0].tangents;
|
||||
src = (float*)curMesh->frames[0].tangents;
|
||||
M_Memcpy(&dest[vertCount],
|
||||
src,
|
||||
sizeof(float)*3*curMesh->numTriangles*3);
|
||||
}*/
|
||||
|
||||
vertCount += 3 * curMesh->numTriangles * 3;
|
||||
|
||||
destByte = (char*)newMesh->frames[0].colors;
|
||||
srcByte = (char*)curMesh->frames[0].colors;
|
||||
|
||||
if (srcByte)
|
||||
{
|
||||
M_Memcpy(&destByte[colorCount],
|
||||
srcByte,
|
||||
sizeof(char)*4*curMesh->numTriangles*3);
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(&destByte[colorCount],
|
||||
255,
|
||||
sizeof(char)*4*curMesh->numTriangles*3);
|
||||
}
|
||||
|
||||
colorCount += 4 * curMesh->numTriangles * 3;
|
||||
}
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
CONS_Printf("Model::Optimize(): Model reduced from %d to %d meshes.\n", model->numMeshes, numMeshes);
|
||||
model->meshes = newMeshes;
|
||||
model->numMeshes = numMeshes;
|
||||
}
|
||||
|
||||
void GeneratePolygonNormals(model_t *model, int ztag)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < model->numMeshes; i++)
|
||||
{
|
||||
int j;
|
||||
mesh_t *mesh = &model->meshes[i];
|
||||
|
||||
if (!mesh->frames)
|
||||
continue;
|
||||
|
||||
for (j = 0; j < mesh->numFrames; j++)
|
||||
{
|
||||
int k;
|
||||
mdlframe_t *frame = &mesh->frames[j];
|
||||
const float *vertices = frame->vertices;
|
||||
vector_t *polyNormals;
|
||||
|
||||
frame->polyNormals = (vector_t*)Z_Malloc(sizeof(vector_t) * mesh->numTriangles, ztag, 0);
|
||||
|
||||
polyNormals = frame->polyNormals;
|
||||
|
||||
for (k = 0; k < mesh->numTriangles; k++)
|
||||
{
|
||||
// Vector::Normal(vertices, polyNormals);
|
||||
vertices += 3 * 3;
|
||||
polyNormals++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Reload
|
||||
//
|
||||
// Reload VBOs
|
||||
//
|
||||
#if 0
|
||||
static void Reload(void)
|
||||
{
|
||||
/* model_t *node;
|
||||
for (node = modelHead; node; node = node->next)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < node->numMeshes; i++)
|
||||
{
|
||||
mesh_t *mesh = &node->meshes[i];
|
||||
|
||||
if (mesh->frames)
|
||||
{
|
||||
int j;
|
||||
for (j = 0; j < mesh->numFrames; j++)
|
||||
CreateVBO(mesh, &mesh->frames[j]);
|
||||
}
|
||||
else if (mesh->tinyframes)
|
||||
{
|
||||
int j;
|
||||
for (j = 0; j < mesh->numFrames; j++)
|
||||
CreateVBO(mesh, &mesh->tinyframes[j]);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
#endif
|
||||
|
||||
void DeleteVBOs(model_t *model)
|
||||
{
|
||||
(void)model;
|
||||
/* for (int i = 0; i < model->numMeshes; i++)
|
||||
{
|
||||
mesh_t *mesh = &model->meshes[i];
|
||||
|
||||
if (mesh->frames)
|
||||
{
|
||||
for (int j = 0; j < mesh->numFrames; j++)
|
||||
{
|
||||
mdlframe_t *frame = &mesh->frames[j];
|
||||
if (!frame->vboID)
|
||||
continue;
|
||||
bglDeleteBuffers(1, &frame->vboID);
|
||||
frame->vboID = 0;
|
||||
}
|
||||
}
|
||||
else if (mesh->tinyframes)
|
||||
{
|
||||
for (int j = 0; j < mesh->numFrames; j++)
|
||||
{
|
||||
tinyframe_t *frame = &mesh->tinyframes[j];
|
||||
if (!frame->vboID)
|
||||
continue;
|
||||
bglDeleteBuffers(1, &frame->vboID);
|
||||
frame->vboID = 0;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
121
src/hardware/hw_model.h
Normal file
121
src/hardware/hw_model.h
Normal file
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
From the 'Wizard2' engine by Spaddlewit Inc. ( http://www.spaddlewit.com )
|
||||
An experimental work-in-progress.
|
||||
|
||||
Donated to Sonic Team Junior and adapted to work with
|
||||
Sonic Robo Blast 2. The license of this code matches whatever
|
||||
the licensing is for Sonic Robo Blast 2.
|
||||
*/
|
||||
|
||||
#ifndef _HW_MODEL_H_
|
||||
#define _HW_MODEL_H_
|
||||
|
||||
#include "../doomtype.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float x, y, z;
|
||||
} vector_t;
|
||||
|
||||
extern vector_t vectorXaxis;
|
||||
extern vector_t vectorYaxis;
|
||||
extern vector_t vectorZaxis;
|
||||
|
||||
void VectorRotate(vector_t *rotVec, const vector_t *axisVec, float angle);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float ambient[4], diffuse[4], specular[4], emissive[4];
|
||||
float shininess;
|
||||
boolean spheremap;
|
||||
// Texture::texture_t *texture;
|
||||
// Texture::texture_t *lightmap;
|
||||
} material_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
material_t *material; // Pointer to the allocated 'materials' list in model_t
|
||||
float *vertices;
|
||||
float *normals;
|
||||
float *tangents;
|
||||
char *colors;
|
||||
unsigned int vboID;
|
||||
vector_t *polyNormals;
|
||||
} mdlframe_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
material_t *material;
|
||||
short *vertices;
|
||||
char *normals;
|
||||
char *tangents;
|
||||
unsigned int vboID;
|
||||
} tinyframe_t;
|
||||
|
||||
// Equivalent to MD3's many 'surfaces'
|
||||
typedef struct mesh_s
|
||||
{
|
||||
int numVertices;
|
||||
int numTriangles;
|
||||
|
||||
float *uvs;
|
||||
float *lightuvs;
|
||||
|
||||
int numFrames;
|
||||
mdlframe_t *frames;
|
||||
tinyframe_t *tinyframes;
|
||||
unsigned short *indices;
|
||||
} mesh_t;
|
||||
|
||||
typedef struct tag_s
|
||||
{
|
||||
char name[64];
|
||||
// matrix_t transform;
|
||||
} tag_t;
|
||||
|
||||
#define MODEL_INTERPOLATION_FLAG "+i"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
INT32 frames[256];
|
||||
UINT8 numframes;
|
||||
boolean interpolate;
|
||||
} modelspr2frames_t;
|
||||
|
||||
typedef struct model_s
|
||||
{
|
||||
int maxNumFrames;
|
||||
|
||||
int numMaterials;
|
||||
material_t *materials;
|
||||
int numMeshes;
|
||||
mesh_t *meshes;
|
||||
int numTags;
|
||||
tag_t *tags;
|
||||
|
||||
char *mdlFilename;
|
||||
boolean unloaded;
|
||||
|
||||
char *framenames;
|
||||
boolean interpolate[256];
|
||||
modelspr2frames_t *spr2frames;
|
||||
} model_t;
|
||||
|
||||
extern int numModels;
|
||||
extern model_t *modelHead;
|
||||
|
||||
void HWR_ReloadModels(void);
|
||||
|
||||
tag_t *GetTagByName(model_t *model, char *name, int frame);
|
||||
model_t *LoadModel(const char *filename, int ztag);
|
||||
void UnloadModel(model_t *model);
|
||||
void Optimize(model_t *model);
|
||||
void LoadModelInterpolationSettings(model_t *model);
|
||||
void LoadModelSprite2(model_t *model);
|
||||
void GenerateVertexNormals(model_t *model);
|
||||
void GeneratePolygonNormals(model_t *model, int ztag);
|
||||
void CreateVBOTiny(mesh_t *mesh, tinyframe_t *frame);
|
||||
void CreateVBO(mesh_t *mesh, mdlframe_t *frame);
|
||||
void DeleteVBOs(model_t *model);
|
||||
|
||||
#endif
|
|
@ -347,13 +347,6 @@ static INT32 WINAPI SetRes(viddef_t *lvid, vmode_t *pcurrentmode)
|
|||
if (strstr(renderer, "810")) oglflags |= GLF_NOZBUFREAD;
|
||||
DBG_Printf("oglflags : 0x%X\n", oglflags);
|
||||
|
||||
#ifdef USE_PALETTED_TEXTURE
|
||||
if (isExtAvailable("GL_EXT_paletted_texture",gl_extensions))
|
||||
glColorTableEXT = GetGLFunc("glColorTableEXT");
|
||||
else
|
||||
glColorTableEXT = NULL;
|
||||
#endif
|
||||
|
||||
#ifdef USE_WGL_SWAP
|
||||
if (isExtAvailable("WGL_EXT_swap_control",gl_extensions))
|
||||
wglSwapIntervalEXT = GetGLFunc("wglSwapIntervalEXT");
|
||||
|
@ -582,19 +575,8 @@ EXPORT void HWRAPI(SetPalette) (RGBA_t *pal, RGBA_t *gamma)
|
|||
myPaletteData[i].s.blue = (UINT8)MIN((pal[i].s.blue*gamma->s.blue)/127, 255);
|
||||
myPaletteData[i].s.alpha = pal[i].s.alpha;
|
||||
}
|
||||
#ifdef USE_PALETTED_TEXTURE
|
||||
if (glColorTableEXT)
|
||||
{
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
palette_tex[3*i+0] = pal[i].s.red;
|
||||
palette_tex[3*i+1] = pal[i].s.green;
|
||||
palette_tex[3*i+2] = pal[i].s.blue;
|
||||
}
|
||||
glColorTableEXT(GL_TEXTURE_2D, GL_RGB8, 256, GL_RGB, GL_UNSIGNED_BYTE, palette_tex);
|
||||
}
|
||||
#endif
|
||||
// on a chang<6E> de palette, il faut recharger toutes les textures
|
||||
|
||||
// on a palette change, you have to reload all of the textures
|
||||
Flush();
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -71,7 +71,6 @@ extern FILE *gllogstream;
|
|||
#endif
|
||||
|
||||
#ifndef DRIVER_STRING
|
||||
// #define USE_PALETTED_TEXTURE
|
||||
#define DRIVER_STRING "HWRAPI Init(): SRB2 OpenGL renderer" // Tails
|
||||
#endif
|
||||
|
||||
|
@ -89,10 +88,6 @@ int SetupPixelFormat(INT32 WantColorBits, INT32 WantStencilBits, INT32 WantDepth
|
|||
void SetModelView(GLint w, GLint h);
|
||||
void SetStates(void);
|
||||
FUNCMATH float byteasfloat(UINT8 fbyte);
|
||||
#ifdef USE_PALETTED_TEXTURE
|
||||
extern PFNGLCOLORTABLEEXTPROC glColorTableEXT;
|
||||
extern GLubyte palette_tex[256*3];
|
||||
#endif
|
||||
|
||||
#ifndef GL_EXT_texture_filter_anisotropic
|
||||
#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
|
||||
|
@ -118,6 +113,10 @@ typedef void (APIENTRY * PFNglGetIntegerv) (GLenum pname, GLint *params);
|
|||
extern PFNglGetIntegerv pglGetIntegerv;
|
||||
typedef const GLubyte* (APIENTRY * PFNglGetString) (GLenum name);
|
||||
extern PFNglGetString pglGetString;
|
||||
#if 0
|
||||
typedef void (APIENTRY * PFNglEnableClientState) (GLenum cap); // redefined in r_opengl.c
|
||||
static PFNglEnableClientState pglEnableClientState;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// ==========================================================================
|
||||
|
|
52
src/hardware/r_opengl/r_vbo.h
Normal file
52
src/hardware/r_opengl/r_vbo.h
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
From the 'Wizard2' engine by Spaddlewit Inc. ( http://www.spaddlewit.com )
|
||||
An experimental work-in-progress.
|
||||
|
||||
Donated to Sonic Team Junior and adapted to work with
|
||||
Sonic Robo Blast 2. The license of this code matches whatever
|
||||
the licensing is for Sonic Robo Blast 2.
|
||||
*/
|
||||
#ifndef _R_VBO_H_
|
||||
#define _R_VBO_H_
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float x, y, z; // Vertex
|
||||
float nx, ny, nz; // Normal
|
||||
float s0, t0; // Texcoord0
|
||||
} vbo32_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float x, y, z; // Vertex
|
||||
float s0, t0; // Texcoord0
|
||||
unsigned char r, g, b, a; // Color
|
||||
float pad[2]; // Pad
|
||||
} vbo2d32_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float x, y; // Vertex
|
||||
float s0, t0; // Texcoord0
|
||||
} vbofont_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
short x, y, z; // Vertex
|
||||
char nx, ny, nz; // Normal
|
||||
char tanx, tany, tanz; // Tangent
|
||||
float s0, t0; // Texcoord0
|
||||
} vbotiny_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float x, y, z; // Vertex
|
||||
float nx, ny, nz; // Normal
|
||||
float s0, t0; // Texcoord0
|
||||
float s1, t1; // Texcoord1
|
||||
float s2, t2; // Texcoord2
|
||||
float tan0, tan1, tan2; // Tangent
|
||||
unsigned char r, g, b, a; // Color
|
||||
} vbo64_t;
|
||||
|
||||
#endif
|
230
src/hardware/u_list.c
Normal file
230
src/hardware/u_list.c
Normal file
|
@ -0,0 +1,230 @@
|
|||
/*
|
||||
From the 'Wizard2' engine by Spaddlewit Inc. ( http://www.spaddlewit.com )
|
||||
An experimental work-in-progress.
|
||||
|
||||
Donated to Sonic Team Junior and adapted to work with
|
||||
Sonic Robo Blast 2. The license of this code matches whatever
|
||||
the licensing is for Sonic Robo Blast 2.
|
||||
*/
|
||||
|
||||
#include "u_list.h"
|
||||
#include "../z_zone.h"
|
||||
|
||||
// Utility for managing
|
||||
// structures in a linked
|
||||
// list.
|
||||
//
|
||||
// Struct must have "next" and "prev" pointers
|
||||
// as its first two variables.
|
||||
//
|
||||
|
||||
//
|
||||
// ListAdd
|
||||
//
|
||||
// Adds an item to the list
|
||||
//
|
||||
void ListAdd(void *pItem, listitem_t **itemHead)
|
||||
{
|
||||
listitem_t *item = (listitem_t*)pItem;
|
||||
|
||||
if (*itemHead == NULL)
|
||||
{
|
||||
*itemHead = item;
|
||||
(*itemHead)->prev = (*itemHead)->next = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
listitem_t *tail;
|
||||
tail = *itemHead;
|
||||
|
||||
while (tail->next != NULL)
|
||||
tail = tail->next;
|
||||
|
||||
tail->next = item;
|
||||
|
||||
tail->next->prev = tail;
|
||||
|
||||
item->next = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// ListAddFront
|
||||
//
|
||||
// Adds an item to the front of the list
|
||||
// (This is much faster)
|
||||
//
|
||||
void ListAddFront(void *pItem, listitem_t **itemHead)
|
||||
{
|
||||
listitem_t *item = (listitem_t*)pItem;
|
||||
|
||||
if (*itemHead == NULL)
|
||||
{
|
||||
*itemHead = item;
|
||||
(*itemHead)->prev = (*itemHead)->next = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
(*itemHead)->prev = item;
|
||||
item->next = (*itemHead);
|
||||
item->prev = NULL;
|
||||
*itemHead = item;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// ListAddBefore
|
||||
//
|
||||
// Adds an item before the item specified in the list
|
||||
//
|
||||
void ListAddBefore(void *pItem, void *pSpot, listitem_t **itemHead)
|
||||
{
|
||||
listitem_t *item = (listitem_t*)pItem;
|
||||
listitem_t *spot = (listitem_t*)pSpot;
|
||||
|
||||
listitem_t *prev = spot->prev;
|
||||
|
||||
if (!prev)
|
||||
ListAddFront(pItem, itemHead);
|
||||
else
|
||||
{
|
||||
item->next = spot;
|
||||
spot->prev = item;
|
||||
item->prev = prev;
|
||||
prev->next = item;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// ListAddAfter
|
||||
//
|
||||
// Adds an item after the item specified in the list
|
||||
//
|
||||
void ListAddAfter(void *pItem, void *pSpot, listitem_t **itemHead)
|
||||
{
|
||||
listitem_t *item = (listitem_t*)pItem;
|
||||
listitem_t *spot = (listitem_t*)pSpot;
|
||||
|
||||
listitem_t *next = spot->next;
|
||||
|
||||
if (!next)
|
||||
ListAdd(pItem, itemHead);
|
||||
else
|
||||
{
|
||||
item->prev = spot;
|
||||
spot->next = item;
|
||||
item->next = next;
|
||||
next->prev = item;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// ListRemove
|
||||
//
|
||||
// Take an item out of the list and free its memory.
|
||||
//
|
||||
void ListRemove(void *pItem, listitem_t **itemHead)
|
||||
{
|
||||
listitem_t *item = (listitem_t*)pItem;
|
||||
|
||||
if (item == *itemHead) // Start of list
|
||||
{
|
||||
*itemHead = item->next;
|
||||
|
||||
if (*itemHead)
|
||||
(*itemHead)->prev = NULL;
|
||||
}
|
||||
else if (item->next == NULL) // end of list
|
||||
{
|
||||
item->prev->next = NULL;
|
||||
}
|
||||
else // Somewhere in between
|
||||
{
|
||||
item->prev->next = item->next;
|
||||
item->next->prev = item->prev;
|
||||
}
|
||||
|
||||
Z_Free (item);
|
||||
}
|
||||
|
||||
//
|
||||
// ListRemoveAll
|
||||
//
|
||||
// Removes all items from the list, freeing their memory.
|
||||
//
|
||||
void ListRemoveAll(listitem_t **itemHead)
|
||||
{
|
||||
listitem_t *item;
|
||||
listitem_t *next;
|
||||
for (item = *itemHead; item; item = next)
|
||||
{
|
||||
next = item->next;
|
||||
ListRemove(item, itemHead);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// ListRemoveNoFree
|
||||
//
|
||||
// Take an item out of the list, but don't free its memory.
|
||||
//
|
||||
void ListRemoveNoFree(void *pItem, listitem_t **itemHead)
|
||||
{
|
||||
listitem_t *item = (listitem_t*)pItem;
|
||||
|
||||
if (item == *itemHead) // Start of list
|
||||
{
|
||||
*itemHead = item->next;
|
||||
|
||||
if (*itemHead)
|
||||
(*itemHead)->prev = NULL;
|
||||
}
|
||||
else if (item->next == NULL) // end of list
|
||||
{
|
||||
item->prev->next = NULL;
|
||||
}
|
||||
else // Somewhere in between
|
||||
{
|
||||
item->prev->next = item->next;
|
||||
item->next->prev = item->prev;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// ListGetCount
|
||||
//
|
||||
// Counts the # of items in a list
|
||||
// Should not be used in performance-minded code
|
||||
//
|
||||
unsigned int ListGetCount(void *itemHead)
|
||||
{
|
||||
listitem_t *item = (listitem_t*)itemHead;
|
||||
|
||||
unsigned int count = 0;
|
||||
for (; item; item = item->next)
|
||||
count++;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
//
|
||||
// ListGetByIndex
|
||||
//
|
||||
// Gets an item in the list by its index
|
||||
// Should not be used in performance-minded code
|
||||
//
|
||||
listitem_t *ListGetByIndex(void *itemHead, unsigned int index)
|
||||
{
|
||||
listitem_t *head = (listitem_t*)itemHead;
|
||||
unsigned int count = 0;
|
||||
listitem_t *node;
|
||||
for (node = head; node; node = node->next)
|
||||
{
|
||||
if (count == index)
|
||||
return node;
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
29
src/hardware/u_list.h
Normal file
29
src/hardware/u_list.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
From the 'Wizard2' engine by Spaddlewit Inc. ( http://www.spaddlewit.com )
|
||||
An experimental work-in-progress.
|
||||
|
||||
Donated to Sonic Team Junior and adapted to work with
|
||||
Sonic Robo Blast 2. The license of this code matches whatever
|
||||
the licensing is for Sonic Robo Blast 2.
|
||||
*/
|
||||
|
||||
#ifndef _U_LIST_H_
|
||||
#define _U_LIST_H_
|
||||
|
||||
typedef struct listitem_s
|
||||
{
|
||||
struct listitem_s *next;
|
||||
struct listitem_s *prev;
|
||||
} listitem_t;
|
||||
|
||||
void ListAdd(void *pItem, listitem_t **itemHead);
|
||||
void ListAddFront(void *pItem, listitem_t **itemHead);
|
||||
void ListAddBefore(void *pItem, void *pSpot, listitem_t **itemHead);
|
||||
void ListAddAfter(void *pItem, void *pSpot, listitem_t **itemHead);
|
||||
void ListRemove(void *pItem, listitem_t **itemHead);
|
||||
void ListRemoveAll(listitem_t **itemHead);
|
||||
void ListRemoveNoFree(void *pItem, listitem_t **itemHead);
|
||||
unsigned int ListGetCount(void *itemHead);
|
||||
listitem_t *ListGetByIndex(void *itemHead, unsigned int index);
|
||||
|
||||
#endif
|
95
src/info.c
95
src/info.c
|
@ -808,7 +808,7 @@ state_t states[NUMSTATES] =
|
|||
{SPR_PLAY, SPR2_LIFE, 20, {NULL}, 0, 4, S_NULL}, // S_PLAY_ICON3
|
||||
|
||||
// Level end sign (uses player sprite)
|
||||
{SPR_PLAY, SPR2_SIGN, 1, {NULL}, 0, 24, S_PLAY_SIGN}, // S_PLAY_SIGN
|
||||
{SPR_PLAY, SPR2_SIGN|FF_PAPERSPRITE, -1, {NULL}, 0, 29, S_PLAY_SIGN}, // S_PLAY_SIGN
|
||||
|
||||
// NiGHTS Player, transforming
|
||||
{SPR_PLAY, SPR2_TRNS|FF_ANIMATE, 7, {NULL}, 0, 4, S_PLAY_NIGHTS_TRANS2}, // S_PLAY_NIGHTS_TRANS1
|
||||
|
@ -1911,59 +1911,18 @@ state_t states[NUMSTATES] =
|
|||
{SPR_BBLS, 3, 8, {A_BubbleCheck}, 0, 0, S_BUBBLES1}, // S_BUBBLES4
|
||||
|
||||
// Level End Sign
|
||||
{SPR_SIGN, 0, 1, {NULL}, 0, 0, S_SIGN2}, // S_SIGN1
|
||||
{SPR_SIGN, 1, 1, {NULL}, 0, 0, S_SIGN3}, // S_SIGN2
|
||||
{SPR_SIGN, 2, 1, {NULL}, 0, 0, S_SIGN4}, // S_SIGN3
|
||||
{SPR_SIGN, 5, 1, {NULL}, 0, 0, S_SIGN5}, // S_SIGN4
|
||||
{SPR_SIGN, 0, 1, {NULL}, 0, 0, S_SIGN6}, // S_SIGN5
|
||||
{SPR_SIGN, 1, 1, {NULL}, 0, 0, S_SIGN7}, // S_SIGN6
|
||||
{SPR_SIGN, 2, 1, {NULL}, 0, 0, S_SIGN8}, // S_SIGN7
|
||||
{SPR_SIGN, 3, 1, {NULL}, 0, 0, S_SIGN9}, // S_SIGN8
|
||||
{SPR_SIGN, 0, 1, {NULL}, 0, 0, S_SIGN10}, // S_SIGN9
|
||||
{SPR_SIGN, 1, 1, {NULL}, 0, 0, S_SIGN11}, // S_SIGN10
|
||||
{SPR_SIGN, 2, 1, {NULL}, 0, 0, S_SIGN12}, // S_SIGN11
|
||||
{SPR_SIGN, 4, 1, {NULL}, 0, 0, S_SIGN13}, // S_SIGN12
|
||||
{SPR_SIGN, 0, 1, {NULL}, 0, 0, S_SIGN14}, // S_SIGN13
|
||||
{SPR_SIGN, 1, 1, {NULL}, 0, 0, S_SIGN15}, // S_SIGN14
|
||||
{SPR_SIGN, 2, 1, {NULL}, 0, 0, S_SIGN16}, // S_SIGN15
|
||||
{SPR_SIGN, 3, 1, {NULL}, 0, 0, S_SIGN17}, // S_SIGN16
|
||||
{SPR_SIGN, 0, 1, {NULL}, 0, 0, S_SIGN18}, // S_SIGN17
|
||||
{SPR_SIGN, 1, 1, {NULL}, 0, 0, S_SIGN19}, // S_SIGN18
|
||||
{SPR_SIGN, 2, 1, {NULL}, 0, 0, S_SIGN20}, // S_SIGN19
|
||||
{SPR_SIGN, 6, 1, {NULL}, 0, 0, S_SIGN21}, // S_SIGN20
|
||||
{SPR_SIGN, 0, 1, {NULL}, 0, 0, S_SIGN22}, // S_SIGN21
|
||||
{SPR_SIGN, 1, 1, {NULL}, 0, 0, S_SIGN23}, // S_SIGN22
|
||||
{SPR_SIGN, 2, 1, {NULL}, 0, 0, S_SIGN24}, // S_SIGN23
|
||||
{SPR_SIGN, 3, 1, {NULL}, 0, 0, S_SIGN25}, // S_SIGN24
|
||||
{SPR_SIGN, 0, 1, {NULL}, 0, 0, S_SIGN26}, // S_SIGN25
|
||||
{SPR_SIGN, 1, 1, {NULL}, 0, 0, S_SIGN27}, // S_SIGN26
|
||||
{SPR_SIGN, 2, 1, {NULL}, 0, 0, S_SIGN28}, // S_SIGN27
|
||||
{SPR_SIGN, 5, 1, {NULL}, 0, 0, S_SIGN29}, // S_SIGN28
|
||||
{SPR_SIGN, 0, 1, {NULL}, 0, 0, S_SIGN30}, // S_SIGN29
|
||||
{SPR_SIGN, 1, 1, {NULL}, 0, 0, S_SIGN31}, // S_SIGN30
|
||||
{SPR_SIGN, 2, 1, {NULL}, 0, 0, S_SIGN32}, // S_SIGN31
|
||||
{SPR_SIGN, 3, 1, {NULL}, 0, 0, S_SIGN33}, // S_SIGN32
|
||||
{SPR_SIGN, 0, 1, {NULL}, 0, 0, S_SIGN34}, // S_SIGN33
|
||||
{SPR_SIGN, 1, 1, {NULL}, 0, 0, S_SIGN35}, // S_SIGN34
|
||||
{SPR_SIGN, 2, 1, {NULL}, 0, 0, S_SIGN36}, // S_SIGN35
|
||||
{SPR_SIGN, 4, 1, {NULL}, 0, 0, S_SIGN37}, // S_SIGN36
|
||||
{SPR_SIGN, 0, 1, {NULL}, 0, 0, S_SIGN38}, // S_SIGN37
|
||||
{SPR_SIGN, 1, 1, {NULL}, 0, 0, S_SIGN39}, // S_SIGN38
|
||||
{SPR_SIGN, 2, 1, {NULL}, 0, 0, S_SIGN40}, // S_SIGN39
|
||||
{SPR_SIGN, 3, 1, {NULL}, 0, 0, S_SIGN41}, // S_SIGN40
|
||||
{SPR_SIGN, 0, 1, {NULL}, 0, 0, S_SIGN42}, // S_SIGN41
|
||||
{SPR_SIGN, 1, 1, {NULL}, 0, 0, S_SIGN43}, // S_SIGN42
|
||||
{SPR_SIGN, 2, 1, {NULL}, 0, 0, S_SIGN44}, // S_SIGN43
|
||||
{SPR_SIGN, 6, 1, {NULL}, 0, 0, S_SIGN45}, // S_SIGN44
|
||||
{SPR_SIGN, 0, 1, {NULL}, 0, 0, S_SIGN46}, // S_SIGN45
|
||||
{SPR_SIGN, 1, 1, {NULL}, 0, 0, S_SIGN47}, // S_SIGN46
|
||||
{SPR_SIGN, 2, 1, {NULL}, 0, 0, S_SIGN48}, // S_SIGN47
|
||||
{SPR_SIGN, 3, 1, {NULL}, 0, 0, S_SIGN49}, // S_SIGN48
|
||||
{SPR_SIGN, 0, 1, {NULL}, 0, 0, S_SIGN50}, // S_SIGN49
|
||||
{SPR_SIGN, 1, 1, {NULL}, 0, 0, S_SIGN51}, // S_SIGN50
|
||||
{SPR_SIGN, 2, 1, {NULL}, 0, 0, S_SIGN53}, // S_SIGN51
|
||||
{SPR_SIGN, 3, -1, {NULL}, 0, 0, S_NULL}, // S_SIGN52 Eggman
|
||||
{SPR_SIGN, 7, -1, {A_SignPlayer}, 0, 0, S_NULL}, // S_SIGN53 Blank
|
||||
{SPR_SIGN, 0, -1, {A_SignPlayer}, -3, 0, S_NULL}, // S_SIGN
|
||||
{SPR_SIGN, 0, 1, {A_SignSpin}, 30, 0, S_SIGNSPIN2}, // S_SIGNSPIN1
|
||||
{SPR_SIGN, 0, 0, {A_Repeat}, 4, S_SIGNSPIN1, S_SIGNSPIN3}, // S_SIGNSPIN2
|
||||
{SPR_SIGN, 0, 0, {A_SignPlayer}, -2, 0, S_SIGNSPIN4}, // S_SIGNSPIN3
|
||||
{SPR_SIGN, 0, 1, {A_SignSpin}, 30, 0, S_SIGNSPIN5}, // S_SIGNSPIN4
|
||||
{SPR_SIGN, 0, 0, {A_Repeat}, 4, S_SIGNSPIN4, S_SIGNSPIN6}, // S_SIGNSPIN5
|
||||
{SPR_SIGN, 0, 0, {A_SignPlayer}, -3, 0, S_SIGNSPIN1}, // S_SIGNSPIN6
|
||||
{SPR_SIGN, 0, 1, {A_SignPlayer}, -1, 0, S_SIGNSLOW}, // S_SIGNPLAYER
|
||||
{SPR_SIGN, 0, 1, {A_SignSpin}, 30, 0, S_SIGNSLOW}, // S_SIGNSLOW
|
||||
{SPR_SIGN, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SIGNSTOP
|
||||
{SPR_SIGN, FF_PAPERSPRITE|2, -1, {NULL}, 0, 0, S_NULL}, // S_SIGNBOARD
|
||||
{SPR_SIGN, FF_PAPERSPRITE|1, -1, {NULL}, 0, 29, S_NULL}, // S_EGGMANSIGN
|
||||
|
||||
// Spike Ball
|
||||
{SPR_SPIK, 0, 1, {NULL}, 0, 0, S_SPIKEBALL2}, // S_SPIKEBALL1
|
||||
|
@ -5280,7 +5239,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
100, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOGRAVITY|MF_NOCLIPTHING|MF_NOBLOCKMAP|MF_RUNSPAWNFUNC, // flags
|
||||
MF_NOGRAVITY|MF_NOCLIPTHING|MF_NOBLOCKMAP|MF_RUNSPAWNFUNC|MF_SCENERY, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
|
@ -5307,7 +5266,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
100, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOGRAVITY|MF_NOCLIPTHING|MF_NOBLOCKMAP|MF_RUNSPAWNFUNC, // flags
|
||||
MF_NOGRAVITY|MF_NOCLIPTHING|MF_NOBLOCKMAP|MF_RUNSPAWNFUNC|MF_SCENERY, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
|
@ -7818,29 +7777,29 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
|
||||
{ // MT_SIGN
|
||||
501, // doomednum
|
||||
S_SIGN52, // spawnstate
|
||||
S_SIGN, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_PLAY_SIGN, // seestate
|
||||
sfx_lvpass, // seesound
|
||||
8, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
S_SIGNPLAYER, // painstate
|
||||
MT_SPARK, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_EGGMANSIGN, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_SIGNSTOP, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
8, // speed
|
||||
8*FRACUNIT, // radius
|
||||
36*FRACUNIT, // radius
|
||||
32*FRACUNIT, // height
|
||||
0, // display offset
|
||||
16, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOCLIP|MF_SCENERY, // flags
|
||||
S_NULL // raisestate
|
||||
MF_NOCLIP|MF_SCENERY|MF_BOUNCE|MF_RUNSPAWNFUNC, // flags
|
||||
S_SIGNBOARD // raisestate
|
||||
},
|
||||
|
||||
{ // MT_SPIKEBALL
|
||||
|
@ -13286,7 +13245,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
3200*FRACUNIT, // speed
|
||||
30*FRACUNIT, // radius
|
||||
32*FRACUNIT, // height
|
||||
1, // display offset
|
||||
|
@ -13374,7 +13333,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
100, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_SPAWNCEILING, // flags
|
||||
MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_SPAWNCEILING|MF_SCENERY, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
|
@ -19024,7 +18983,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL, // deathstate
|
||||
S_PUMA_DOWN3, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
2000*FRACUNIT, // speed
|
||||
8*FRACUNIT, // radius
|
||||
16*FRACUNIT, // height
|
||||
0, // display offset
|
||||
|
@ -19058,7 +19017,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
100, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY, // flags
|
||||
MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
|
|
66
src/info.h
66
src/info.h
|
@ -63,6 +63,7 @@ void A_FishJump(); // Fish Jump
|
|||
void A_ThrownRing(); // Sparkle trail for red ring
|
||||
void A_SetSolidSteam();
|
||||
void A_UnsetSolidSteam();
|
||||
void A_SignSpin();
|
||||
void A_SignPlayer();
|
||||
void A_OverlayThink();
|
||||
void A_JetChase();
|
||||
|
@ -2040,59 +2041,18 @@ typedef enum state
|
|||
S_BUBBLES4,
|
||||
|
||||
// Level End Sign
|
||||
S_SIGN1,
|
||||
S_SIGN2,
|
||||
S_SIGN3,
|
||||
S_SIGN4,
|
||||
S_SIGN5,
|
||||
S_SIGN6,
|
||||
S_SIGN7,
|
||||
S_SIGN8,
|
||||
S_SIGN9,
|
||||
S_SIGN10,
|
||||
S_SIGN11,
|
||||
S_SIGN12,
|
||||
S_SIGN13,
|
||||
S_SIGN14,
|
||||
S_SIGN15,
|
||||
S_SIGN16,
|
||||
S_SIGN17,
|
||||
S_SIGN18,
|
||||
S_SIGN19,
|
||||
S_SIGN20,
|
||||
S_SIGN21,
|
||||
S_SIGN22,
|
||||
S_SIGN23,
|
||||
S_SIGN24,
|
||||
S_SIGN25,
|
||||
S_SIGN26,
|
||||
S_SIGN27,
|
||||
S_SIGN28,
|
||||
S_SIGN29,
|
||||
S_SIGN30,
|
||||
S_SIGN31,
|
||||
S_SIGN32,
|
||||
S_SIGN33,
|
||||
S_SIGN34,
|
||||
S_SIGN35,
|
||||
S_SIGN36,
|
||||
S_SIGN37,
|
||||
S_SIGN38,
|
||||
S_SIGN39,
|
||||
S_SIGN40,
|
||||
S_SIGN41,
|
||||
S_SIGN42,
|
||||
S_SIGN43,
|
||||
S_SIGN44,
|
||||
S_SIGN45,
|
||||
S_SIGN46,
|
||||
S_SIGN47,
|
||||
S_SIGN48,
|
||||
S_SIGN49,
|
||||
S_SIGN50,
|
||||
S_SIGN51,
|
||||
S_SIGN52, // Eggman
|
||||
S_SIGN53,
|
||||
S_SIGN,
|
||||
S_SIGNSPIN1,
|
||||
S_SIGNSPIN2,
|
||||
S_SIGNSPIN3,
|
||||
S_SIGNSPIN4,
|
||||
S_SIGNSPIN5,
|
||||
S_SIGNSPIN6,
|
||||
S_SIGNPLAYER,
|
||||
S_SIGNSLOW,
|
||||
S_SIGNSTOP,
|
||||
S_SIGNBOARD,
|
||||
S_EGGMANSIGN,
|
||||
|
||||
// Spike Ball
|
||||
S_SPIKEBALL1,
|
||||
|
|
239
src/m_fixed.c
239
src/m_fixed.c
|
@ -56,7 +56,7 @@ fixed_t FixedDiv2(fixed_t a, fixed_t b)
|
|||
if (b == 0)
|
||||
I_Error("FixedDiv: divide by zero");
|
||||
|
||||
ret = (((INT64)a * FRACUNIT) ) / b;
|
||||
ret = (((INT64)a * FRACUNIT)) / b;
|
||||
|
||||
if ((ret > INT32_MAX) || (ret < INT32_MIN))
|
||||
I_Error("FixedDiv: divide by zero");
|
||||
|
@ -117,7 +117,7 @@ fixed_t FixedHypot(fixed_t x, fixed_t y)
|
|||
yx = FixedDiv(y, x); // (x/y)
|
||||
}
|
||||
yx2 = FixedMul(yx, yx); // (x/y)^2
|
||||
yx1 = FixedSqrt(1*FRACUNIT + yx2); // (1 + (x/y)^2)^1/2
|
||||
yx1 = FixedSqrt(1 * FRACUNIT + yx2); // (1 + (x/y)^2)^1/2
|
||||
return FixedMul(ax, yx1); // |x|*((1 + (x/y)^2)^1/2)
|
||||
}
|
||||
|
||||
|
@ -191,8 +191,8 @@ vector2_t *FV2_Divide(vector2_t *a_i, fixed_t a_c)
|
|||
// Vector Complex Math
|
||||
vector2_t *FV2_Midpoint(const vector2_t *a_1, const vector2_t *a_2, vector2_t *a_o)
|
||||
{
|
||||
a_o->x = FixedDiv(a_2->x - a_1->x, 2*FRACUNIT);
|
||||
a_o->y = FixedDiv(a_2->y - a_1->y, 2*FRACUNIT);
|
||||
a_o->x = FixedDiv(a_2->x - a_1->x, 2 * FRACUNIT);
|
||||
a_o->y = FixedDiv(a_2->y - a_1->y, 2 * FRACUNIT);
|
||||
a_o->x = a_1->x + a_o->x;
|
||||
a_o->y = a_1->y + a_o->y;
|
||||
return a_o;
|
||||
|
@ -200,16 +200,16 @@ vector2_t *FV2_Midpoint(const vector2_t *a_1, const vector2_t *a_2, vector2_t *a
|
|||
|
||||
fixed_t FV2_Distance(const vector2_t *p1, const vector2_t *p2)
|
||||
{
|
||||
fixed_t xs = FixedMul(p2->x-p1->x,p2->x-p1->x);
|
||||
fixed_t ys = FixedMul(p2->y-p1->y,p2->y-p1->y);
|
||||
return FixedSqrt(xs+ys);
|
||||
fixed_t xs = FixedMul(p2->x - p1->x, p2->x - p1->x);
|
||||
fixed_t ys = FixedMul(p2->y - p1->y, p2->y - p1->y);
|
||||
return FixedSqrt(xs + ys);
|
||||
}
|
||||
|
||||
fixed_t FV2_Magnitude(const vector2_t *a_normal)
|
||||
{
|
||||
fixed_t xs = FixedMul(a_normal->x,a_normal->x);
|
||||
fixed_t ys = FixedMul(a_normal->y,a_normal->y);
|
||||
return FixedSqrt(xs+ys);
|
||||
fixed_t xs = FixedMul(a_normal->x, a_normal->x);
|
||||
fixed_t ys = FixedMul(a_normal->y, a_normal->y);
|
||||
return FixedSqrt(xs + ys);
|
||||
}
|
||||
|
||||
// Also returns the magnitude
|
||||
|
@ -240,7 +240,7 @@ vector2_t *FV2_Negate(vector2_t *a_1)
|
|||
|
||||
boolean FV2_Equal(const vector2_t *a_1, const vector2_t *a_2)
|
||||
{
|
||||
fixed_t Epsilon = FRACUNIT/FRACUNIT;
|
||||
fixed_t Epsilon = FRACUNIT / FRACUNIT;
|
||||
|
||||
if ((abs(a_2->x - a_1->x) > Epsilon) ||
|
||||
(abs(a_2->y - a_1->y) > Epsilon))
|
||||
|
@ -261,7 +261,7 @@ fixed_t FV2_Dot(const vector2_t *a_1, const vector2_t *a_2)
|
|||
//
|
||||
// Given two points, create a vector between them.
|
||||
//
|
||||
vector2_t *FV2_Point2Vec (const vector2_t *point1, const vector2_t *point2, vector2_t *a_o)
|
||||
vector2_t *FV2_Point2Vec(const vector2_t *point1, const vector2_t *point2, vector2_t *a_o)
|
||||
{
|
||||
a_o->x = point1->x - point2->x;
|
||||
a_o->y = point1->y - point2->y;
|
||||
|
@ -344,9 +344,9 @@ vector3_t *FV3_Divide(vector3_t *a_i, fixed_t a_c)
|
|||
// Vector Complex Math
|
||||
vector3_t *FV3_Midpoint(const vector3_t *a_1, const vector3_t *a_2, vector3_t *a_o)
|
||||
{
|
||||
a_o->x = FixedDiv(a_2->x - a_1->x, 2*FRACUNIT);
|
||||
a_o->y = FixedDiv(a_2->y - a_1->y, 2*FRACUNIT);
|
||||
a_o->z = FixedDiv(a_2->z - a_1->z, 2*FRACUNIT);
|
||||
a_o->x = FixedDiv(a_2->x - a_1->x, 2 * FRACUNIT);
|
||||
a_o->y = FixedDiv(a_2->y - a_1->y, 2 * FRACUNIT);
|
||||
a_o->z = FixedDiv(a_2->z - a_1->z, 2 * FRACUNIT);
|
||||
a_o->x = a_1->x + a_o->x;
|
||||
a_o->y = a_1->y + a_o->y;
|
||||
a_o->z = a_1->z + a_o->z;
|
||||
|
@ -355,18 +355,18 @@ vector3_t *FV3_Midpoint(const vector3_t *a_1, const vector3_t *a_2, vector3_t *a
|
|||
|
||||
fixed_t FV3_Distance(const vector3_t *p1, const vector3_t *p2)
|
||||
{
|
||||
fixed_t xs = FixedMul(p2->x-p1->x,p2->x-p1->x);
|
||||
fixed_t ys = FixedMul(p2->y-p1->y,p2->y-p1->y);
|
||||
fixed_t zs = FixedMul(p2->z-p1->z,p2->z-p1->z);
|
||||
return FixedSqrt(xs+ys+zs);
|
||||
fixed_t xs = FixedMul(p2->x - p1->x, p2->x - p1->x);
|
||||
fixed_t ys = FixedMul(p2->y - p1->y, p2->y - p1->y);
|
||||
fixed_t zs = FixedMul(p2->z - p1->z, p2->z - p1->z);
|
||||
return FixedSqrt(xs + ys + zs);
|
||||
}
|
||||
|
||||
fixed_t FV3_Magnitude(const vector3_t *a_normal)
|
||||
{
|
||||
fixed_t xs = FixedMul(a_normal->x,a_normal->x);
|
||||
fixed_t ys = FixedMul(a_normal->y,a_normal->y);
|
||||
fixed_t zs = FixedMul(a_normal->z,a_normal->z);
|
||||
return FixedSqrt(xs+ys+zs);
|
||||
fixed_t xs = FixedMul(a_normal->x, a_normal->x);
|
||||
fixed_t ys = FixedMul(a_normal->y, a_normal->y);
|
||||
fixed_t zs = FixedMul(a_normal->z, a_normal->z);
|
||||
return FixedSqrt(xs + ys + zs);
|
||||
}
|
||||
|
||||
// Also returns the magnitude
|
||||
|
@ -399,7 +399,7 @@ vector3_t *FV3_Negate(vector3_t *a_1)
|
|||
|
||||
boolean FV3_Equal(const vector3_t *a_1, const vector3_t *a_2)
|
||||
{
|
||||
fixed_t Epsilon = FRACUNIT/FRACUNIT;
|
||||
fixed_t Epsilon = FRACUNIT / FRACUNIT;
|
||||
|
||||
if ((abs(a_2->x - a_1->x) > Epsilon) ||
|
||||
(abs(a_2->y - a_1->y) > Epsilon) ||
|
||||
|
@ -458,6 +458,20 @@ vector3_t *FV3_ClosestPointOnLine(const vector3_t *Line, const vector3_t *p, vec
|
|||
return FV3_AddEx(&Line[0], &V, out);
|
||||
}
|
||||
|
||||
//
|
||||
// ClosestPointOnVector
|
||||
//
|
||||
// Similar to ClosestPointOnLine, but uses a vector instead of two points.
|
||||
//
|
||||
void FV3_ClosestPointOnVector(const vector3_t *dir, const vector3_t *p, vector3_t *out)
|
||||
{
|
||||
fixed_t t = FV3_Dot(dir, p);
|
||||
|
||||
// Return the point on the line closest
|
||||
FV3_MulEx(dir, t, out);
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// ClosestPointOnTriangle
|
||||
//
|
||||
|
@ -465,7 +479,7 @@ vector3_t *FV3_ClosestPointOnLine(const vector3_t *Line, const vector3_t *p, vec
|
|||
// the closest point on the edge of
|
||||
// the triangle is returned.
|
||||
//
|
||||
void FV3_ClosestPointOnTriangle (const vector3_t *tri, const vector3_t *point, vector3_t *result)
|
||||
void FV3_ClosestPointOnTriangle(const vector3_t *tri, const vector3_t *point, vector3_t *result)
|
||||
{
|
||||
UINT8 i;
|
||||
fixed_t dist, closestdist;
|
||||
|
@ -506,7 +520,7 @@ void FV3_ClosestPointOnTriangle (const vector3_t *tri, const vector3_t *point, v
|
|||
//
|
||||
// Given two points, create a vector between them.
|
||||
//
|
||||
vector3_t *FV3_Point2Vec (const vector3_t *point1, const vector3_t *point2, vector3_t *a_o)
|
||||
vector3_t *FV3_Point2Vec(const vector3_t *point1, const vector3_t *point2, vector3_t *a_o)
|
||||
{
|
||||
a_o->x = point1->x - point2->x;
|
||||
a_o->y = point1->y - point2->y;
|
||||
|
@ -519,7 +533,7 @@ vector3_t *FV3_Point2Vec (const vector3_t *point1, const vector3_t *point2, vect
|
|||
//
|
||||
// Calculates the normal of a polygon.
|
||||
//
|
||||
void FV3_Normal (const vector3_t *a_triangle, vector3_t *a_normal)
|
||||
fixed_t FV3_Normal(const vector3_t *a_triangle, vector3_t *a_normal)
|
||||
{
|
||||
vector3_t a_1;
|
||||
vector3_t a_2;
|
||||
|
@ -529,7 +543,28 @@ void FV3_Normal (const vector3_t *a_triangle, vector3_t *a_normal)
|
|||
|
||||
FV3_Cross(&a_1, &a_2, a_normal);
|
||||
|
||||
FV3_NormalizeEx(a_normal, a_normal);
|
||||
return FV3_NormalizeEx(a_normal, a_normal);
|
||||
}
|
||||
|
||||
//
|
||||
// Strength
|
||||
//
|
||||
// Measures the 'strength' of a vector in a particular direction.
|
||||
//
|
||||
fixed_t FV3_Strength(const vector3_t *a_1, const vector3_t *dir)
|
||||
{
|
||||
vector3_t normal;
|
||||
fixed_t dist = FV3_NormalizeEx(a_1, &normal);
|
||||
fixed_t dot = FV3_Dot(&normal, dir);
|
||||
|
||||
FV3_ClosestPointOnVector(dir, a_1, &normal);
|
||||
|
||||
dist = FV3_Magnitude(&normal);
|
||||
|
||||
if (dot < 0) // Not facing same direction, so negate result.
|
||||
dist = -dist;
|
||||
|
||||
return dist;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -550,11 +585,11 @@ boolean FV3_IntersectedPlane(const vector3_t *a_triangle, const vector3_t *a_lin
|
|||
|
||||
*originDistance = FV3_PlaneDistance(a_normal, &a_triangle[0]);
|
||||
|
||||
distance1 = (FixedMul(a_normal->x, a_line[0].x) + FixedMul(a_normal->y, a_line[0].y)
|
||||
+ FixedMul(a_normal->z, a_line[0].z)) + *originDistance;
|
||||
distance1 = (FixedMul(a_normal->x, a_line[0].x) + FixedMul(a_normal->y, a_line[0].y)
|
||||
+ FixedMul(a_normal->z, a_line[0].z)) + *originDistance;
|
||||
|
||||
distance2 = (FixedMul(a_normal->x, a_line[1].x) + FixedMul(a_normal->y, a_line[1].y)
|
||||
+ FixedMul(a_normal->z, a_line[1].z)) + *originDistance;
|
||||
distance2 = (FixedMul(a_normal->x, a_line[1].x) + FixedMul(a_normal->y, a_line[1].y)
|
||||
+ FixedMul(a_normal->z, a_line[1].z)) + *originDistance;
|
||||
|
||||
// Positive or zero number means no intersection
|
||||
if (FixedMul(distance1, distance2) >= 0)
|
||||
|
@ -575,8 +610,8 @@ boolean FV3_IntersectedPlane(const vector3_t *a_triangle, const vector3_t *a_lin
|
|||
fixed_t FV3_PlaneIntersection(const vector3_t *pOrigin, const vector3_t *pNormal, const vector3_t *rOrigin, const vector3_t *rVector)
|
||||
{
|
||||
fixed_t d = -(FV3_Dot(pNormal, pOrigin));
|
||||
fixed_t number = FV3_Dot(pNormal,rOrigin) + d;
|
||||
fixed_t denom = FV3_Dot(pNormal,rVector);
|
||||
fixed_t number = FV3_Dot(pNormal, rOrigin) + d;
|
||||
fixed_t denom = FV3_Dot(pNormal, rVector);
|
||||
return -FixedDiv(number, denom);
|
||||
}
|
||||
|
||||
|
@ -597,11 +632,11 @@ fixed_t FV3_IntersectRaySphere(const vector3_t *rO, const vector3_t *rV, const v
|
|||
|
||||
c = FV3_Magnitude(&Q);
|
||||
v = FV3_Dot(&Q, rV);
|
||||
d = FixedMul(sR, sR) - (FixedMul(c,c) - FixedMul(v,v));
|
||||
d = FixedMul(sR, sR) - (FixedMul(c, c) - FixedMul(v, v));
|
||||
|
||||
// If there was no intersection, return -1
|
||||
if (d < 0*FRACUNIT)
|
||||
return (-1*FRACUNIT);
|
||||
if (d < 0 * FRACUNIT)
|
||||
return (-1 * FRACUNIT);
|
||||
|
||||
// Return the distance to the [first] intersecting point
|
||||
return (v - FixedSqrt(d));
|
||||
|
@ -629,9 +664,9 @@ vector3_t *FV3_IntersectionPoint(const vector3_t *vNormal, const vector3_t *vLin
|
|||
// Here I just chose a arbitrary point as the point to find that distance. You notice we negate that
|
||||
// distance. We negate the distance because we want to eventually go BACKWARDS from our point to the plane.
|
||||
// By doing this is will basically bring us back to the plane to find our intersection point.
|
||||
Numerator = - (FixedMul(vNormal->x, vLine[0].x) + // Use the plane equation with the normal and the line
|
||||
FixedMul(vNormal->y, vLine[0].y) +
|
||||
FixedMul(vNormal->z, vLine[0].z) + distance);
|
||||
Numerator = -(FixedMul(vNormal->x, vLine[0].x) + // Use the plane equation with the normal and the line
|
||||
FixedMul(vNormal->y, vLine[0].y) +
|
||||
FixedMul(vNormal->z, vLine[0].z) + distance);
|
||||
|
||||
// 3) If we take the dot product between our line vector and the normal of the polygon,
|
||||
// this will give us the cosine of the angle between the 2 (since they are both normalized - length 1).
|
||||
|
@ -643,7 +678,7 @@ vector3_t *FV3_IntersectionPoint(const vector3_t *vNormal, const vector3_t *vLin
|
|||
// on the plane (the normal is perpendicular to the line - (Normal.Vector = 0)).
|
||||
// In this case, we should just return any point on the line.
|
||||
|
||||
if( Denominator == 0*FRACUNIT) // Check so we don't divide by zero
|
||||
if (Denominator == 0 * FRACUNIT) // Check so we don't divide by zero
|
||||
{
|
||||
ReturnVec->x = vLine[0].x;
|
||||
ReturnVec->y = vLine[0].y;
|
||||
|
@ -686,8 +721,8 @@ vector3_t *FV3_IntersectionPoint(const vector3_t *vNormal, const vector3_t *vLin
|
|||
//
|
||||
UINT8 FV3_PointOnLineSide(const vector3_t *point, const vector3_t *line)
|
||||
{
|
||||
fixed_t s1 = FixedMul((point->y - line[0].y),(line[1].x - line[0].x));
|
||||
fixed_t s2 = FixedMul((point->x - line[0].x),(line[1].y - line[0].y));
|
||||
fixed_t s1 = FixedMul((point->y - line[0].y), (line[1].x - line[0].x));
|
||||
fixed_t s2 = FixedMul((point->x - line[0].x), (line[1].y - line[0].y));
|
||||
return (UINT8)(s1 - s2 < 0);
|
||||
}
|
||||
|
||||
|
@ -752,7 +787,7 @@ void FM_CreateObjectMatrix(matrix_t *matrix, fixed_t x, fixed_t y, fixed_t z, fi
|
|||
matrix->m[0] = upcross.x;
|
||||
matrix->m[1] = upcross.y;
|
||||
matrix->m[2] = upcross.z;
|
||||
matrix->m[3] = 0*FRACUNIT;
|
||||
matrix->m[3] = 0 * FRACUNIT;
|
||||
|
||||
matrix->m[4] = upx;
|
||||
matrix->m[5] = upy;
|
||||
|
@ -764,9 +799,9 @@ void FM_CreateObjectMatrix(matrix_t *matrix, fixed_t x, fixed_t y, fixed_t z, fi
|
|||
matrix->m[10] = anglez;
|
||||
matrix->m[11] = 0;
|
||||
|
||||
matrix->m[12] = x - FixedMul(upx,radius);
|
||||
matrix->m[13] = y - FixedMul(upy,radius);
|
||||
matrix->m[14] = z - FixedMul(upz,radius);
|
||||
matrix->m[12] = x - FixedMul(upx, radius);
|
||||
matrix->m[13] = y - FixedMul(upy, radius);
|
||||
matrix->m[14] = z - FixedMul(upz, radius);
|
||||
matrix->m[15] = FRACUNIT;
|
||||
}
|
||||
|
||||
|
@ -778,20 +813,20 @@ void FM_CreateObjectMatrix(matrix_t *matrix, fixed_t x, fixed_t y, fixed_t z, fi
|
|||
void FM_MultMatrixVec3(const matrix_t *matrix, const vector3_t *vec, vector3_t *out)
|
||||
{
|
||||
#define M(row,col) matrix->m[col * 4 + row]
|
||||
out->x = FixedMul(vec->x,M(0, 0))
|
||||
+ FixedMul(vec->y,M(0, 1))
|
||||
+ FixedMul(vec->z,M(0, 2))
|
||||
+ M(0, 3);
|
||||
out->x = FixedMul(vec->x, M(0, 0))
|
||||
+ FixedMul(vec->y, M(0, 1))
|
||||
+ FixedMul(vec->z, M(0, 2))
|
||||
+ M(0, 3);
|
||||
|
||||
out->y = FixedMul(vec->x,M(1, 0))
|
||||
+ FixedMul(vec->y,M(1, 1))
|
||||
+ FixedMul(vec->z,M(1, 2))
|
||||
+ M(1, 3);
|
||||
out->y = FixedMul(vec->x, M(1, 0))
|
||||
+ FixedMul(vec->y, M(1, 1))
|
||||
+ FixedMul(vec->z, M(1, 2))
|
||||
+ M(1, 3);
|
||||
|
||||
out->z = FixedMul(vec->x,M(2, 0))
|
||||
+ FixedMul(vec->y,M(2, 1))
|
||||
+ FixedMul(vec->z,M(2, 2))
|
||||
+ M(2, 3);
|
||||
out->z = FixedMul(vec->x, M(2, 0))
|
||||
+ FixedMul(vec->y, M(2, 1))
|
||||
+ FixedMul(vec->z, M(2, 2))
|
||||
+ M(2, 3);
|
||||
#undef M
|
||||
}
|
||||
|
||||
|
@ -811,7 +846,7 @@ void FM_MultMatrix(matrix_t *dest, const matrix_t *multme)
|
|||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
for (j = 0; j < 4; j++)
|
||||
R(i, j) = FixedMul(D(i, 0),M(0, j)) + FixedMul(D(i, 1),M(1, j)) + FixedMul(D(i, 2),M(2, j)) + FixedMul(D(i, 3),M(3, j));
|
||||
R(i, j) = FixedMul(D(i, 0), M(0, j)) + FixedMul(D(i, 1), M(1, j)) + FixedMul(D(i, 2), M(2, j)) + FixedMul(D(i, 3), M(3, j));
|
||||
}
|
||||
|
||||
M_Memcpy(dest, &result, sizeof(matrix_t));
|
||||
|
@ -869,8 +904,8 @@ void FM_Scale(matrix_t *dest, fixed_t x, fixed_t y, fixed_t z)
|
|||
|
||||
static inline void M_print(INT64 a)
|
||||
{
|
||||
const fixed_t w = (a>>FRACBITS);
|
||||
fixed_t f = a%FRACUNIT;
|
||||
const fixed_t w = (a >> FRACBITS);
|
||||
fixed_t f = a % FRACUNIT;
|
||||
fixed_t d = FRACUNIT;
|
||||
|
||||
if (f == 0)
|
||||
|
@ -878,7 +913,7 @@ static inline void M_print(INT64 a)
|
|||
printf("%d", (fixed_t)w);
|
||||
return;
|
||||
}
|
||||
else while (f != 1 && f/2 == f>>1)
|
||||
else while (f != 1 && f / 2 == f >> 1)
|
||||
{
|
||||
d /= 2;
|
||||
f /= 2;
|
||||
|
@ -892,7 +927,7 @@ static inline void M_print(INT64 a)
|
|||
|
||||
FUNCMATH FUNCINLINE static inline fixed_t FixedMulC(fixed_t a, fixed_t b)
|
||||
{
|
||||
return (fixed_t)((((INT64)a * b) ) / FRACUNIT);
|
||||
return (fixed_t)((((INT64)a * b)) / FRACUNIT);
|
||||
}
|
||||
|
||||
FUNCMATH FUNCINLINE static inline fixed_t FixedDivC2(fixed_t a, fixed_t b)
|
||||
|
@ -902,7 +937,7 @@ FUNCMATH FUNCINLINE static inline fixed_t FixedDivC2(fixed_t a, fixed_t b)
|
|||
if (b == 0)
|
||||
I_Error("FixedDiv: divide by zero");
|
||||
|
||||
ret = (((INT64)a * FRACUNIT) ) / b;
|
||||
ret = (((INT64)a * FRACUNIT)) / b;
|
||||
|
||||
if ((ret > INT32_MAX) || (ret < INT32_MIN))
|
||||
I_Error("FixedDiv: divide by zero");
|
||||
|
@ -911,7 +946,7 @@ FUNCMATH FUNCINLINE static inline fixed_t FixedDivC2(fixed_t a, fixed_t b)
|
|||
|
||||
FUNCMATH FUNCINLINE static inline fixed_t FixedDivC(fixed_t a, fixed_t b)
|
||||
{
|
||||
if ((abs(a) >> (FRACBITS-2)) >= abs(b))
|
||||
if ((abs(a) >> (FRACBITS - 2)) >= abs(b))
|
||||
return (a^b) < 0 ? INT32_MIN : INT32_MAX;
|
||||
|
||||
return FixedDivC2(a, b);
|
||||
|
@ -938,43 +973,43 @@ int main(int argc, char** argv)
|
|||
|
||||
#ifdef MULDIV_TEST
|
||||
for (a = 1; a <= INT32_MAX; a += FRACUNIT)
|
||||
for (b = 0; b <= INT32_MAX; b += FRACUNIT)
|
||||
{
|
||||
c = FixedMul(a, b);
|
||||
d = FixedMulC(a, b);
|
||||
if (c != d)
|
||||
for (b = 0; b <= INT32_MAX; b += FRACUNIT)
|
||||
{
|
||||
printf("(");
|
||||
M_print(a);
|
||||
printf(") * (");
|
||||
M_print(b);
|
||||
printf(") = (");
|
||||
M_print(c);
|
||||
printf(") != (");
|
||||
M_print(d);
|
||||
printf(") \n");
|
||||
n--;
|
||||
printf("%d != %d\n", c, d);
|
||||
c = FixedMul(a, b);
|
||||
d = FixedMulC(a, b);
|
||||
if (c != d)
|
||||
{
|
||||
printf("(");
|
||||
M_print(a);
|
||||
printf(") * (");
|
||||
M_print(b);
|
||||
printf(") = (");
|
||||
M_print(c);
|
||||
printf(") != (");
|
||||
M_print(d);
|
||||
printf(") \n");
|
||||
n--;
|
||||
printf("%d != %d\n", c, d);
|
||||
}
|
||||
c = FixedDiv(a, b);
|
||||
d = FixedDivC(a, b);
|
||||
if (c != d)
|
||||
{
|
||||
printf("(");
|
||||
M_print(a);
|
||||
printf(") / (");
|
||||
M_print(b);
|
||||
printf(") = (");
|
||||
M_print(c);
|
||||
printf(") != (");
|
||||
M_print(d);
|
||||
printf(")\n");
|
||||
n--;
|
||||
printf("%d != %d\n", c, d);
|
||||
}
|
||||
if (n <= 0)
|
||||
exit(-1);
|
||||
}
|
||||
c = FixedDiv(a, b);
|
||||
d = FixedDivC(a, b);
|
||||
if (c != d)
|
||||
{
|
||||
printf("(");
|
||||
M_print(a);
|
||||
printf(") / (");
|
||||
M_print(b);
|
||||
printf(") = (");
|
||||
M_print(c);
|
||||
printf(") != (");
|
||||
M_print(d);
|
||||
printf(")\n");
|
||||
n--;
|
||||
printf("%d != %d\n", c, d);
|
||||
}
|
||||
if (n <= 0)
|
||||
exit(-1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SQRT_TEST
|
||||
|
@ -982,7 +1017,7 @@ int main(int argc, char** argv)
|
|||
{
|
||||
c = FixedSqrt(a);
|
||||
d = FixedSqrtC(a);
|
||||
b = abs(c-d);
|
||||
b = abs(c - d);
|
||||
if (b > 1)
|
||||
{
|
||||
printf("sqrt(");
|
||||
|
|
|
@ -389,9 +389,11 @@ boolean FV3_Equal(const vector3_t *a_1, const vector3_t *a_2);
|
|||
fixed_t FV3_Dot(const vector3_t *a_1, const vector3_t *a_2);
|
||||
vector3_t *FV3_Cross(const vector3_t *a_1, const vector3_t *a_2, vector3_t *a_o);
|
||||
vector3_t *FV3_ClosestPointOnLine(const vector3_t *Line, const vector3_t *p, vector3_t *out);
|
||||
void FV3_ClosestPointOnVector(const vector3_t *dir, const vector3_t *p, vector3_t *out);
|
||||
void FV3_ClosestPointOnTriangle(const vector3_t *tri, const vector3_t *point, vector3_t *result);
|
||||
vector3_t *FV3_Point2Vec(const vector3_t *point1, const vector3_t *point2, vector3_t *a_o);
|
||||
void FV3_Normal(const vector3_t *a_triangle, vector3_t *a_normal);
|
||||
fixed_t FV3_Normal(const vector3_t *a_triangle, vector3_t *a_normal);
|
||||
fixed_t FV3_Strength(const vector3_t *a_1, const vector3_t *dir);
|
||||
fixed_t FV3_PlaneDistance(const vector3_t *a_normal, const vector3_t *a_point);
|
||||
boolean FV3_IntersectedPlane(const vector3_t *a_triangle, const vector3_t *a_line, vector3_t *a_normal, fixed_t *originDistance);
|
||||
fixed_t FV3_PlaneIntersection(const vector3_t *pOrigin, const vector3_t *pNormal, const vector3_t *rOrigin, const vector3_t *rVector);
|
||||
|
|
220
src/m_menu.c
220
src/m_menu.c
|
@ -1295,18 +1295,21 @@ static menuitem_t OP_ColorOptionsMenu[] =
|
|||
#ifdef HWRENDER
|
||||
static menuitem_t OP_OpenGLOptionsMenu[] =
|
||||
{
|
||||
{IT_STRING|IT_CVAR, NULL, "Field of view", &cv_grfov, 10},
|
||||
{IT_STRING|IT_CVAR, NULL, "Quality", &cv_scr_depth, 20},
|
||||
{IT_STRING|IT_CVAR, NULL, "Texture Filter", &cv_grfiltermode, 30},
|
||||
{IT_STRING|IT_CVAR, NULL, "Anisotropic", &cv_granisotropicmode,40},
|
||||
{IT_STRING|IT_CVAR, NULL, "Models", &cv_grmodels, 10},
|
||||
{IT_STRING|IT_CVAR, NULL, "Model interpolation", &cv_grmodelinterpolation, 20},
|
||||
|
||||
{IT_STRING|IT_CVAR, NULL, "Field of view", &cv_grfov, 40},
|
||||
{IT_STRING|IT_CVAR, NULL, "Quality", &cv_scr_depth, 50},
|
||||
{IT_STRING|IT_CVAR, NULL, "Texture Filter", &cv_grfiltermode, 60},
|
||||
{IT_STRING|IT_CVAR, NULL, "Anisotropic", &cv_granisotropicmode,70},
|
||||
#if defined (_WINDOWS) && (!((defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL)))
|
||||
{IT_STRING|IT_CVAR, NULL, "Fullscreen", &cv_fullscreen, 50},
|
||||
{IT_STRING|IT_CVAR, NULL, "Fullscreen", &cv_fullscreen, 80},
|
||||
#endif
|
||||
#ifdef ALAM_LIGHTING
|
||||
{IT_SUBMENU|IT_STRING, NULL, "Lighting...", &OP_OpenGLLightingDef, 70},
|
||||
{IT_SUBMENU|IT_STRING, NULL, "Lighting...", &OP_OpenGLLightingDef, 100},
|
||||
#endif
|
||||
{IT_SUBMENU|IT_STRING, NULL, "Fog...", &OP_OpenGLFogDef, 80},
|
||||
{IT_SUBMENU|IT_STRING, NULL, "Gamma...", &OP_OpenGLColorDef, 90},
|
||||
{IT_SUBMENU|IT_STRING, NULL, "Fog...", &OP_OpenGLFogDef, 110},
|
||||
{IT_SUBMENU|IT_STRING, NULL, "Gamma...", &OP_OpenGLColorDef, 120},
|
||||
};
|
||||
|
||||
#ifdef ALAM_LIGHTING
|
||||
|
@ -2289,6 +2292,13 @@ void M_InitMenuPresTables(void)
|
|||
// so-called "undefined"
|
||||
menupres[i].fadestrength = -1;
|
||||
menupres[i].hidetitlepics = -1; // inherits global hidetitlepics
|
||||
menupres[i].ttmode = TTMODE_NONE;
|
||||
menupres[i].ttscale = UINT8_MAX;
|
||||
menupres[i].ttname[0] = 0;
|
||||
menupres[i].ttx = INT16_MAX;
|
||||
menupres[i].tty = INT16_MAX;
|
||||
menupres[i].ttloop = INT16_MAX;
|
||||
menupres[i].tttics = UINT16_MAX;
|
||||
menupres[i].enterwipe = -1;
|
||||
menupres[i].exitwipe = -1;
|
||||
menupres[i].bgcolor = -1;
|
||||
|
@ -2467,7 +2477,7 @@ static boolean MIT_SetCurFadeValue(UINT32 menutype, INT32 level, INT32 *retval,
|
|||
return false;
|
||||
}
|
||||
|
||||
static boolean MIT_SetCurHideTitlePics(UINT32 menutype, INT32 level, INT32 *retval, void **input, boolean fromoldest)
|
||||
static boolean MIT_SetCurTitlePics(UINT32 menutype, INT32 level, INT32 *retval, void **input, boolean fromoldest)
|
||||
{
|
||||
(void)input;
|
||||
(void)retval;
|
||||
|
@ -2481,8 +2491,41 @@ static boolean MIT_SetCurHideTitlePics(UINT32 menutype, INT32 level, INT32 *retv
|
|||
curhidepics = menupres[menutype].hidetitlepics;
|
||||
return true;
|
||||
}
|
||||
else if (menupres[menutype].ttmode == TTMODE_USER)
|
||||
{
|
||||
if (menupres[menutype].ttname[0])
|
||||
{
|
||||
curhidepics = menupres[menutype].hidetitlepics;
|
||||
curttmode = menupres[menutype].ttmode;
|
||||
curttscale = (menupres[menutype].ttscale != UINT8_MAX ? menupres[menutype].ttscale : ttscale);
|
||||
strncpy(curttname, menupres[menutype].ttname, 9);
|
||||
curttx = (menupres[menutype].ttx != INT16_MAX ? menupres[menutype].ttx : ttx);
|
||||
curtty = (menupres[menutype].tty != INT16_MAX ? menupres[menutype].tty : tty);
|
||||
curttloop = (menupres[menutype].ttloop != INT16_MAX ? menupres[menutype].ttloop : ttloop);
|
||||
curtttics = (menupres[menutype].tttics != UINT16_MAX ? menupres[menutype].tttics : tttics);
|
||||
}
|
||||
else
|
||||
curhidepics = menupres[menutype].hidetitlepics;
|
||||
return true;
|
||||
}
|
||||
else if (menupres[menutype].ttmode != TTMODE_NONE)
|
||||
{
|
||||
curhidepics = menupres[menutype].hidetitlepics;
|
||||
curttmode = menupres[menutype].ttmode;
|
||||
curttscale = (menupres[menutype].ttscale != UINT8_MAX ? menupres[menutype].ttscale : ttscale);
|
||||
return true;
|
||||
}
|
||||
else if (!level)
|
||||
{
|
||||
curhidepics = hidetitlepics;
|
||||
curttmode = ttmode;
|
||||
curttscale = ttscale;
|
||||
strncpy(curttname, ttname, 9);
|
||||
curttx = ttx;
|
||||
curtty = tty;
|
||||
curttloop = ttloop;
|
||||
curtttics = tttics;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2527,9 +2570,9 @@ void M_SetMenuCurFadeValue(UINT8 defaultvalue)
|
|||
M_IterateMenuTree(MIT_SetCurFadeValue, &defaultvalue);
|
||||
}
|
||||
|
||||
void M_SetMenuCurHideTitlePics(void)
|
||||
void M_SetMenuCurTitlePics(void)
|
||||
{
|
||||
M_IterateMenuTree(MIT_SetCurHideTitlePics, NULL);
|
||||
M_IterateMenuTree(MIT_SetCurTitlePics, NULL);
|
||||
}
|
||||
|
||||
// ====================================
|
||||
|
@ -2579,12 +2622,20 @@ static void M_HandleMenuPresState(menu_t *newMenu)
|
|||
curbgyspeed = titlescrollyspeed;
|
||||
curbghide = (gamestate != GS_TIMEATTACK); // show in time attack, hide in other menus
|
||||
|
||||
curttmode = ttmode;
|
||||
curttscale = ttscale;
|
||||
strncpy(curttname, ttname, 9);
|
||||
curttx = ttx;
|
||||
curtty = tty;
|
||||
curttloop = ttloop;
|
||||
curtttics = tttics;
|
||||
|
||||
// don't do the below during the in-game menus
|
||||
if (gamestate != GS_TITLESCREEN && gamestate != GS_TIMEATTACK)
|
||||
return;
|
||||
|
||||
M_SetMenuCurFadeValue(16);
|
||||
M_SetMenuCurHideTitlePics();
|
||||
M_SetMenuCurTitlePics();
|
||||
|
||||
// Loop through both menu IDs in parallel and look for type changes
|
||||
// The youngest child in activeMenuId is the entered menu
|
||||
|
@ -6512,7 +6563,7 @@ static void M_LevelSelectWarp(INT32 choice)
|
|||
|
||||
if (W_CheckNumForName(G_BuildMapName(cv_nextmap.value)) == LUMPERROR)
|
||||
{
|
||||
// CONS_Alert(CONS_WARNING, "Internal game map '%s' not found\n", G_BuildMapName(cv_nextmap.value));
|
||||
CONS_Alert(CONS_WARNING, "Internal game map '%s' not found\n", G_BuildMapName(cv_nextmap.value));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -7929,81 +7980,80 @@ static void M_SetupChoosePlayer(INT32 choice)
|
|||
char *and;
|
||||
(void)choice;
|
||||
|
||||
SP_PlayerMenu[0].status &= ~IT_DYBIGSPACE; // Correcting a hack that may be made below.
|
||||
|
||||
for (i = 0; i < 32; i++) // Handle charsels, availability, and unlocks.
|
||||
if (!(mapheaderinfo[startmap-1]
|
||||
&& (mapheaderinfo[startmap-1]->forcecharacter[0] != '\0'
|
||||
|| (mapheaderinfo[startmap-1]->typeoflevel & TOL_NIGHTS)) // remove this later when everyone gets their own nights sprites, maybe
|
||||
))
|
||||
{
|
||||
if (description[i].used) // If the character's disabled through SOC, there's nothing we can do for it.
|
||||
for (i = 0; i < 32; i++) // Handle charsels, availability, and unlocks.
|
||||
{
|
||||
and = strchr(description[i].skinname, '&');
|
||||
if (and)
|
||||
if (description[i].used) // If the character's disabled through SOC, there's nothing we can do for it.
|
||||
{
|
||||
char firstskin[SKINNAMESIZE+1];
|
||||
strncpy(firstskin, description[i].skinname, (and - description[i].skinname));
|
||||
firstskin[(and - description[i].skinname)] = '\0';
|
||||
description[i].skinnum[0] = R_SkinAvailable(firstskin);
|
||||
description[i].skinnum[1] = R_SkinAvailable(and+1);
|
||||
}
|
||||
else
|
||||
{
|
||||
description[i].skinnum[0] = R_SkinAvailable(description[i].skinname);
|
||||
description[i].skinnum[1] = -1;
|
||||
}
|
||||
skinnum = description[i].skinnum[0];
|
||||
if ((skinnum != -1) && (R_SkinUsable(-1, skinnum)))
|
||||
{
|
||||
// Handling order.
|
||||
if (firstvalid == 255)
|
||||
firstvalid = i;
|
||||
and = strchr(description[i].skinname, '&');
|
||||
if (and)
|
||||
{
|
||||
char firstskin[SKINNAMESIZE+1];
|
||||
strncpy(firstskin, description[i].skinname, (and - description[i].skinname));
|
||||
firstskin[(and - description[i].skinname)] = '\0';
|
||||
description[i].skinnum[0] = R_SkinAvailable(firstskin);
|
||||
description[i].skinnum[1] = R_SkinAvailable(and+1);
|
||||
}
|
||||
else
|
||||
{
|
||||
description[i].prev = lastvalid;
|
||||
description[lastvalid].next = i;
|
||||
description[i].skinnum[0] = R_SkinAvailable(description[i].skinname);
|
||||
description[i].skinnum[1] = -1;
|
||||
}
|
||||
lastvalid = i;
|
||||
|
||||
if (i == char_on)
|
||||
allowed = true;
|
||||
|
||||
if (!(description[i].picname[0]))
|
||||
skinnum = description[i].skinnum[0];
|
||||
if ((skinnum != -1) && (R_SkinUsable(-1, skinnum)))
|
||||
{
|
||||
if (skins[skinnum].sprites[SPR2_XTRA].numframes >= XTRA_CHARSEL+1)
|
||||
// Handling order.
|
||||
if (firstvalid == 255)
|
||||
firstvalid = i;
|
||||
else
|
||||
{
|
||||
spritedef_t *sprdef = &skins[skinnum].sprites[SPR2_XTRA];
|
||||
spriteframe_t *sprframe = &sprdef->spriteframes[XTRA_CHARSEL];
|
||||
description[i].charpic = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE);
|
||||
description[i].prev = lastvalid;
|
||||
description[lastvalid].next = i;
|
||||
}
|
||||
lastvalid = i;
|
||||
|
||||
if (i == char_on)
|
||||
allowed = true;
|
||||
|
||||
if (!(description[i].picname[0]))
|
||||
{
|
||||
if (skins[skinnum].sprites[SPR2_XTRA].numframes >= XTRA_CHARSEL+1)
|
||||
{
|
||||
spritedef_t *sprdef = &skins[skinnum].sprites[SPR2_XTRA];
|
||||
spriteframe_t *sprframe = &sprdef->spriteframes[XTRA_CHARSEL];
|
||||
description[i].charpic = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE);
|
||||
}
|
||||
else
|
||||
description[i].charpic = W_CachePatchName("MISSING", PU_CACHE);
|
||||
}
|
||||
else
|
||||
description[i].charpic = W_CachePatchName("MISSING", PU_CACHE);
|
||||
}
|
||||
else
|
||||
description[i].charpic = W_CachePatchName(description[i].picname, PU_CACHE);
|
||||
description[i].charpic = W_CachePatchName(description[i].picname, PU_CACHE);
|
||||
|
||||
if (description[i].nametag[0])
|
||||
{
|
||||
const char *nametag = description[i].nametag;
|
||||
description[i].namepic = NULL;
|
||||
if (W_LumpExists(nametag))
|
||||
description[i].namepic = W_CachePatchName(nametag, PU_CACHE);
|
||||
if (description[i].nametag[0])
|
||||
{
|
||||
const char *nametag = description[i].nametag;
|
||||
description[i].namepic = NULL;
|
||||
if (W_LumpExists(nametag))
|
||||
description[i].namepic = W_CachePatchName(nametag, PU_CACHE);
|
||||
}
|
||||
}
|
||||
// else -- Technically, character select icons without corresponding skins get bundled away behind this too. Sucks to be them.
|
||||
}
|
||||
// else -- Technically, character select icons without corresponding skins get bundled away behind this too. Sucks to be them.
|
||||
}
|
||||
}
|
||||
|
||||
if ((firstvalid != 255)
|
||||
&& !(mapheaderinfo[startmap-1]
|
||||
&& (mapheaderinfo[startmap-1]->forcecharacter[0] != '\0')
|
||||
)
|
||||
)
|
||||
if (firstvalid != 255)
|
||||
{ // One last bit of order we can't do in the iteration above.
|
||||
description[firstvalid].prev = lastvalid;
|
||||
description[lastvalid].next = firstvalid;
|
||||
}
|
||||
else // We're being forced into a specific character, so might as well.
|
||||
else // We're being forced into a specific character, so might as well just skip it.
|
||||
{
|
||||
SP_PlayerMenu[0].status |= IT_DYBIGSPACE; // This is a dummy flag hack to make a non-IT_CALL character in slot 0 not softlock the game.
|
||||
M_ChoosePlayer(0);
|
||||
M_ChoosePlayer(-1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -8330,38 +8380,42 @@ static void M_DrawSetupChoosePlayerMenu(void)
|
|||
static void M_ChoosePlayer(INT32 choice)
|
||||
{
|
||||
boolean ultmode = (ultimate_selectable && SP_PlayerDef.prevMenu == &SP_LoadDef && saveSlotSelected == NOSAVESLOT);
|
||||
UINT8 skinnum;
|
||||
|
||||
// skip this if forcecharacter or no characters available
|
||||
if (!(SP_PlayerMenu[0].status & IT_DYBIGSPACE))
|
||||
if (choice == -1)
|
||||
{
|
||||
skinnum = botskin = 0;
|
||||
botingame = false;
|
||||
}
|
||||
// M_SetupChoosePlayer didn't call us directly, that means we've been properly set up.
|
||||
else
|
||||
{
|
||||
// M_SetupChoosePlayer didn't call us directly, that means we've been properly set up.
|
||||
char_scroll = 0; // finish scrolling the menu
|
||||
M_DrawSetupChoosePlayerMenu(); // draw the finally selected character one last time for the fadeout
|
||||
// Is this a hack?
|
||||
charseltimer = 0;
|
||||
}
|
||||
M_ClearMenus(true);
|
||||
|
||||
if (description[choice].skinnum[1] != -1) {
|
||||
// this character has a second skin
|
||||
botingame = true;
|
||||
botskin = (UINT8)(description[choice].skinnum[1]+1);
|
||||
botcolor = skins[description[choice].skinnum[1]].prefcolor;
|
||||
}
|
||||
else
|
||||
{
|
||||
botingame = false;
|
||||
botskin = 0;
|
||||
botcolor = 0;
|
||||
skinnum = description[choice].skinnum[0];
|
||||
|
||||
if ((botingame = (description[choice].skinnum[1] != -1))) {
|
||||
// this character has a second skin
|
||||
botskin = (UINT8)(description[choice].skinnum[1]+1);
|
||||
botcolor = skins[description[choice].skinnum[1]].prefcolor;
|
||||
}
|
||||
else
|
||||
botskin = botcolor = 0;
|
||||
}
|
||||
|
||||
M_ClearMenus(true);
|
||||
|
||||
if (startmap != spstage_start)
|
||||
cursaveslot = 0;
|
||||
|
||||
//lastmapsaved = 0;
|
||||
gamecomplete = false;
|
||||
|
||||
G_DeferedInitNew(ultmode, G_BuildMapName(startmap), (UINT8)description[choice].skinnum[0], false, fromlevelselect);
|
||||
G_DeferedInitNew(ultmode, G_BuildMapName(startmap), skinnum, false, fromlevelselect);
|
||||
COM_BufAddText("dummyconsvar 1\n"); // G_DeferedInitNew doesn't do this
|
||||
|
||||
if (levelselect.rows)
|
||||
|
|
17
src/m_menu.h
17
src/m_menu.h
|
@ -18,6 +18,7 @@
|
|||
#include "d_event.h"
|
||||
#include "command.h"
|
||||
#include "r_things.h" // for SKINNAMESIZE
|
||||
#include "f_finale.h" // for ttmode_enum
|
||||
|
||||
//
|
||||
// MENUS
|
||||
|
@ -128,19 +129,27 @@ typedef enum
|
|||
typedef struct
|
||||
{
|
||||
char bgname[8]; // name for background gfx lump; lays over titlemap if this is set
|
||||
SINT8 hidetitlepics; // hide title gfx per menu; -1 means undefined, inherits global setting
|
||||
SINT8 fadestrength; // darken background when displaying this menu, strength 0-31 or -1 for undefined
|
||||
INT32 bgcolor; // fill color, overrides bg name. -1 means follow bg name rules.
|
||||
INT32 titlescrollxspeed; // background gfx scroll per menu; inherits global setting
|
||||
INT32 titlescrollyspeed; // y scroll
|
||||
INT32 bgcolor; // fill color, overrides bg name. -1 means follow bg name rules.
|
||||
boolean bghide; // for titlemaps, hide the background.
|
||||
|
||||
SINT8 hidetitlepics; // hide title gfx per menu; -1 means undefined, inherits global setting
|
||||
ttmode_enum ttmode; // title wing animation mode; default TTMODE_OLD
|
||||
UINT8 ttscale; // scale of title wing gfx (FRACUNIT / ttscale); -1 means undefined, inherits global setting
|
||||
char ttname[9]; // lump name of title wing gfx. If name length is <= 6, engine will attempt to load numbered frames (TTNAMExx)
|
||||
INT16 ttx; // X position of title wing
|
||||
INT16 tty; // Y position of title wing
|
||||
INT16 ttloop; // # frame to loop; -1 means dont loop
|
||||
UINT16 tttics; // # of tics per frame
|
||||
|
||||
char musname[7]; ///< Music track to play. "" for no music.
|
||||
UINT16 mustrack; ///< Subsong to play. Only really relevant for music modules and specific formats supported by GME. 0 to ignore.
|
||||
boolean muslooping; ///< Loop the music
|
||||
boolean musstop; ///< Don't play any music
|
||||
boolean musignore; ///< Let the current music keep playing
|
||||
|
||||
SINT8 fadestrength; // darken background when displaying this menu, strength 0-31 or -1 for undefined
|
||||
boolean enterbubble; // run all entrance line execs after common ancestor and up to child. If false, only run the child's exec
|
||||
boolean exitbubble; // run all exit line execs from child and up to before common ancestor. If false, only run the child's exec
|
||||
INT32 entertag; // line exec to run on menu enter, if titlemap
|
||||
|
@ -158,7 +167,7 @@ UINT8 M_GetYoungestChildMenu(void);
|
|||
void M_ChangeMenuMusic(const char *defaultmusname, boolean defaultmuslooping);
|
||||
void M_SetMenuCurBackground(const char *defaultname);
|
||||
void M_SetMenuCurFadeValue(UINT8 defaultvalue);
|
||||
void M_SetMenuCurHideTitlePics(void);
|
||||
void M_SetMenuCurTitlePics(void);
|
||||
|
||||
// Called by main loop,
|
||||
// saves config file and calls I_Quit when user exits.
|
||||
|
|
241
src/p_enemy.c
241
src/p_enemy.c
|
@ -129,6 +129,7 @@ void A_FishJump(mobj_t *actor);
|
|||
void A_ThrownRing(mobj_t *actor);
|
||||
void A_SetSolidSteam(mobj_t *actor);
|
||||
void A_UnsetSolidSteam(mobj_t *actor);
|
||||
void A_SignSpin(mobj_t *actor);
|
||||
void A_SignPlayer(mobj_t *actor);
|
||||
void A_OverlayThink(mobj_t *actor);
|
||||
void A_JetChase(mobj_t *actor);
|
||||
|
@ -3930,11 +3931,15 @@ void A_BossDeath(mobj_t *mo)
|
|||
{
|
||||
// Touching the egg trap button calls P_DoPlayerExit, which calls P_RestoreMusic.
|
||||
// So just park ourselves in the mapmus variables.
|
||||
boolean changed = strnicmp(mapheaderinfo[gamemap-1]->musname, mapmusname, 7);
|
||||
strncpy(mapmusname, mapheaderinfo[gamemap-1]->muspostbossname, 7);
|
||||
mapmusname[6] = 0;
|
||||
mapmusflags = (mapheaderinfo[gamemap-1]->muspostbosstrack & MUSIC_TRACKMASK) | MUSIC_RELOADRESET;
|
||||
mapmusposition = mapheaderinfo[gamemap-1]->muspostbosspos;
|
||||
// But don't change the mapmus variables if they were modified from their level header values (e.g., TUNES).
|
||||
boolean changed = strnicmp(mapheaderinfo[gamemap-1]->musname, S_MusicName(), 7);
|
||||
if (!strnicmp(mapheaderinfo[gamemap-1]->musname, mapmusname, 7))
|
||||
{
|
||||
strncpy(mapmusname, mapheaderinfo[gamemap-1]->muspostbossname, 7);
|
||||
mapmusname[6] = 0;
|
||||
mapmusflags = (mapheaderinfo[gamemap-1]->muspostbosstrack & MUSIC_TRACKMASK) | MUSIC_RELOADRESET;
|
||||
mapmusposition = mapheaderinfo[gamemap-1]->muspostbosspos;
|
||||
}
|
||||
|
||||
// don't change if we're in another tune
|
||||
// but in case we're in jingle, use our parked mapmus variables so the correct track restores
|
||||
|
@ -4759,7 +4764,7 @@ void A_DropMine(mobj_t *actor)
|
|||
// Description: Makes the stupid harmless fish in Greenflower Zone jump.
|
||||
//
|
||||
// var1 = Jump strength (in FRACBITS), if specified. Otherwise, uses the angle value.
|
||||
// var2 = unused
|
||||
// var2 = Trail object to spawn, if desired.
|
||||
//
|
||||
void A_FishJump(mobj_t *actor)
|
||||
{
|
||||
|
@ -4772,8 +4777,17 @@ void A_FishJump(mobj_t *actor)
|
|||
|
||||
if (locvar2)
|
||||
{
|
||||
fixed_t rad = actor->radius>>FRACBITS;
|
||||
P_SpawnMobjFromMobj(actor, P_RandomRange(rad, -rad)<<FRACBITS, P_RandomRange(rad, -rad)<<FRACBITS, 0, (mobjtype_t)locvar2);
|
||||
UINT8 i;
|
||||
// Don't spawn trail unless a player is nearby.
|
||||
for (i = 0; i < MAXPLAYERS; ++i)
|
||||
if (playeringame[i] && players[i].mo
|
||||
&& P_AproxDistance(actor->x - players[i].mo->x, actor->y - players[i].mo->y) < (actor->info->speed))
|
||||
break; // Stop looking.
|
||||
if (i < MAXPLAYERS)
|
||||
{
|
||||
fixed_t rad = actor->radius>>FRACBITS;
|
||||
P_SpawnMobjFromMobj(actor, P_RandomRange(rad, -rad)<<FRACBITS, P_RandomRange(rad, -rad)<<FRACBITS, 0, (mobjtype_t)locvar2);
|
||||
}
|
||||
}
|
||||
|
||||
if ((actor->z <= actor->floorz) || (actor->z <= actor->watertop - FixedMul((64 << FRACBITS), actor->scale)))
|
||||
|
@ -5006,59 +5020,186 @@ void A_UnsetSolidSteam(mobj_t *actor)
|
|||
actor->flags |= MF_NOCLIP;
|
||||
}
|
||||
|
||||
// Function: A_SignSpin
|
||||
//
|
||||
// Description: Spins a signpost until it hits the ground and reaches its mapthing's angle.
|
||||
//
|
||||
// var1 = degrees to rotate object (must be positive, because I'm lazy)
|
||||
// var2 = unused
|
||||
//
|
||||
void A_SignSpin(mobj_t *actor)
|
||||
{
|
||||
INT32 locvar1 = var1;
|
||||
INT32 locvar2 = var2;
|
||||
INT16 i;
|
||||
angle_t rotateangle = FixedAngle(locvar1 << FRACBITS);
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUA_CallAction("A_SignSpin", actor))
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (P_IsObjectOnGround(actor) && P_MobjFlip(actor) * actor->momz <= 0)
|
||||
{
|
||||
if (actor->spawnpoint)
|
||||
{
|
||||
angle_t mapangle = FixedAngle(actor->spawnpoint->angle << FRACBITS);
|
||||
angle_t diff = mapangle - actor->angle;
|
||||
if (diff < ANG2)
|
||||
{
|
||||
actor->angle = mapangle;
|
||||
P_SetMobjState(actor, actor->info->deathstate);
|
||||
return;
|
||||
}
|
||||
if ((statenum_t)(actor->state-states) != actor->info->painstate)
|
||||
P_SetMobjState(actor, actor->info->painstate);
|
||||
actor->movedir = min((mapangle - actor->angle) >> 2, actor->movedir);
|
||||
}
|
||||
else // no mapthing? just finish in your current angle
|
||||
{
|
||||
P_SetMobjState(actor, locvar2);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
actor->movedir = rotateangle;
|
||||
}
|
||||
actor->angle += actor->movedir;
|
||||
if (actor->tracer == NULL || P_MobjWasRemoved(actor->tracer)) return;
|
||||
for (i = -1; i < 2; i += 2)
|
||||
{
|
||||
P_SpawnMobjFromMobj(actor,
|
||||
P_ReturnThrustX(actor, actor->tracer->angle, i * actor->radius),
|
||||
P_ReturnThrustY(actor, actor->tracer->angle, i * actor->radius),
|
||||
(actor->eflags & MFE_VERTICALFLIP) ? 0 : actor->height,
|
||||
actor->info->painchance)->destscale >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Function: A_SignPlayer
|
||||
//
|
||||
// Description: Changes the state of a level end sign to reflect the player that hit it.
|
||||
// Also used to display Eggman or the skin roulette whilst spinning.
|
||||
//
|
||||
// var1 = unused
|
||||
// var2 = unused
|
||||
// var1 = number of skin to display (e.g. 2 = Knuckles; special cases: -1 = target's skin, -2 = skin roulette, -3 = Eggman)
|
||||
// var2 = custom sign color, if desired.
|
||||
//
|
||||
void A_SignPlayer(mobj_t *actor)
|
||||
{
|
||||
INT32 locvar1 = var1;
|
||||
INT32 locvar2 = var2;
|
||||
skin_t *skin = NULL;
|
||||
mobj_t *ov;
|
||||
skin_t *skin;
|
||||
UINT8 facecolor, signcolor = (UINT8)locvar2;
|
||||
UINT32 signframe = states[actor->info->raisestate].frame;
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUA_CallAction("A_SignPlayer", actor))
|
||||
return;
|
||||
#endif
|
||||
if (!actor->target)
|
||||
|
||||
if (actor->tracer == NULL || locvar1 < -3 || locvar1 >= numskins)
|
||||
return;
|
||||
|
||||
if (!actor->target->player)
|
||||
return;
|
||||
|
||||
skin = &skins[actor->target->player->skin];
|
||||
|
||||
if ((actor->target->player->skincolor == skin->prefcolor) && (skin->prefoppositecolor)) // Set it as the skin's preferred oppositecolor?
|
||||
// if no face overlay, spawn one
|
||||
if (actor->tracer->tracer == NULL || P_MobjWasRemoved(actor->tracer->tracer))
|
||||
{
|
||||
actor->color = skin->prefoppositecolor;
|
||||
/*
|
||||
If you're here from the comment above Color_Opposite,
|
||||
the following line is the one which is dependent on the
|
||||
array being symmetrical. It gets the opposite of the
|
||||
opposite of your desired colour just so it can get the
|
||||
brightness frame for the End Sign. It's not a great
|
||||
design choice, but it's constant time array access and
|
||||
the idea that the colours should be OPPOSITES is kind
|
||||
of in the name. If you have a better idea, feel free
|
||||
to let me know. ~toast 2016/07/20
|
||||
*/
|
||||
actor->frame += (15 - Color_Opposite[Color_Opposite[skin->prefoppositecolor - 1][0] - 1][1]);
|
||||
}
|
||||
else if (actor->target->player->skincolor) // Set the sign to be an appropriate background color for this player's skincolor.
|
||||
{
|
||||
actor->color = Color_Opposite[actor->target->player->skincolor - 1][0];
|
||||
actor->frame += (15 - Color_Opposite[actor->target->player->skincolor - 1][1]);
|
||||
}
|
||||
|
||||
if (skin->sprites[SPR2_SIGN].numframes)
|
||||
{
|
||||
// spawn an overlay of the player's face.
|
||||
ov = P_SpawnMobj(actor->x, actor->y, actor->z, MT_OVERLAY);
|
||||
P_SetTarget(&ov->target, actor);
|
||||
ov->color = actor->target->player->skincolor;
|
||||
P_SetTarget(&ov->target, actor->tracer);
|
||||
P_SetTarget(&actor->tracer->tracer, ov);
|
||||
}
|
||||
else
|
||||
ov = actor->tracer->tracer;
|
||||
|
||||
if (locvar1 == -1) // set to target's skin
|
||||
{
|
||||
if (!actor->target)
|
||||
return;
|
||||
|
||||
if (!actor->target->player)
|
||||
return;
|
||||
|
||||
skin = &skins[actor->target->player->skin];
|
||||
facecolor = actor->target->player->skincolor;
|
||||
|
||||
if (signcolor)
|
||||
;
|
||||
else if ((actor->target->player->skincolor == skin->prefcolor) && (skin->prefoppositecolor)) // Set it as the skin's preferred oppositecolor?
|
||||
{
|
||||
signcolor = skin->prefoppositecolor;
|
||||
/*
|
||||
If you're here from the comment above Color_Opposite,
|
||||
the following line is the one which is dependent on the
|
||||
array being symmetrical. It gets the opposite of the
|
||||
opposite of your desired colour just so it can get the
|
||||
brightness frame for the End Sign. It's not a great
|
||||
design choice, but it's constant time array access and
|
||||
the idea that the colours should be OPPOSITES is kind
|
||||
of in the name. If you have a better idea, feel free
|
||||
to let me know. ~toast 2016/07/20
|
||||
*/
|
||||
signframe += (15 - Color_Opposite[Color_Opposite[skin->prefoppositecolor - 1][0] - 1][1]);
|
||||
}
|
||||
else if (actor->target->player->skincolor) // Set the sign to be an appropriate background color for this player's skincolor.
|
||||
{
|
||||
signcolor = Color_Opposite[actor->target->player->skincolor - 1][0];
|
||||
signframe += (15 - Color_Opposite[actor->target->player->skincolor - 1][1]);
|
||||
}
|
||||
else
|
||||
signcolor = SKINCOLOR_NONE;
|
||||
}
|
||||
else if (locvar1 != -3) // set to a defined skin
|
||||
{
|
||||
// I turned this function into a fucking mess. I'm so sorry. -Lach
|
||||
if (locvar1 == -2) // next skin
|
||||
{
|
||||
if (ov->skin == NULL) // pick a random skin to start with!
|
||||
skin = &skins[P_RandomKey(numskins)];
|
||||
else // otherwise, advance 1 skin
|
||||
{
|
||||
UINT8 skinnum = (skin_t*)ov->skin-skins;
|
||||
player_t *player = actor->target ? actor->target->player : NULL;
|
||||
while ((skinnum = (skinnum + 1) % numskins) && (player ? !R_SkinUsable(player-players, skinnum) : skins[skinnum].availability > 0));
|
||||
skin = &skins[skinnum];
|
||||
}
|
||||
}
|
||||
else // specific skin
|
||||
{
|
||||
skin = &skins[locvar1];
|
||||
}
|
||||
|
||||
facecolor = skin->prefcolor;
|
||||
if (signcolor)
|
||||
;
|
||||
else if (skin->prefoppositecolor)
|
||||
{
|
||||
signcolor = skin->prefoppositecolor;
|
||||
}
|
||||
else
|
||||
{
|
||||
signcolor = Color_Opposite[facecolor - 1][0];
|
||||
}
|
||||
signframe += (15 - Color_Opposite[Color_Opposite[signcolor - 1][0] - 1][1]);
|
||||
}
|
||||
|
||||
if (skin != NULL && skin->sprites[SPR2_SIGN].numframes) // player face
|
||||
{
|
||||
ov->color = facecolor;
|
||||
ov->skin = skin;
|
||||
P_SetMobjState(ov, actor->info->seestate); // S_PLAY_SIGN
|
||||
actor->tracer->color = signcolor;
|
||||
actor->tracer->frame = signframe;
|
||||
}
|
||||
else // Eggman face
|
||||
{
|
||||
ov->color = SKINCOLOR_NONE;
|
||||
P_SetMobjState(ov, actor->info->meleestate); // S_EGGMANSIGN
|
||||
if (signcolor)
|
||||
actor->tracer->color = signcolor;
|
||||
else
|
||||
actor->tracer->color = signcolor = SKINCOLOR_CARBON;
|
||||
actor->tracer->frame = signframe += (15 - Color_Opposite[Color_Opposite[signcolor - 1][0] - 1][1]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5106,7 +5247,7 @@ void A_OverlayThink(mobj_t *actor)
|
|||
actor->z = actor->target->z + actor->target->height - mobjinfo[actor->type].height - ((var2>>16) ? -1 : 1)*(var2&0xFFFF)*FRACUNIT;
|
||||
else
|
||||
actor->z = actor->target->z + ((var2>>16) ? -1 : 1)*(var2&0xFFFF)*FRACUNIT;
|
||||
actor->angle = actor->target->angle;
|
||||
actor->angle = actor->target->angle + actor->movedir;
|
||||
actor->eflags = actor->target->eflags;
|
||||
|
||||
actor->momx = actor->target->momx;
|
||||
|
@ -14025,7 +14166,7 @@ void A_LavafallRocks(mobj_t *actor)
|
|||
// Don't spawn rocks unless a player is relatively close by.
|
||||
for (i = 0; i < MAXPLAYERS; ++i)
|
||||
if (playeringame[i] && players[i].mo
|
||||
&& P_AproxDistance(actor->x - players[i].mo->x, actor->y - players[i].mo->y) < (1600 << FRACBITS))
|
||||
&& P_AproxDistance(actor->x - players[i].mo->x, actor->y - players[i].mo->y) < (actor->info->speed >> 1))
|
||||
break; // Stop looking.
|
||||
|
||||
if (i < MAXPLAYERS)
|
||||
|
@ -14048,6 +14189,7 @@ void A_LavafallRocks(mobj_t *actor)
|
|||
void A_LavafallLava(mobj_t *actor)
|
||||
{
|
||||
mobj_t *lavafall;
|
||||
UINT8 i;
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUA_CallAction("A_LavafallLava", actor))
|
||||
|
@ -14057,6 +14199,15 @@ void A_LavafallLava(mobj_t *actor)
|
|||
if ((40 - actor->fuse) % (2*(actor->scale >> FRACBITS)))
|
||||
return;
|
||||
|
||||
// Don't spawn lava unless a player is nearby.
|
||||
for (i = 0; i < MAXPLAYERS; ++i)
|
||||
if (playeringame[i] && players[i].mo
|
||||
&& P_AproxDistance(actor->x - players[i].mo->x, actor->y - players[i].mo->y) < (actor->info->speed))
|
||||
break; // Stop looking.
|
||||
|
||||
if (i >= MAXPLAYERS)
|
||||
return;
|
||||
|
||||
lavafall = P_SpawnMobjFromMobj(actor, 0, 0, -8*FRACUNIT, MT_LAVAFALL_LAVA);
|
||||
lavafall->momz = -P_MobjFlip(actor)*25*FRACUNIT;
|
||||
}
|
||||
|
|
|
@ -633,7 +633,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
if (!(netgame || multiplayer))
|
||||
{
|
||||
player->continues += 1;
|
||||
players->gotcontinue = true;
|
||||
player->gotcontinue = true;
|
||||
if (P_IsLocalPlayer(player))
|
||||
S_StartSound(NULL, sfx_s3kac);
|
||||
else
|
||||
|
@ -2482,6 +2482,8 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
|||
P_UnsetThingPosition(target);
|
||||
target->flags |= MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY;
|
||||
P_SetThingPosition(target);
|
||||
target->standingslope = NULL;
|
||||
target->pmomz = 0;
|
||||
|
||||
if (target->player->powers[pw_super])
|
||||
{
|
||||
|
|
|
@ -540,7 +540,7 @@ static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object)
|
|||
|
||||
static void P_DoPterabyteCarry(player_t *player, mobj_t *ptera)
|
||||
{
|
||||
if (player->powers[pw_carry] && players->powers[pw_carry] != CR_ROLLOUT)
|
||||
if (player->powers[pw_carry] && player->powers[pw_carry] != CR_ROLLOUT)
|
||||
return;
|
||||
if (ptera->extravalue1 != 1)
|
||||
return; // Not swooping
|
||||
|
|
48
src/p_mobj.c
48
src/p_mobj.c
|
@ -1861,6 +1861,9 @@ void P_XYMovement(mobj_t *mo)
|
|||
oldy = mo->y;
|
||||
|
||||
#ifdef ESLOPE
|
||||
if (mo->flags & MF_NOCLIPHEIGHT)
|
||||
mo->standingslope = NULL;
|
||||
|
||||
// adjust various things based on slope
|
||||
if (mo->standingslope && abs(mo->standingslope->zdelta) > FRACUNIT>>8) {
|
||||
if (!P_IsObjectOnGround(mo)) { // We fell off at some point? Do the twisty thing!
|
||||
|
@ -1991,7 +1994,7 @@ void P_XYMovement(mobj_t *mo)
|
|||
mo->momz = transfermomz;
|
||||
mo->standingslope = NULL;
|
||||
if (player->pflags & PF_SPINNING)
|
||||
player->pflags = (player->pflags & ~PF_SPINNING) | (PF_JUMPED | PF_THOKKED);
|
||||
player->pflags |= PF_THOKKED;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -2051,7 +2054,7 @@ void P_XYMovement(mobj_t *mo)
|
|||
return;
|
||||
|
||||
#ifdef ESLOPE
|
||||
if (moved && oldslope) { // Check to see if we ran off
|
||||
if (moved && oldslope && !(mo->flags & MF_NOCLIPHEIGHT)) { // Check to see if we ran off
|
||||
|
||||
if (oldslope != mo->standingslope) { // First, compare different slopes
|
||||
angle_t oldangle, newangle;
|
||||
|
@ -2459,16 +2462,6 @@ static boolean P_ZMovement(mobj_t *mo)
|
|||
P_RemoveMobj(mo);
|
||||
return false;
|
||||
}
|
||||
if (mo->momz
|
||||
&& !(mo->flags & MF_NOGRAVITY)
|
||||
&& ((!(mo->eflags & MFE_VERTICALFLIP) && mo->z <= mo->floorz)
|
||||
|| ((mo->eflags & MFE_VERTICALFLIP) && mo->z+mo->height >= mo->ceilingz)))
|
||||
{
|
||||
mo->flags |= MF_NOGRAVITY;
|
||||
mo->momx = 8; // this is a hack which is used to ensure it still behaves as a missile and can damage others
|
||||
mo->momy = mo->momz = 0;
|
||||
mo->z = ((mo->eflags & MFE_VERTICALFLIP) ? mo->ceilingz-mo->height : mo->floorz);
|
||||
}
|
||||
break;
|
||||
case MT_GOOP:
|
||||
if (P_CheckDeathPitCollide(mo))
|
||||
|
@ -3325,7 +3318,7 @@ void P_MobjCheckWater(mobj_t *mobj)
|
|||
ffloor_t *rover;
|
||||
player_t *p = mobj->player; // Will just be null if not a player.
|
||||
fixed_t height = (p ? P_GetPlayerHeight(p) : mobj->height); // for players, calculation height does not necessarily match actual height for gameplay reasons (spin, etc)
|
||||
boolean wasgroundpounding = (p && (mobj->eflags & MFE_GOOWATER) && ((p->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL || (p->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP) && (p->pflags & PF_SHIELDABILITY));
|
||||
boolean wasgroundpounding = (p && ((p->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL || (p->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP) && (p->pflags & PF_SHIELDABILITY));
|
||||
|
||||
// Default if no water exists.
|
||||
mobj->watertop = mobj->waterbottom = mobj->z - 1000*FRACUNIT;
|
||||
|
@ -3425,7 +3418,7 @@ void P_MobjCheckWater(mobj_t *mobj)
|
|||
p->powers[pw_underwater] = underwatertics + 1;
|
||||
}
|
||||
|
||||
if (wasgroundpounding)
|
||||
if ((wasgroundpounding = ((mobj->eflags & MFE_GOOWATER) && wasgroundpounding)))
|
||||
{
|
||||
p->pflags &= ~PF_SHIELDABILITY;
|
||||
mobj->momz >>= 1;
|
||||
|
@ -6948,7 +6941,7 @@ void P_RunOverlays(void)
|
|||
|
||||
mo->eflags = (mo->eflags & ~MFE_VERTICALFLIP) | (mo->target->eflags & MFE_VERTICALFLIP);
|
||||
mo->scale = mo->destscale = mo->target->scale;
|
||||
mo->angle = mo->target->angle;
|
||||
mo->angle = mo->target->angle + mo->movedir;
|
||||
|
||||
if (!(mo->state->frame & FF_ANIMATE))
|
||||
zoffs = FixedMul(((signed)mo->state->var2)*FRACUNIT, mo->scale);
|
||||
|
@ -9498,6 +9491,13 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
|
||||
hdist = R_PointToDist2(mobj->x, mobj->y, mobj->target->x, mobj->target->y);
|
||||
|
||||
if (hdist > 1500*FRACUNIT)
|
||||
{
|
||||
mobj->flags2 &= ~MF2_BOSSNOTRAP;
|
||||
P_SetTarget(&mobj->target, NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(mobj->flags2 & MF2_BOSSNOTRAP) && hdist <= 450*FRACUNIT)
|
||||
mobj->flags2 |= MF2_BOSSNOTRAP;
|
||||
|
||||
|
@ -9517,11 +9517,6 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
mobj->momx = 0;
|
||||
mobj->momy = 0;
|
||||
mobj->momz = 0;
|
||||
if (hdist >= 1500*FRACUNIT)
|
||||
{
|
||||
mobj->flags2 &= ~MF2_BOSSNOTRAP;
|
||||
P_SetTarget(&mobj->target, NULL);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -9631,6 +9626,14 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
else
|
||||
mobj->z = mobj->floorz;
|
||||
}
|
||||
else if ((!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z <= mobj->floorz)
|
||||
|| ((mobj->eflags & MFE_VERTICALFLIP) && mobj->z+mobj->height >= mobj->ceilingz))
|
||||
{
|
||||
mobj->flags |= MF_NOGRAVITY;
|
||||
mobj->momx = 8; // this is a hack which is used to ensure it still behaves as a missile and can damage others
|
||||
mobj->momy = mobj->momz = 0;
|
||||
mobj->z = ((mobj->eflags & MFE_VERTICALFLIP) ? mobj->ceilingz-mobj->height : mobj->floorz);
|
||||
}
|
||||
/* FALLTHRU */
|
||||
default:
|
||||
// check mobj against possible water content, before movement code
|
||||
|
@ -10506,6 +10509,11 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
|||
mobj->extravalue2 = 0;
|
||||
mobj->fuse = 100;
|
||||
break;
|
||||
case MT_SIGN:
|
||||
P_SetTarget(&mobj->tracer, P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_OVERLAY));
|
||||
P_SetTarget(&mobj->tracer->target, mobj);
|
||||
P_SetMobjState(mobj->tracer, S_SIGNBOARD);
|
||||
mobj->tracer->movedir = ANGLE_90;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
186
src/p_setup.c
186
src/p_setup.c
|
@ -75,6 +75,7 @@
|
|||
#ifdef HWRENDER
|
||||
#include "hardware/hw_main.h"
|
||||
#include "hardware/hw_light.h"
|
||||
#include "hardware/hw_model.h"
|
||||
#endif
|
||||
|
||||
#ifdef ESLOPE
|
||||
|
@ -546,52 +547,118 @@ size_t P_PrecacheLevelFlats(void)
|
|||
//SoM: 4/18/2000: New flat code to make use of levelflats.
|
||||
for (i = 0; i < numlevelflats; i++)
|
||||
{
|
||||
lump = levelflats[i].lumpnum;
|
||||
if (devparm)
|
||||
flatmemory += W_LumpLength(lump);
|
||||
R_GetFlat(lump);
|
||||
if (levelflats[i].type == LEVELFLAT_FLAT)
|
||||
{
|
||||
lump = levelflats[i].u.flat.lumpnum;
|
||||
if (devparm)
|
||||
flatmemory += W_LumpLength(lump);
|
||||
R_GetFlat(lump);
|
||||
}
|
||||
}
|
||||
return flatmemory;
|
||||
}
|
||||
|
||||
/*
|
||||
levelflat refers to an array of level flats,
|
||||
or NULL if we want to allocate it now.
|
||||
*/
|
||||
static INT32
|
||||
Ploadflat (levelflat_t *levelflat, const char *flatname)
|
||||
{
|
||||
UINT8 buffer[8];
|
||||
|
||||
lumpnum_t flatnum;
|
||||
int texturenum;
|
||||
|
||||
size_t i;
|
||||
|
||||
if (levelflat)
|
||||
{
|
||||
// Scan through the already found flats, return if it matches.
|
||||
for (i = 0; i < numlevelflats; i++)
|
||||
{
|
||||
if (strnicmp(levelflat[i].name, flatname, 8) == 0)
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef ZDEBUG
|
||||
CONS_Debug(DBG_SETUP, "flat #%03d: %s\n", atoi(sizeu1(numlevelflats)), levelflat->name);
|
||||
#endif
|
||||
|
||||
if (numlevelflats >= MAXLEVELFLATS)
|
||||
I_Error("Too many flats in level\n");
|
||||
|
||||
if (levelflat)
|
||||
levelflat += numlevelflats;
|
||||
else
|
||||
{
|
||||
// allocate new flat memory
|
||||
levelflats = Z_Realloc(levelflats, (numlevelflats + 1) * sizeof(*levelflats), PU_LEVEL, NULL);
|
||||
levelflat = levelflats + numlevelflats;
|
||||
}
|
||||
|
||||
// Store the name.
|
||||
strlcpy(levelflat->name, flatname, sizeof (levelflat->name));
|
||||
strupr(levelflat->name);
|
||||
|
||||
/* If we can't find a flat, try looking for a texture! */
|
||||
if (( flatnum = R_GetFlatNumForName(flatname) ) == LUMPERROR)
|
||||
{
|
||||
if (( texturenum = R_CheckTextureNumForName(flatname) ) == -1)
|
||||
{
|
||||
// check for REDWALL
|
||||
if (( texturenum = R_CheckTextureNumForName("REDWALL") ) != -1)
|
||||
goto texturefound;
|
||||
// check for REDFLR
|
||||
else if (( flatnum = R_GetFlatNumForName("REDFLR") ) != LUMPERROR)
|
||||
goto flatfound;
|
||||
// nevermind
|
||||
levelflat->type = LEVELFLAT_NONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
texturefound:
|
||||
levelflat->type = LEVELFLAT_TEXTURE;
|
||||
levelflat->u.texture. num = texturenum;
|
||||
levelflat->u.texture.lastnum = texturenum;
|
||||
/* start out unanimated */
|
||||
levelflat->u.texture.basenum = -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
flatfound:
|
||||
/* This could be a flat, patch, or PNG. */
|
||||
if (R_CheckIfPatch(flatnum))
|
||||
levelflat->type = LEVELFLAT_PATCH;
|
||||
else
|
||||
{
|
||||
#ifndef NO_PNG_LUMPS
|
||||
/*
|
||||
Only need eight bytes for PNG headers.
|
||||
FIXME: Put this elsewhere.
|
||||
*/
|
||||
W_ReadLumpHeader(flatnum, buffer, 8, 0);
|
||||
if (R_IsLumpPNG(buffer, W_LumpLength(flatnum)))
|
||||
levelflat->type = LEVELFLAT_PNG;
|
||||
else
|
||||
#endif/*NO_PNG_LUMPS*/
|
||||
levelflat->type = LEVELFLAT_FLAT;/* phew */
|
||||
}
|
||||
|
||||
levelflat->u.flat. lumpnum = flatnum;
|
||||
levelflat->u.flat.baselumpnum = LUMPERROR;
|
||||
}
|
||||
|
||||
return ( numlevelflats++ );
|
||||
}
|
||||
|
||||
// Auxiliary function. Find a flat in the active wad files,
|
||||
// allocate an id for it, and set the levelflat (to speedup search)
|
||||
INT32 P_AddLevelFlat(const char *flatname, levelflat_t *levelflat)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
// Scan through the already found flats, break if it matches.
|
||||
for (i = 0; i < numlevelflats; i++, levelflat++)
|
||||
if (strnicmp(levelflat->name, flatname, 8) == 0)
|
||||
break;
|
||||
|
||||
// If there is no match, make room for a new flat.
|
||||
if (i == numlevelflats)
|
||||
{
|
||||
// Store the name.
|
||||
strlcpy(levelflat->name, flatname, sizeof (levelflat->name));
|
||||
strupr(levelflat->name);
|
||||
|
||||
// store the flat lump number
|
||||
levelflat->lumpnum = R_GetFlatNumForName(flatname);
|
||||
levelflat->texturenum = R_CheckTextureNumForName(flatname);
|
||||
levelflat->lasttexturenum = levelflat->texturenum;
|
||||
|
||||
levelflat->baselumpnum = LUMPERROR;
|
||||
levelflat->basetexturenum = -1;
|
||||
|
||||
#ifndef ZDEBUG
|
||||
CONS_Debug(DBG_SETUP, "flat #%03d: %s\n", atoi(sizeu1(numlevelflats)), levelflat->name);
|
||||
#endif
|
||||
|
||||
numlevelflats++;
|
||||
|
||||
if (numlevelflats >= MAXLEVELFLATS)
|
||||
I_Error("Too many flats in level\n");
|
||||
}
|
||||
|
||||
// level flat id
|
||||
return (INT32)i;
|
||||
return Ploadflat(levelflat, flatname);
|
||||
}
|
||||
|
||||
// help function for Lua and $$$.sav reading
|
||||
|
@ -600,44 +667,7 @@ INT32 P_AddLevelFlat(const char *flatname, levelflat_t *levelflat)
|
|||
//
|
||||
INT32 P_AddLevelFlatRuntime(const char *flatname)
|
||||
{
|
||||
size_t i;
|
||||
levelflat_t *levelflat = levelflats;
|
||||
|
||||
//
|
||||
// first scan through the already found flats
|
||||
//
|
||||
for (i = 0; i < numlevelflats; i++, levelflat++)
|
||||
if (strnicmp(levelflat->name,flatname,8)==0)
|
||||
break;
|
||||
|
||||
// that flat was already found in the level, return the id
|
||||
if (i == numlevelflats)
|
||||
{
|
||||
// allocate new flat memory
|
||||
levelflats = Z_Realloc(levelflats, (numlevelflats + 1) * sizeof(*levelflats), PU_LEVEL, NULL);
|
||||
levelflat = levelflats+i;
|
||||
|
||||
// store the name
|
||||
strlcpy(levelflat->name, flatname, sizeof (levelflat->name));
|
||||
strupr(levelflat->name);
|
||||
|
||||
// store the flat lump number
|
||||
levelflat->lumpnum = R_GetFlatNumForName(flatname);
|
||||
levelflat->texturenum = R_CheckTextureNumForName(flatname);
|
||||
levelflat->lasttexturenum = levelflat->texturenum;
|
||||
|
||||
levelflat->baselumpnum = LUMPERROR;
|
||||
levelflat->basetexturenum = -1;
|
||||
|
||||
#ifndef ZDEBUG
|
||||
CONS_Debug(DBG_SETUP, "flat #%03d: %s\n", atoi(sizeu1(numlevelflats)), levelflat->name);
|
||||
#endif
|
||||
|
||||
numlevelflats++;
|
||||
}
|
||||
|
||||
// level flat id
|
||||
return (INT32)i;
|
||||
return Ploadflat(0, flatname);
|
||||
}
|
||||
|
||||
// help function for $$$.sav checking
|
||||
|
@ -3472,6 +3502,10 @@ boolean P_AddWadFile(const char *wadfilename)
|
|||
if (!mapsadded)
|
||||
CONS_Printf(M_GetText("No maps added\n"));
|
||||
|
||||
#ifdef HWRENDER
|
||||
HWR_ReloadModels();
|
||||
#endif // HWRENDER
|
||||
|
||||
// reload status bar (warning should have valid player!)
|
||||
if (gamestate == GS_LEVEL)
|
||||
ST_Start();
|
||||
|
|
|
@ -30,20 +30,51 @@ extern boolean levelloading;
|
|||
extern UINT8 levelfadecol;
|
||||
|
||||
extern lumpnum_t lastloadedmaplumpnum; // for comparative savegame
|
||||
|
||||
/* for levelflat type */
|
||||
enum
|
||||
{
|
||||
LEVELFLAT_NONE,/* HOM time my friend */
|
||||
LEVELFLAT_FLAT,
|
||||
LEVELFLAT_PATCH,
|
||||
#ifndef NO_PNG_LUMPS
|
||||
LEVELFLAT_PNG,
|
||||
#endif
|
||||
LEVELFLAT_TEXTURE,
|
||||
};
|
||||
|
||||
//
|
||||
// MAP used flats lookup table
|
||||
//
|
||||
typedef struct
|
||||
{
|
||||
char name[9]; // resource name from wad
|
||||
lumpnum_t lumpnum; // lump number of the flat
|
||||
INT32 texturenum, lasttexturenum; // texture number of the flat
|
||||
|
||||
UINT8 type;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
lumpnum_t lumpnum; // lump number of the flat
|
||||
// for flat animation
|
||||
lumpnum_t baselumpnum;
|
||||
}
|
||||
flat;
|
||||
struct
|
||||
{
|
||||
INT32 num;
|
||||
INT32 lastnum; // texture number of the flat
|
||||
// for flat animation
|
||||
INT32 basenum;
|
||||
}
|
||||
texture;
|
||||
}
|
||||
u;
|
||||
|
||||
UINT16 width, height;
|
||||
fixed_t topoffset, leftoffset;
|
||||
|
||||
// for flat animation
|
||||
lumpnum_t baselumpnum;
|
||||
INT32 basetexturenum;
|
||||
INT32 animseq; // start pos. in the anim sequence
|
||||
INT32 numpics;
|
||||
INT32 speed;
|
||||
|
|
34
src/p_spec.c
34
src/p_spec.c
|
@ -464,11 +464,11 @@ static inline void P_FindAnimatedFlat(INT32 animnum)
|
|||
for (i = 0; i < numlevelflats; i++, foundflats++)
|
||||
{
|
||||
// is that levelflat from the flat anim sequence ?
|
||||
if ((anims[animnum].istexture) && (foundflats->texturenum != 0 && foundflats->texturenum != -1)
|
||||
&& ((UINT16)foundflats->texturenum >= startflatnum && (UINT16)foundflats->texturenum <= endflatnum))
|
||||
if ((anims[animnum].istexture) && (foundflats->type == LEVELFLAT_TEXTURE)
|
||||
&& ((UINT16)foundflats->u.texture.num >= startflatnum && (UINT16)foundflats->u.texture.num <= endflatnum))
|
||||
{
|
||||
foundflats->basetexturenum = startflatnum;
|
||||
foundflats->animseq = foundflats->texturenum - startflatnum;
|
||||
foundflats->u.texture.basenum = startflatnum;
|
||||
foundflats->animseq = foundflats->u.texture.num - startflatnum;
|
||||
foundflats->numpics = endflatnum - startflatnum + 1;
|
||||
foundflats->speed = anims[animnum].speed;
|
||||
|
||||
|
@ -476,10 +476,10 @@ static inline void P_FindAnimatedFlat(INT32 animnum)
|
|||
atoi(sizeu1(i)), foundflats->name, foundflats->animseq,
|
||||
foundflats->numpics,foundflats->speed);
|
||||
}
|
||||
else if (foundflats->lumpnum >= startflatnum && foundflats->lumpnum <= endflatnum)
|
||||
else if (foundflats->u.flat.lumpnum >= startflatnum && foundflats->u.flat.lumpnum <= endflatnum)
|
||||
{
|
||||
foundflats->baselumpnum = startflatnum;
|
||||
foundflats->animseq = foundflats->lumpnum - startflatnum;
|
||||
foundflats->u.flat.baselumpnum = startflatnum;
|
||||
foundflats->animseq = foundflats->u.flat.lumpnum - startflatnum;
|
||||
foundflats->numpics = endflatnum - startflatnum + 1;
|
||||
foundflats->speed = anims[animnum].speed;
|
||||
|
||||
|
@ -4054,11 +4054,15 @@ void P_SetupSignExit(player_t *player)
|
|||
if (thing->type != MT_SIGN)
|
||||
continue;
|
||||
|
||||
if (!player->mo->target || player->mo->target->type != MT_SIGN)
|
||||
P_SetTarget(&player->mo->target, thing);
|
||||
|
||||
if (thing->state != &states[thing->info->spawnstate])
|
||||
continue;
|
||||
|
||||
P_SetTarget(&thing->target, player->mo);
|
||||
P_SetMobjState(thing, S_SIGN1);
|
||||
P_SetObjectMomZ(thing, 12*FRACUNIT, false);
|
||||
P_SetMobjState(thing, S_SIGNSPIN1);
|
||||
if (thing->info->seesound)
|
||||
S_StartSound(thing, thing->info->seesound);
|
||||
|
||||
|
@ -4079,11 +4083,15 @@ void P_SetupSignExit(player_t *player)
|
|||
if (thing->type != MT_SIGN)
|
||||
continue;
|
||||
|
||||
if (!player->mo->target || player->mo->target->type != MT_SIGN)
|
||||
P_SetTarget(&player->mo->target, thing);
|
||||
|
||||
if (thing->state != &states[thing->info->spawnstate])
|
||||
continue;
|
||||
|
||||
P_SetTarget(&thing->target, player->mo);
|
||||
P_SetMobjState(thing, S_SIGN1);
|
||||
P_SetObjectMomZ(thing, 12*FRACUNIT, false);
|
||||
P_SetMobjState(thing, S_SIGNSPIN1);
|
||||
if (thing->info->seesound)
|
||||
S_StartSound(thing, thing->info->seesound);
|
||||
|
||||
|
@ -5581,11 +5589,11 @@ void P_UpdateSpecials(void)
|
|||
if (foundflats->speed) // it is an animated flat
|
||||
{
|
||||
// update the levelflat texture number
|
||||
if (foundflats->basetexturenum != -1)
|
||||
foundflats->texturenum = foundflats->basetexturenum + ((leveltime/foundflats->speed + foundflats->animseq) % foundflats->numpics);
|
||||
if (foundflats->type == LEVELFLAT_TEXTURE)
|
||||
foundflats->u.texture.num = foundflats->u.texture.basenum + ((leveltime/foundflats->speed + foundflats->animseq) % foundflats->numpics);
|
||||
// update the levelflat lump number
|
||||
else if (foundflats->baselumpnum != LUMPERROR)
|
||||
foundflats->lumpnum = foundflats->baselumpnum + ((leveltime/foundflats->speed + foundflats->animseq) % foundflats->numpics);
|
||||
else if ((foundflats->type == LEVELFLAT_FLAT) && (foundflats->u.flat.baselumpnum != LUMPERROR))
|
||||
foundflats->u.flat.lumpnum = foundflats->u.flat.baselumpnum + ((leveltime/foundflats->speed + foundflats->animseq) % foundflats->numpics);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
118
src/p_user.c
118
src/p_user.c
|
@ -1240,6 +1240,8 @@ void P_GivePlayerLives(player_t *player, INT32 numlives)
|
|||
numlives = (numlives + prevlives - player->lives);
|
||||
}
|
||||
}
|
||||
else if (player->lives == INFLIVES)
|
||||
return;
|
||||
|
||||
player->lives += numlives;
|
||||
|
||||
|
@ -2223,8 +2225,8 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff)
|
|||
{
|
||||
if (dorollstuff)
|
||||
{
|
||||
if ((player->charability2 == CA2_SPINDASH) && !(player->pflags & PF_THOKKED) && (player->cmd.buttons & BT_USE) && (FixedHypot(player->mo->momx, player->mo->momy) > (5*player->mo->scale)))
|
||||
player->pflags |= PF_SPINNING;
|
||||
if ((player->charability2 == CA2_SPINDASH) && !((player->pflags & (PF_SPINNING|PF_THOKKED)) == PF_THOKKED) && (player->cmd.buttons & BT_USE) && (FixedHypot(player->mo->momx, player->mo->momy) > (5*player->mo->scale)))
|
||||
player->pflags = (player->pflags|PF_SPINNING) & ~PF_THOKKED;
|
||||
else if (!(player->pflags & PF_STARTDASH))
|
||||
player->pflags &= ~PF_SPINNING;
|
||||
}
|
||||
|
@ -2261,7 +2263,7 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff)
|
|||
else if (!player->skidtime)
|
||||
player->pflags &= ~PF_GLIDING;
|
||||
}
|
||||
else if (player->charability == CA_GLIDEANDCLIMB && player->pflags & PF_THOKKED && (~player->pflags) & PF_SHIELDABILITY)
|
||||
else if (player->charability == CA_GLIDEANDCLIMB && player->pflags & PF_THOKKED && !(player->pflags & PF_SHIELDABILITY) && player->mo->state-states == S_PLAY_FALL)
|
||||
{
|
||||
if (player->mo->state-states != S_PLAY_GLIDE_LANDING)
|
||||
{
|
||||
|
@ -5300,14 +5302,23 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
|
|||
// Now Knuckles-type abilities are checked.
|
||||
if (!(player->pflags & PF_THOKKED) || player->charflags & SF_MULTIABILITY)
|
||||
{
|
||||
INT32 glidespeed = player->actionspd;
|
||||
fixed_t glidespeed = FixedMul(player->actionspd, player->mo->scale);
|
||||
fixed_t playerspeed = player->speed;
|
||||
|
||||
if (player->mo->eflags & MFE_UNDERWATER)
|
||||
{
|
||||
glidespeed >>= 1;
|
||||
playerspeed >>= 1;
|
||||
player->mo->momx = ((player->mo->momx - player->cmomx) >> 1) + player->cmomx;
|
||||
player->mo->momy = ((player->mo->momy - player->cmomy) >> 1) + player->cmomy;
|
||||
}
|
||||
|
||||
player->pflags |= PF_GLIDING|PF_THOKKED;
|
||||
player->glidetime = 0;
|
||||
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_GLIDE);
|
||||
if (player->speed < glidespeed)
|
||||
P_Thrust(player->mo, player->mo->angle, glidespeed - player->speed);
|
||||
if (playerspeed < glidespeed)
|
||||
P_Thrust(player->mo, player->mo->angle, glidespeed - playerspeed);
|
||||
player->pflags &= ~(PF_SPINNING|PF_STARTDASH);
|
||||
}
|
||||
break;
|
||||
|
@ -5764,7 +5775,7 @@ static void P_2dMovement(player_t *player)
|
|||
movepushforward >>= 1; // Proper air movement
|
||||
|
||||
// Allow a bit of movement while spinning
|
||||
if (player->pflags & PF_SPINNING)
|
||||
if ((player->pflags & (PF_SPINNING|PF_THOKKED)) == PF_SPINNING)
|
||||
{
|
||||
if (!(player->pflags & PF_STARTDASH))
|
||||
movepushforward = movepushforward/48;
|
||||
|
@ -5791,7 +5802,7 @@ static void P_3dMovement(player_t *player)
|
|||
angle_t dangle; // replaces old quadrants bits
|
||||
fixed_t normalspd = FixedMul(player->normalspeed, player->mo->scale);
|
||||
boolean analogmove = false;
|
||||
boolean spin = ((onground = P_IsObjectOnGround(player->mo)) && player->pflags & PF_SPINNING && (player->rmomx || player->rmomy) && !(player->pflags & PF_STARTDASH));
|
||||
boolean spin = ((onground = P_IsObjectOnGround(player->mo)) && (player->pflags & (PF_SPINNING|PF_THOKKED)) == PF_SPINNING && (player->rmomx || player->rmomy) && !(player->pflags & PF_STARTDASH));
|
||||
fixed_t oldMagnitude, newMagnitude;
|
||||
#ifdef ESLOPE
|
||||
vector3_t totalthrust;
|
||||
|
@ -5967,7 +5978,12 @@ static void P_3dMovement(player_t *player)
|
|||
if (player->climbing)
|
||||
{
|
||||
if (cmd->forwardmove)
|
||||
P_SetObjectMomZ(player->mo, FixedDiv(cmd->forwardmove*FRACUNIT, 15*FRACUNIT>>1), false);
|
||||
{
|
||||
if (player->mo->eflags & MFE_UNDERWATER)
|
||||
P_SetObjectMomZ(player->mo, FixedDiv(cmd->forwardmove*FRACUNIT, 10*FRACUNIT), false);
|
||||
else
|
||||
P_SetObjectMomZ(player->mo, FixedDiv(cmd->forwardmove*FRACUNIT, 15*FRACUNIT>>1), false);
|
||||
}
|
||||
}
|
||||
else if (!analogmove
|
||||
&& cmd->forwardmove != 0 && !(player->pflags & PF_GLIDING || player->exiting
|
||||
|
@ -5976,7 +5992,7 @@ static void P_3dMovement(player_t *player)
|
|||
movepushforward = cmd->forwardmove * (thrustfactor * acceleration);
|
||||
|
||||
// Allow a bit of movement while spinning
|
||||
if (player->pflags & PF_SPINNING)
|
||||
if ((player->pflags & (PF_SPINNING|PF_THOKKED)) == PF_SPINNING)
|
||||
{
|
||||
if ((mforward && cmd->forwardmove > 0) || (mbackward && cmd->forwardmove < 0)
|
||||
|| (player->pflags & PF_STARTDASH))
|
||||
|
@ -6001,7 +6017,12 @@ static void P_3dMovement(player_t *player)
|
|||
}
|
||||
// Sideways movement
|
||||
if (player->climbing)
|
||||
P_InstaThrust(player->mo, player->mo->angle-ANGLE_90, FixedDiv(cmd->sidemove*player->mo->scale, 15*FRACUNIT>>1));
|
||||
{
|
||||
if (player->mo->eflags & MFE_UNDERWATER)
|
||||
P_InstaThrust(player->mo, player->mo->angle-ANGLE_90, FixedDiv(cmd->sidemove*player->mo->scale, 10*FRACUNIT));
|
||||
else
|
||||
P_InstaThrust(player->mo, player->mo->angle-ANGLE_90, FixedDiv(cmd->sidemove*player->mo->scale, 15*FRACUNIT>>1));
|
||||
}
|
||||
// Analog movement control
|
||||
else if (analogmove)
|
||||
{
|
||||
|
@ -6017,7 +6038,7 @@ static void P_3dMovement(player_t *player)
|
|||
movepushforward = max(abs(cmd->sidemove), abs(cmd->forwardmove)) * (thrustfactor * acceleration);
|
||||
|
||||
// Allow a bit of movement while spinning
|
||||
if (player->pflags & PF_SPINNING)
|
||||
if ((player->pflags & (PF_SPINNING|PF_THOKKED)) == PF_SPINNING)
|
||||
{
|
||||
if ((mforward && cmd->forwardmove > 0) || (mbackward && cmd->forwardmove < 0)
|
||||
|| (player->pflags & PF_STARTDASH))
|
||||
|
@ -6052,11 +6073,11 @@ static void P_3dMovement(player_t *player)
|
|||
{
|
||||
movepushside >>= 2; // proper air movement
|
||||
// Reduce movepushslide even more if over "max" flight speed
|
||||
if ((player->pflags & PF_SPINNING) || (player->powers[pw_tailsfly] && player->speed > topspeed))
|
||||
if (((player->pflags & (PF_SPINNING|PF_THOKKED)) == PF_SPINNING) || (player->powers[pw_tailsfly] && player->speed > topspeed))
|
||||
movepushside >>= 2;
|
||||
}
|
||||
// Allow a bit of movement while spinning
|
||||
else if (player->pflags & PF_SPINNING)
|
||||
else if ((player->pflags & (PF_SPINNING|PF_THOKKED)) == PF_SPINNING)
|
||||
{
|
||||
if (player->pflags & PF_STARTDASH)
|
||||
movepushside = 0;
|
||||
|
@ -8594,6 +8615,9 @@ static void P_MovePlayer(player_t *player)
|
|||
// Look for Quicksand!
|
||||
if (CheckForQuicksand)
|
||||
P_CheckQuicksand(player);
|
||||
|
||||
if (P_IsObjectOnGround(player->mo))
|
||||
player->mo->pmomz = 0;
|
||||
}
|
||||
|
||||
static void P_DoZoomTube(player_t *player)
|
||||
|
@ -9497,7 +9521,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
fixed_t x, y, z, dist, distxy, distz, checkdist, viewpointx, viewpointy, camspeed, camdist, camheight, pviewheight, slopez = 0;
|
||||
INT32 camrotate;
|
||||
boolean camstill, cameranoclip, camorbit;
|
||||
mobj_t *mo;
|
||||
mobj_t *mo, *sign = NULL;
|
||||
subsector_t *newsubsec;
|
||||
fixed_t f1, f2;
|
||||
|
||||
|
@ -9507,6 +9531,9 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
|
||||
mo = player->mo;
|
||||
|
||||
if (player->exiting && mo->target && mo->target->type == MT_SIGN)
|
||||
sign = mo->target;
|
||||
|
||||
cameranoclip = (player->powers[pw_carry] == CR_NIGHTSMODE || player->pflags & PF_NOCLIP) || (mo->flags & (MF_NOCLIP|MF_NOCLIPHEIGHT)); // Noclipping player camera noclips too!!
|
||||
|
||||
if (!(player->climbing || (player->powers[pw_carry] == CR_NIGHTSMODE) || player->playerstate == PST_DEAD || tutorialmode))
|
||||
|
@ -9553,6 +9580,11 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
focusangle = mo->angle;
|
||||
focusaiming = 0;
|
||||
}
|
||||
else if (sign)
|
||||
{
|
||||
focusangle = FixedAngle(sign->spawnpoint->angle << FRACBITS) + ANGLE_180;
|
||||
focusaiming = 0;
|
||||
}
|
||||
else if (player == &players[consoleplayer])
|
||||
{
|
||||
focusangle = localangle;
|
||||
|
@ -9701,6 +9733,12 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
camheight = FixedMul(camheight, 6*FRACUNIT/5);
|
||||
}
|
||||
|
||||
if (sign)
|
||||
{
|
||||
camheight = mo->scale << 7;
|
||||
camspeed = FRACUNIT/12;
|
||||
}
|
||||
|
||||
if (player->climbing || player->exiting || player->playerstate == PST_DEAD || (player->powers[pw_carry] == CR_ROPEHANG || player->powers[pw_carry] == CR_GENERIC || player->powers[pw_carry] == CR_MACESPIN))
|
||||
dist <<= 1;
|
||||
}
|
||||
|
@ -9747,8 +9785,16 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
distz = slopez;
|
||||
}
|
||||
|
||||
x = mo->x - FixedMul(FINECOSINE((angle>>ANGLETOFINESHIFT) & FINEMASK), distxy);
|
||||
y = mo->y - FixedMul(FINESINE((angle>>ANGLETOFINESHIFT) & FINEMASK), distxy);
|
||||
if (sign)
|
||||
{
|
||||
x = sign->x - FixedMul(FINECOSINE((angle>>ANGLETOFINESHIFT) & FINEMASK), distxy);
|
||||
y = sign->y - FixedMul(FINESINE((angle>>ANGLETOFINESHIFT) & FINEMASK), distxy);
|
||||
}
|
||||
else
|
||||
{
|
||||
x = mo->x - FixedMul(FINECOSINE((angle>>ANGLETOFINESHIFT) & FINEMASK), distxy);
|
||||
y = mo->y - FixedMul(FINESINE((angle>>ANGLETOFINESHIFT) & FINEMASK), distxy);
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (twodlevel || (mo->flags2 & MF2_TWOD))
|
||||
|
@ -9993,14 +10039,30 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
// point viewed by the camera
|
||||
// this point is just 64 unit forward the player
|
||||
dist = FixedMul(64 << FRACBITS, mo->scale);
|
||||
viewpointx = mo->x + FixedMul(FINECOSINE((angle>>ANGLETOFINESHIFT) & FINEMASK), dist);
|
||||
viewpointy = mo->y + FixedMul(FINESINE((angle>>ANGLETOFINESHIFT) & FINEMASK), dist);
|
||||
if (sign)
|
||||
{
|
||||
viewpointx = sign->x + FixedMul(FINECOSINE((angle>>ANGLETOFINESHIFT) & FINEMASK), dist);
|
||||
viewpointy = sign->y + FixedMul(FINESINE((angle>>ANGLETOFINESHIFT) & FINEMASK), dist);
|
||||
}
|
||||
else
|
||||
{
|
||||
viewpointx = mo->x + FixedMul(FINECOSINE((angle>>ANGLETOFINESHIFT) & FINEMASK), dist);
|
||||
viewpointy = mo->y + FixedMul(FINESINE((angle>>ANGLETOFINESHIFT) & FINEMASK), dist);
|
||||
}
|
||||
|
||||
if (!camstill && !resetcalled && !paused)
|
||||
thiscam->angle = R_PointToAngle2(thiscam->x, thiscam->y, viewpointx, viewpointy);
|
||||
|
||||
viewpointx = mo->x + FixedMul(FINECOSINE((angle>>ANGLETOFINESHIFT) & FINEMASK), dist);
|
||||
viewpointy = mo->y + FixedMul(FINESINE((angle>>ANGLETOFINESHIFT) & FINEMASK), dist);
|
||||
if (sign)
|
||||
{
|
||||
viewpointx = sign->x + FixedMul(FINECOSINE((angle>>ANGLETOFINESHIFT) & FINEMASK), dist);
|
||||
viewpointy = sign->y + FixedMul(FINESINE((angle>>ANGLETOFINESHIFT) & FINEMASK), dist);
|
||||
}
|
||||
else
|
||||
{
|
||||
viewpointx = mo->x + FixedMul(FINECOSINE((angle>>ANGLETOFINESHIFT) & FINEMASK), dist);
|
||||
viewpointy = mo->y + FixedMul(FINESINE((angle>>ANGLETOFINESHIFT) & FINEMASK), dist);
|
||||
}
|
||||
|
||||
/*
|
||||
if (twodlevel || (mo->flags2 & MF2_TWOD))
|
||||
|
@ -11821,8 +11883,8 @@ void P_PlayerThink(player_t *player)
|
|||
player->pflags &= ~PF_SLIDING;
|
||||
|
||||
#define dashmode player->dashmode
|
||||
// Dash mode - thanks be to Iceman404
|
||||
if ((player->charflags & SF_DASHMODE) && !(player->gotflag) && !(maptol & TOL_NIGHTS) && !metalrecording) // woo, dashmode! no nights tho.
|
||||
// Dash mode - thanks be to VelocitOni
|
||||
if ((player->charflags & SF_DASHMODE) && !player->gotflag && !player->powers[pw_carry] && !player->exiting && !(maptol & TOL_NIGHTS) && !metalrecording) // woo, dashmode! no nights tho.
|
||||
{
|
||||
boolean totallyradical = player->speed >= FixedMul(player->runspeed, player->mo->scale);
|
||||
boolean floating = (player->secondjump == 1);
|
||||
|
@ -11832,12 +11894,16 @@ void P_PlayerThink(player_t *player)
|
|||
if (dashmode < DASHMODE_MAX)
|
||||
dashmode++; // Counter. Adds 1 to dash mode per tic in top speed.
|
||||
if (dashmode == DASHMODE_THRESHOLD) // This isn't in the ">=" equation because it'd cause the sound to play infinitely.
|
||||
S_StartSound(player->mo, sfx_s3ka2); // If the player enters dashmode, play this sound on the the tic it starts.
|
||||
S_StartSound(player->mo, (player->charflags & SF_MACHINE) ? sfx_kc4d : sfx_cdfm40); // If the player enters dashmode, play this sound on the the tic it starts.
|
||||
}
|
||||
else if ((!totallyradical || !floating) && !(player->pflags & PF_SPINNING))
|
||||
{
|
||||
if (dashmode > 3)
|
||||
{
|
||||
dashmode -= 3; // Rather than lose it all, it gently counts back down!
|
||||
if ((dashmode+3) >= DASHMODE_THRESHOLD && dashmode < DASHMODE_THRESHOLD)
|
||||
S_StartSound(player->mo, sfx_kc65);
|
||||
}
|
||||
else
|
||||
dashmode = 0;
|
||||
}
|
||||
|
@ -11868,6 +11934,7 @@ void P_PlayerThink(player_t *player)
|
|||
{
|
||||
player->normalspeed = skins[player->skin].normalspeed;
|
||||
player->jumpfactor = skins[player->skin].jumpfactor;
|
||||
S_StartSound(player->mo, sfx_kc65);
|
||||
}
|
||||
dashmode = 0;
|
||||
}
|
||||
|
@ -12395,9 +12462,6 @@ void P_PlayerAfterThink(player_t *player)
|
|||
player->mo->flags |= MF_NOGRAVITY;
|
||||
}
|
||||
|
||||
if (P_IsObjectOnGround(player->mo))
|
||||
player->mo->pmomz = 0;
|
||||
|
||||
if (player->followmobj && (player->spectator || player->mo->health <= 0 || player->followmobj->type != player->followitem))
|
||||
{
|
||||
P_RemoveMobj(player->followmobj);
|
||||
|
|
78
src/r_data.c
78
src/r_data.c
|
@ -456,10 +456,11 @@ static UINT8 *R_GenerateTexture(size_t texnum)
|
|||
texture_t *texture;
|
||||
texpatch_t *patch;
|
||||
patch_t *realpatch;
|
||||
boolean dealloc = false;
|
||||
int x, x1, x2, i, width, height;
|
||||
size_t blocksize;
|
||||
column_t *patchcol;
|
||||
UINT32 *colofs;
|
||||
UINT8 *colofs;
|
||||
|
||||
UINT16 wadnum;
|
||||
lumpnum_t lumpnum;
|
||||
|
@ -487,19 +488,16 @@ static UINT8 *R_GenerateTexture(size_t texnum)
|
|||
|
||||
#ifndef NO_PNG_LUMPS
|
||||
if (R_IsLumpPNG((UINT8 *)realpatch, lumplength))
|
||||
{
|
||||
realpatch = R_PNGToPatch((UINT8 *)realpatch, lumplength, NULL, false);
|
||||
goto multipatch;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Check the patch for holes.
|
||||
if (texture->width > SHORT(realpatch->width) || texture->height > SHORT(realpatch->height))
|
||||
holey = true;
|
||||
colofs = (UINT32 *)realpatch->columnofs;
|
||||
colofs = (UINT8 *)realpatch->columnofs;
|
||||
for (x = 0; x < texture->width && !holey; x++)
|
||||
{
|
||||
column_t *col = (column_t *)((UINT8 *)realpatch + LONG(colofs[x]));
|
||||
column_t *col = (column_t *)((UINT8 *)realpatch + LONG(*(UINT32 *)&colofs[x<<2]));
|
||||
INT32 topdelta, prevdelta = -1, y = 0;
|
||||
while (col->topdelta != 0xff)
|
||||
{
|
||||
|
@ -528,19 +526,19 @@ static UINT8 *R_GenerateTexture(size_t texnum)
|
|||
texturememory += blocksize;
|
||||
|
||||
// use the patch's column lookup
|
||||
colofs = (UINT32 *)(void *)(block + 8);
|
||||
texturecolumnofs[texnum] = colofs;
|
||||
colofs = (block + 8);
|
||||
texturecolumnofs[texnum] = (UINT32 *)colofs;
|
||||
blocktex = block;
|
||||
if (patch->flip & 1) // flip the patch horizontally
|
||||
{
|
||||
UINT32 *realcolofs = (UINT32 *)realpatch->columnofs;
|
||||
UINT8 *realcolofs = (UINT8 *)realpatch->columnofs;
|
||||
for (x = 0; x < texture->width; x++)
|
||||
colofs[x] = realcolofs[texture->width-1-x]; // swap with the offset of the other side of the texture
|
||||
*(UINT32 *)&colofs[x<<2] = realcolofs[( texture->width-1-x )<<2]; // swap with the offset of the other side of the texture
|
||||
}
|
||||
// we can't as easily flip the patch vertically sadly though,
|
||||
// we have wait until the texture itself is drawn to do that
|
||||
for (x = 0; x < texture->width; x++)
|
||||
colofs[x] = LONG(LONG(colofs[x]) + 3);
|
||||
*(UINT32 *)&colofs[x<<2] = LONG(LONG(*(UINT32 *)&colofs[x<<2]) + 3);
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
@ -560,8 +558,8 @@ static UINT8 *R_GenerateTexture(size_t texnum)
|
|||
memset(block, TRANSPARENTPIXEL, blocksize+1); // Transparency hack
|
||||
|
||||
// columns lookup table
|
||||
colofs = (UINT32 *)(void *)block;
|
||||
texturecolumnofs[texnum] = colofs;
|
||||
colofs = block;
|
||||
texturecolumnofs[texnum] = (UINT32 *)colofs;
|
||||
|
||||
// texture data after the lookup table
|
||||
blocktex = block + (texture->width*4);
|
||||
|
@ -579,9 +577,14 @@ static UINT8 *R_GenerateTexture(size_t texnum)
|
|||
lumpnum = patch->lump;
|
||||
lumplength = W_LumpLengthPwad(wadnum, lumpnum);
|
||||
realpatch = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE);
|
||||
dealloc = false;
|
||||
|
||||
#ifndef NO_PNG_LUMPS
|
||||
if (R_IsLumpPNG((UINT8 *)realpatch, lumplength))
|
||||
{
|
||||
realpatch = R_PNGToPatch((UINT8 *)realpatch, lumplength, NULL, false);
|
||||
dealloc = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
x1 = patch->originx;
|
||||
|
@ -616,9 +619,12 @@ static UINT8 *R_GenerateTexture(size_t texnum)
|
|||
patchcol = (column_t *)((UINT8 *)realpatch + LONG(realpatch->columnofs[x-x1]));
|
||||
|
||||
// generate column ofset lookup
|
||||
colofs[x] = LONG((x * texture->height) + (texture->width*4));
|
||||
ColumnDrawerPointer(patchcol, block + LONG(colofs[x]), patch, texture->height, height);
|
||||
*(UINT32 *)&colofs[x<<2] = LONG((x * texture->height) + (texture->width*4));
|
||||
ColumnDrawerPointer(patchcol, block + LONG(*(UINT32 *)&colofs[x<<2]), patch, texture->height, height);
|
||||
}
|
||||
|
||||
if (dealloc)
|
||||
Z_Free(realpatch);
|
||||
}
|
||||
|
||||
done:
|
||||
|
@ -1450,48 +1456,6 @@ lumpnum_t R_GetFlatNumForName(const char *name)
|
|||
lump = LUMPERROR;
|
||||
}
|
||||
|
||||
// Detect textures
|
||||
if (lump == LUMPERROR)
|
||||
{
|
||||
// Scan wad files backwards so patched textures take preference.
|
||||
for (i = numwadfiles - 1; i >= 0; i--)
|
||||
{
|
||||
switch (wadfiles[i]->type)
|
||||
{
|
||||
case RET_WAD:
|
||||
if ((start = W_CheckNumForNamePwad("TX_START", (UINT16)i, 0)) == INT16_MAX)
|
||||
continue;
|
||||
if ((end = W_CheckNumForNamePwad("TX_END", (UINT16)i, start)) == INT16_MAX)
|
||||
continue;
|
||||
break;
|
||||
case RET_PK3:
|
||||
if ((start = W_CheckNumForFolderStartPK3("Textures/", i, 0)) == INT16_MAX)
|
||||
continue;
|
||||
if ((end = W_CheckNumForFolderEndPK3("Textures/", i, start)) == INT16_MAX)
|
||||
continue;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
// Now find lump with specified name in that range.
|
||||
lump = W_CheckNumForNamePwad(name, (UINT16)i, start);
|
||||
if (lump < end)
|
||||
{
|
||||
lump += (i<<16); // found it, in our constraints
|
||||
break;
|
||||
}
|
||||
lump = LUMPERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (lump == LUMPERROR)
|
||||
{
|
||||
if (strcmp(name, SKYFLATNAME))
|
||||
CONS_Debug(DBG_SETUP, "R_GetFlatNumForName: Could not find flat %.8s\n", name);
|
||||
lump = W_CheckNumForName("REDFLR");
|
||||
}
|
||||
|
||||
return lump;
|
||||
}
|
||||
|
||||
|
|
|
@ -1208,7 +1208,6 @@ void R_RegisterEngineStuff(void)
|
|||
CV_RegisterVar(&cv_grgammared);
|
||||
CV_RegisterVar(&cv_grfovchange);
|
||||
CV_RegisterVar(&cv_grfog);
|
||||
CV_RegisterVar(&cv_voodoocompatibility);
|
||||
CV_RegisterVar(&cv_grfogcolor);
|
||||
CV_RegisterVar(&cv_grsoftwarefog);
|
||||
#ifdef ALAM_LIGHTING
|
||||
|
@ -1217,7 +1216,8 @@ void R_RegisterEngineStuff(void)
|
|||
CV_RegisterVar(&cv_grcoronas);
|
||||
CV_RegisterVar(&cv_grcoronasize);
|
||||
#endif
|
||||
CV_RegisterVar(&cv_grmd2);
|
||||
CV_RegisterVar(&cv_grmodelinterpolation);
|
||||
CV_RegisterVar(&cv_grmodels);
|
||||
CV_RegisterVar(&cv_grspritebillboarding);
|
||||
CV_RegisterVar(&cv_grskydome);
|
||||
#endif
|
||||
|
|
|
@ -756,9 +756,9 @@ static UINT8 *R_GenerateFlat(UINT16 width, UINT16 height)
|
|||
static UINT8 *R_GetTextureFlat(levelflat_t *levelflat, boolean leveltexture, boolean ispng)
|
||||
{
|
||||
UINT8 *flat;
|
||||
textureflat_t *texflat = &texflats[levelflat->texturenum];
|
||||
textureflat_t *texflat = &texflats[levelflat->u.texture.num];
|
||||
patch_t *patch = NULL;
|
||||
boolean texturechanged = (leveltexture ? (levelflat->texturenum != levelflat->lasttexturenum) : false);
|
||||
boolean texturechanged = (leveltexture ? (levelflat->u.texture.num != levelflat->u.texture.lastnum) : false);
|
||||
|
||||
// Check if the texture changed.
|
||||
if (leveltexture && (!texturechanged))
|
||||
|
@ -780,12 +780,12 @@ static UINT8 *R_GetTextureFlat(levelflat_t *levelflat, boolean leveltexture, boo
|
|||
// Level texture
|
||||
if (leveltexture)
|
||||
{
|
||||
texture_t *texture = textures[levelflat->texturenum];
|
||||
texture_t *texture = textures[levelflat->u.texture.num];
|
||||
texflat->width = ds_flatwidth = texture->width;
|
||||
texflat->height = ds_flatheight = texture->height;
|
||||
|
||||
texflat->flat = R_GenerateFlat(ds_flatwidth, ds_flatheight);
|
||||
R_TextureToFlat(levelflat->texturenum, texflat->flat);
|
||||
R_TextureToFlat(levelflat->u.texture.num, texflat->flat);
|
||||
flat = texflat->flat;
|
||||
|
||||
levelflat->flatpatch = flat;
|
||||
|
@ -799,7 +799,7 @@ static UINT8 *R_GetTextureFlat(levelflat_t *levelflat, boolean leveltexture, boo
|
|||
#ifndef NO_PNG_LUMPS
|
||||
if (ispng)
|
||||
{
|
||||
levelflat->flatpatch = R_PNGToFlat(&levelflat->width, &levelflat->height, ds_source, W_LumpLength(levelflat->lumpnum));
|
||||
levelflat->flatpatch = R_PNGToFlat(&levelflat->width, &levelflat->height, ds_source, W_LumpLength(levelflat->u.flat.lumpnum));
|
||||
levelflat->topoffset = levelflat->leftoffset = 0;
|
||||
ds_flatwidth = levelflat->width;
|
||||
ds_flatheight = levelflat->height;
|
||||
|
@ -829,7 +829,7 @@ static UINT8 *R_GetTextureFlat(levelflat_t *levelflat, boolean leveltexture, boo
|
|||
xoffs += levelflat->leftoffset;
|
||||
yoffs += levelflat->topoffset;
|
||||
|
||||
levelflat->lasttexturenum = levelflat->texturenum;
|
||||
levelflat->u.texture.lastnum = levelflat->u.texture.num;
|
||||
return flat;
|
||||
}
|
||||
|
||||
|
@ -839,10 +839,9 @@ void R_DrawSinglePlane(visplane_t *pl)
|
|||
INT32 light = 0;
|
||||
INT32 x;
|
||||
INT32 stop, angle;
|
||||
size_t size;
|
||||
ffloor_t *rover;
|
||||
levelflat_t *levelflat;
|
||||
boolean rawflat = false;
|
||||
int type;
|
||||
|
||||
if (!(pl->minx <= pl->maxx))
|
||||
return;
|
||||
|
@ -996,43 +995,45 @@ void R_DrawSinglePlane(visplane_t *pl)
|
|||
|
||||
currentplane = pl;
|
||||
levelflat = &levelflats[pl->picnum];
|
||||
size = W_LumpLength(levelflat->lumpnum);
|
||||
ds_source = (UINT8 *)W_CacheLumpNum(levelflat->lumpnum, PU_STATIC); // Stay here until Z_ChangeTag
|
||||
|
||||
// Check if the flat is actually a wall texture.
|
||||
if (levelflat->texturenum != 0 && levelflat->texturenum != -1)
|
||||
flat = R_GetTextureFlat(levelflat, true, false);
|
||||
/* :james: */
|
||||
type = levelflat->type;
|
||||
switch (type)
|
||||
{
|
||||
case LEVELFLAT_NONE:
|
||||
return;
|
||||
case LEVELFLAT_FLAT:
|
||||
ds_source = W_CacheLumpNum(levelflat->u.flat.lumpnum, PU_CACHE);
|
||||
R_CheckFlatLength(W_LumpLength(levelflat->u.flat.lumpnum));
|
||||
// Raw flats always have dimensions that are powers-of-two numbers.
|
||||
ds_powersoftwo = true;
|
||||
break;
|
||||
default:
|
||||
switch (type)
|
||||
{
|
||||
case LEVELFLAT_TEXTURE:
|
||||
/* Textures get cached differently and don't need ds_source */
|
||||
ds_source = R_GetTextureFlat(levelflat, true, false);
|
||||
break;
|
||||
default:
|
||||
ds_source = W_CacheLumpNum(levelflat->u.flat.lumpnum, PU_STATIC);
|
||||
flat = R_GetTextureFlat(levelflat, false,
|
||||
#ifndef NO_PNG_LUMPS
|
||||
// Maybe it's a PNG?!
|
||||
else if (R_IsLumpPNG(ds_source, size))
|
||||
flat = R_GetTextureFlat(levelflat, false, true);
|
||||
( type == LEVELFLAT_PNG )
|
||||
#else
|
||||
false
|
||||
#endif
|
||||
// Maybe it's just a patch, then?
|
||||
else if (R_CheckIfPatch(levelflat->lumpnum))
|
||||
flat = R_GetTextureFlat(levelflat, false, false);
|
||||
// It's a raw flat.
|
||||
else
|
||||
{
|
||||
rawflat = true;
|
||||
R_CheckFlatLength(size);
|
||||
flat = ds_source;
|
||||
}
|
||||
|
||||
Z_ChangeTag(ds_source, PU_CACHE);
|
||||
ds_source = flat;
|
||||
|
||||
if (ds_source == NULL)
|
||||
return;
|
||||
|
||||
// Raw flats always have dimensions that are powers-of-two numbers.
|
||||
if (rawflat)
|
||||
ds_powersoftwo = true;
|
||||
// Otherwise, check if this texture or patch has such dimensions.
|
||||
else if (R_CheckPowersOfTwo())
|
||||
{
|
||||
R_CheckFlatLength(ds_flatwidth * ds_flatheight);
|
||||
if (spanfunc == basespanfunc)
|
||||
spanfunc = mmxspanfunc;
|
||||
);
|
||||
Z_ChangeTag(ds_source, PU_CACHE);
|
||||
ds_source = flat;
|
||||
}
|
||||
// Check if this texture or patch has power-of-two dimensions.
|
||||
if (R_CheckPowersOfTwo())
|
||||
{
|
||||
R_CheckFlatLength(ds_flatwidth * ds_flatheight);
|
||||
if (spanfunc == basespanfunc)
|
||||
spanfunc = mmxspanfunc;
|
||||
}
|
||||
}
|
||||
|
||||
if (light >= LIGHTLEVELS)
|
||||
|
|
|
@ -400,10 +400,6 @@ void R_AddSpriteDefs(UINT16 wadnum)
|
|||
start = W_CheckNumForNamePwad("S_START", wadnum, 0);
|
||||
if (start == INT16_MAX)
|
||||
start = W_CheckNumForNamePwad("SS_START", wadnum, 0); //deutex compatib.
|
||||
if (start == INT16_MAX)
|
||||
start = 0; //let say S_START is lump 0
|
||||
else
|
||||
start++; // just after S_START
|
||||
|
||||
end = W_CheckNumForNamePwad("S_END",wadnum,start);
|
||||
if (end == INT16_MAX)
|
||||
|
@ -417,9 +413,16 @@ void R_AddSpriteDefs(UINT16 wadnum)
|
|||
return;
|
||||
}
|
||||
|
||||
// ignore skin wads (we don't want skin sprites interfering with vanilla sprites)
|
||||
if (start == 0 && W_CheckNumForNamePwad("S_SKIN", wadnum, 0) != UINT16_MAX)
|
||||
return;
|
||||
if (start == INT16_MAX)
|
||||
{
|
||||
// ignore skin wads (we don't want skin sprites interfering with vanilla sprites)
|
||||
if (W_CheckNumForNamePwad("S_SKIN", wadnum, 0) != UINT16_MAX)
|
||||
return;
|
||||
|
||||
start = 0; //let say S_START is lump 0
|
||||
}
|
||||
else
|
||||
start++; // just after S_START
|
||||
|
||||
if (end == INT16_MAX)
|
||||
{
|
||||
|
@ -441,7 +444,7 @@ void R_AddSpriteDefs(UINT16 wadnum)
|
|||
{
|
||||
#ifdef HWRENDER
|
||||
if (rendermode == render_opengl)
|
||||
HWR_AddSpriteMD2(i);
|
||||
HWR_AddSpriteModel(i);
|
||||
#endif
|
||||
// if a new sprite was added (not just replaced)
|
||||
addsprites++;
|
||||
|
@ -755,10 +758,13 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
|||
dc_translation = R_GetTranslationColormap(TC_RAINBOW, vis->mobj->color, GTC_CACHE);
|
||||
else if (!(vis->cut & SC_PRECIP)
|
||||
&& vis->mobj->player && vis->mobj->player->dashmode >= DASHMODE_THRESHOLD
|
||||
&& (vis->mobj->player->charflags & (SF_DASHMODE|SF_MACHINE)) == (SF_DASHMODE|SF_MACHINE)
|
||||
&& (vis->mobj->player->charflags & SF_DASHMODE)
|
||||
&& ((leveltime/2) & 1))
|
||||
{
|
||||
dc_translation = R_GetTranslationColormap(TC_DASHMODE, 0, GTC_CACHE);
|
||||
if (vis->mobj->player->charflags & SF_MACHINE)
|
||||
dc_translation = R_GetTranslationColormap(TC_DASHMODE, 0, GTC_CACHE);
|
||||
else
|
||||
dc_translation = R_GetTranslationColormap(TC_RAINBOW, vis->mobj->color, GTC_CACHE);
|
||||
}
|
||||
else if (!(vis->cut & SC_PRECIP) && vis->mobj->skin && vis->mobj->sprite == SPR_PLAY) // MT_GHOST LOOKS LIKE A PLAYER SO USE THE PLAYER TRANSLATION TABLES. >_>
|
||||
{
|
||||
|
@ -783,10 +789,13 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
|||
dc_translation = R_GetTranslationColormap(TC_RAINBOW, vis->mobj->color, GTC_CACHE);
|
||||
else if (!(vis->cut & SC_PRECIP)
|
||||
&& vis->mobj->player && vis->mobj->player->dashmode >= DASHMODE_THRESHOLD
|
||||
&& (vis->mobj->player->charflags & (SF_DASHMODE|SF_MACHINE)) == (SF_DASHMODE|SF_MACHINE)
|
||||
&& (vis->mobj->player->charflags & SF_DASHMODE)
|
||||
&& ((leveltime/2) & 1))
|
||||
{
|
||||
dc_translation = R_GetTranslationColormap(TC_DASHMODE, 0, GTC_CACHE);
|
||||
if (vis->mobj->player->charflags & SF_MACHINE)
|
||||
dc_translation = R_GetTranslationColormap(TC_DASHMODE, 0, GTC_CACHE);
|
||||
else
|
||||
dc_translation = R_GetTranslationColormap(TC_RAINBOW, vis->mobj->color, GTC_CACHE);
|
||||
}
|
||||
else if (!(vis->cut & SC_PRECIP) && vis->mobj->skin && vis->mobj->sprite == SPR_PLAY) // This thing is a player!
|
||||
{
|
||||
|
@ -2551,7 +2560,7 @@ UINT8 P_GetSkinSprite2(skin_t *skin, UINT8 spr2, player_t *player)
|
|||
if ((playersprite_t)(spr2 & ~FF_SPR2SUPER) >= free_spr2)
|
||||
return 0;
|
||||
|
||||
while (!(skin->sprites[spr2].numframes)
|
||||
while (!skin->sprites[spr2].numframes
|
||||
&& spr2 != SPR2_STND
|
||||
&& ++i < 32) // recursion limiter
|
||||
{
|
||||
|
@ -3181,7 +3190,7 @@ next_token:
|
|||
|
||||
#ifdef HWRENDER
|
||||
if (rendermode == render_opengl)
|
||||
HWR_AddPlayerMD2(numskins);
|
||||
HWR_AddPlayerModel(numskins);
|
||||
#endif
|
||||
|
||||
numskins++;
|
||||
|
|
|
@ -64,6 +64,8 @@ static void ModFilter_OnChange(void);
|
|||
|
||||
static lumpnum_t S_GetMusicLumpNum(const char *mname);
|
||||
|
||||
static boolean S_CheckQueue(void);
|
||||
|
||||
// commands for music and sound servers
|
||||
#ifdef MUSSERV
|
||||
consvar_t musserver_cmd = {"musserver_cmd", "musserver", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
@ -1613,13 +1615,14 @@ static void S_AddMusicStackEntry(const char *mname, UINT16 mflags, boolean loopi
|
|||
if (!music_stacks)
|
||||
{
|
||||
music_stacks = Z_Calloc(sizeof (*mst), PU_MUSIC, NULL);
|
||||
strncpy(music_stacks->musname, (status == JT_MASTER ? mname : mapmusname), 7);
|
||||
music_stacks->musflags = (status == JT_MASTER ? mflags : mapmusflags);
|
||||
music_stacks->looping = (status == JT_MASTER ? looping : true);
|
||||
music_stacks->position = (status == JT_MASTER ? position : S_GetMusicPosition());
|
||||
strncpy(music_stacks->musname, (status == JT_MASTER ? mname : (S_CheckQueue() ? queue_name : mapmusname)), 7);
|
||||
music_stacks->musflags = (status == JT_MASTER ? mflags : (S_CheckQueue() ? queue_flags : mapmusflags));
|
||||
music_stacks->looping = (status == JT_MASTER ? looping : (S_CheckQueue() ? queue_looping : true));
|
||||
music_stacks->position = (status == JT_MASTER ? position : (S_CheckQueue() ? queue_position : S_GetMusicPosition()));
|
||||
music_stacks->tic = gametic;
|
||||
music_stacks->status = JT_MASTER;
|
||||
music_stacks->mlumpnum = S_GetMusicLumpNum(music_stacks->musname);
|
||||
music_stacks->noposition = S_CheckQueue();
|
||||
|
||||
if (status == JT_MASTER)
|
||||
return; // we just added the user's entry here
|
||||
|
@ -1638,6 +1641,7 @@ static void S_AddMusicStackEntry(const char *mname, UINT16 mflags, boolean loopi
|
|||
new_mst->tic = gametic;
|
||||
new_mst->status = status;
|
||||
new_mst->mlumpnum = S_GetMusicLumpNum(new_mst->musname);
|
||||
new_mst->noposition = false;
|
||||
|
||||
mst->next = new_mst;
|
||||
new_mst->prev = mst;
|
||||
|
@ -1745,11 +1749,23 @@ boolean S_RecallMusic(UINT16 status, boolean fromfirst)
|
|||
entry->tic = gametic;
|
||||
entry->status = JT_MASTER;
|
||||
entry->mlumpnum = S_GetMusicLumpNum(entry->musname);
|
||||
entry->noposition = false; // don't set this until we do the mapmuschanged check, below. Else, this breaks some resumes.
|
||||
}
|
||||
|
||||
if (entry->status == JT_MASTER)
|
||||
{
|
||||
mapmuschanged = strnicmp(entry->musname, mapmusname, 7);
|
||||
if (mapmuschanged)
|
||||
{
|
||||
strncpy(entry->musname, mapmusname, 7);
|
||||
entry->musflags = mapmusflags;
|
||||
entry->looping = true;
|
||||
entry->position = mapmusposition;
|
||||
entry->tic = gametic;
|
||||
entry->status = JT_MASTER;
|
||||
entry->mlumpnum = S_GetMusicLumpNum(entry->musname);
|
||||
entry->noposition = true;
|
||||
}
|
||||
S_ResetMusicStack();
|
||||
}
|
||||
else if (!entry->status)
|
||||
|
@ -1758,7 +1774,7 @@ boolean S_RecallMusic(UINT16 status, boolean fromfirst)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!mapmuschanged && strncmp(entry->musname, S_MusicName(), 7)) // don't restart music if we're already playing it
|
||||
if (strncmp(entry->musname, S_MusicName(), 7)) // don't restart music if we're already playing it
|
||||
{
|
||||
if (music_stack_fadeout)
|
||||
S_ChangeMusicEx(entry->musname, entry->musflags, entry->looping, 0, music_stack_fadeout, 0);
|
||||
|
@ -1766,7 +1782,7 @@ boolean S_RecallMusic(UINT16 status, boolean fromfirst)
|
|||
{
|
||||
S_ChangeMusicEx(entry->musname, entry->musflags, entry->looping, 0, 0, music_stack_fadein);
|
||||
|
||||
if (!music_stack_noposition) // HACK: Global boolean to toggle position resuming, e.g., de-superize
|
||||
if (!entry->noposition && !music_stack_noposition) // HACK: Global boolean to toggle position resuming, e.g., de-superize
|
||||
{
|
||||
UINT32 poslapse = 0;
|
||||
|
||||
|
@ -1908,6 +1924,11 @@ static void S_QueueMusic(const char *mmusic, UINT16 mflags, boolean looping, UIN
|
|||
queue_fadeinms = fadeinms;
|
||||
}
|
||||
|
||||
static boolean S_CheckQueue(void)
|
||||
{
|
||||
return queue_name[0];
|
||||
}
|
||||
|
||||
static void S_ClearQueue(void)
|
||||
{
|
||||
queue_name[0] = queue_flags = queue_looping = queue_position = queue_fadeinms = 0;
|
||||
|
|
|
@ -220,6 +220,7 @@ typedef struct musicstack_s
|
|||
tic_t tic;
|
||||
UINT16 status;
|
||||
lumpnum_t mlumpnum;
|
||||
boolean noposition; // force music stack resuming from zero (like music_stack_noposition)
|
||||
|
||||
struct musicstack_s *prev;
|
||||
struct musicstack_s *next;
|
||||
|
|
|
@ -229,6 +229,10 @@
|
|||
<ClInclude Include="..\hardware\hw_light.h" />
|
||||
<ClInclude Include="..\hardware\hw_main.h" />
|
||||
<ClInclude Include="..\hardware\hw_md2.h" />
|
||||
<ClInclude Include="..\hardware\hw_md2load.h" />
|
||||
<ClInclude Include="..\hardware\hw_md3load.h" />
|
||||
<ClInclude Include="..\hardware\hw_model.h" />
|
||||
<ClInclude Include="..\hardware\u_list.h" />
|
||||
<ClInclude Include="..\hu_stuff.h" />
|
||||
<ClInclude Include="..\info.h" />
|
||||
<ClInclude Include="..\i_addrinfo.h" />
|
||||
|
@ -368,8 +372,12 @@
|
|||
<ClCompile Include="..\hardware\hw_light.c" />
|
||||
<ClCompile Include="..\hardware\hw_main.c" />
|
||||
<ClCompile Include="..\hardware\hw_md2.c" />
|
||||
<ClCompile Include="..\hardware\hw_md2load.c" />
|
||||
<ClCompile Include="..\hardware\hw_md3load.c" />
|
||||
<ClCompile Include="..\hardware\hw_model.c" />
|
||||
<ClCompile Include="..\hardware\hw_trick.c" />
|
||||
<ClCompile Include="..\hardware\r_opengl\r_opengl.c" />
|
||||
<ClCompile Include="..\hardware\u_list.c" />
|
||||
<ClCompile Include="..\hu_stuff.c" />
|
||||
<ClCompile Include="..\info.c" />
|
||||
<ClCompile Include="..\i_addrinfo.c">
|
||||
|
|
|
@ -246,6 +246,18 @@
|
|||
<ClInclude Include="..\hardware\hw_md2.h">
|
||||
<Filter>Hw_Hardware</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\hardware\hw_md2load.h">
|
||||
<Filter>Hw_Hardware</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\hardware\hw_md3load.h">
|
||||
<Filter>Hw_Hardware</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\hardware\hw_model.h">
|
||||
<Filter>Hw_Hardware</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\hardware\u_list.h">
|
||||
<Filter>Hw_Hardware</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\byteptr.h">
|
||||
<Filter>I_Interface</Filter>
|
||||
</ClInclude>
|
||||
|
@ -630,9 +642,21 @@
|
|||
<ClCompile Include="..\hardware\hw_md2.c">
|
||||
<Filter>Hw_Hardware</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\hardware\hw_md2load.c">
|
||||
<Filter>Hw_Hardware</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\hardware\hw_md3load.c">
|
||||
<Filter>Hw_Hardware</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\hardware\hw_model.c">
|
||||
<Filter>Hw_Hardware</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\hardware\hw_trick.c">
|
||||
<Filter>Hw_Hardware</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\hardware\u_list.c">
|
||||
<Filter>Hw_Hardware</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\filesrch.c">
|
||||
<Filter>I_Interface</Filter>
|
||||
</ClCompile>
|
||||
|
|
|
@ -88,13 +88,11 @@ void *hwSym(const char *funcName,void *handle)
|
|||
GETFUNC(ClearMipMapCache);
|
||||
GETFUNC(SetSpecialState);
|
||||
GETFUNC(GetTextureUsed);
|
||||
GETFUNC(DrawMD2);
|
||||
GETFUNC(DrawMD2i);
|
||||
GETFUNC(DrawModel);
|
||||
GETFUNC(CreateModelVBOs);
|
||||
GETFUNC(SetTransform);
|
||||
GETFUNC(GetRenderVersion);
|
||||
#ifdef SHUFFLE
|
||||
GETFUNC(PostImgRedraw);
|
||||
#endif //SHUFFLE
|
||||
GETFUNC(FlushScreenTextures);
|
||||
GETFUNC(StartScreenWipe);
|
||||
GETFUNC(EndScreenWipe);
|
||||
|
|
|
@ -1654,13 +1654,11 @@ void I_StartupGraphics(void)
|
|||
HWD.pfnSetSpecialState = hwSym("SetSpecialState",NULL);
|
||||
HWD.pfnSetPalette = hwSym("SetPalette",NULL);
|
||||
HWD.pfnGetTextureUsed = hwSym("GetTextureUsed",NULL);
|
||||
HWD.pfnDrawMD2 = hwSym("DrawMD2",NULL);
|
||||
HWD.pfnDrawMD2i = hwSym("DrawMD2i",NULL);
|
||||
HWD.pfnDrawModel = hwSym("DrawModel",NULL);
|
||||
HWD.pfnCreateModelVBOs = hwSym("CreateModelVBOs",NULL);
|
||||
HWD.pfnSetTransform = hwSym("SetTransform",NULL);
|
||||
HWD.pfnGetRenderVersion = hwSym("GetRenderVersion",NULL);
|
||||
#ifdef SHUFFLE
|
||||
HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL);
|
||||
#endif
|
||||
HWD.pfnFlushScreenTextures=hwSym("FlushScreenTextures",NULL);
|
||||
HWD.pfnStartScreenWipe = hwSym("StartScreenWipe",NULL);
|
||||
HWD.pfnEndScreenWipe = hwSym("EndScreenWipe",NULL);
|
||||
|
|
|
@ -693,7 +693,7 @@ sfxinfo_t S_sfx[NUMSFX] =
|
|||
{"cdfm37", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"cdfm38", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Drowning"},
|
||||
{"cdfm39", false, 128, 8, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"cdfm40", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"cdfm40", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Power up"},
|
||||
{"cdfm41", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"cdfm42", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"cdfm43", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
|
@ -780,7 +780,7 @@ sfxinfo_t S_sfx[NUMSFX] =
|
|||
{"kc4a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"kc4b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"kc4c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"kc4d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"kc4d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Power up"},
|
||||
{"kc4e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"kc4f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"kc50", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
|
@ -804,7 +804,7 @@ sfxinfo_t S_sfx[NUMSFX] =
|
|||
{"kc62", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"kc63", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"kc64", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Terrifying rumble"},
|
||||
{"kc65", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"kc65", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Power down"},
|
||||
{"kc66", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"kc67", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"kc68", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
|
|
|
@ -89,8 +89,8 @@ static void CV_Gammaxxx_ONChange(void);
|
|||
// but they won't do anything.
|
||||
static CV_PossibleValue_t grgamma_cons_t[] = {{1, "MIN"}, {255, "MAX"}, {0, NULL}};
|
||||
static CV_PossibleValue_t grsoftwarefog_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "LightPlanes"}, {0, NULL}};
|
||||
static CV_PossibleValue_t grmodelinterpolation_cons_t[] = {{0, "Off"}, {1, "Sometimes"}, {2, "Always"}, {0, NULL}};
|
||||
|
||||
consvar_t cv_voodoocompatibility = {"gr_voodoocompatibility", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_grfovchange = {"gr_fovchange", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_grfog = {"gr_fog", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_grfogcolor = {"gr_fogcolor", "AAAAAA", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
@ -108,9 +108,9 @@ consvar_t cv_grcoronas = {"gr_coronas", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL,
|
|||
consvar_t cv_grcoronasize = {"gr_coronasize", "1", CV_SAVE| CV_FLOAT, 0, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
#endif
|
||||
|
||||
static CV_PossibleValue_t CV_MD2[] = {{0, "Off"}, {1, "On"}, {2, "Old"}, {0, NULL}};
|
||||
// console variables in development
|
||||
consvar_t cv_grmd2 = {"gr_md2", "Off", CV_SAVE, CV_MD2, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_grmodels = {"gr_models", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_grmodelinterpolation = {"gr_modelinterpolation", "Sometimes", CV_SAVE, grmodelinterpolation_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_grspritebillboarding = {"gr_spritebillboarding", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_grskydome = {"gr_skydome", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
#endif
|
||||
|
|
12
src/w_wad.c
12
src/w_wad.c
|
@ -1565,22 +1565,22 @@ void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag)
|
|||
|
||||
grPatch = HWR_GetCachedGLPatchPwad(wad, lump);
|
||||
|
||||
if (grPatch->mipmap.grInfo.data)
|
||||
if (grPatch->mipmap->grInfo.data)
|
||||
{
|
||||
if (tag == PU_CACHE)
|
||||
tag = PU_HWRCACHE;
|
||||
Z_ChangeTag(grPatch->mipmap.grInfo.data, tag);
|
||||
Z_ChangeTag(grPatch->mipmap->grInfo.data, tag);
|
||||
}
|
||||
else
|
||||
{
|
||||
patch_t *ptr = NULL;
|
||||
|
||||
// Only load the patch if we haven't initialised the grPatch yet
|
||||
if (grPatch->mipmap.width == 0)
|
||||
if (grPatch->mipmap->width == 0)
|
||||
ptr = W_CacheLumpNumPwad(grPatch->wadnum, grPatch->lumpnum, PU_STATIC);
|
||||
|
||||
// Run HWR_MakePatch in all cases, to recalculate some things
|
||||
HWR_MakePatch(ptr, grPatch, &grPatch->mipmap, false);
|
||||
HWR_MakePatch(ptr, grPatch, grPatch->mipmap, false);
|
||||
Z_Free(ptr);
|
||||
}
|
||||
|
||||
|
@ -1679,12 +1679,12 @@ void W_VerifyFileMD5(UINT16 wadfilenum, const char *matchmd5)
|
|||
{
|
||||
char actualmd5text[2*MD5_LEN+1];
|
||||
PrintMD5String(wadfiles[wadfilenum]->md5sum, actualmd5text);
|
||||
#ifdef _DEBUG
|
||||
/*#ifdef _DEBUG
|
||||
CONS_Printf
|
||||
#else
|
||||
I_Error
|
||||
#endif
|
||||
(M_GetText("File is corrupt or has been modified: %s (found md5: %s, wanted: %s)\n"), wadfiles[wadfilenum]->filename, actualmd5text, matchmd5);
|
||||
(M_GetText("File is corrupt or has been modified: %s (found md5: %s, wanted: %s)\n"), wadfiles[wadfilenum]->filename, actualmd5text, matchmd5);*/
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -231,7 +231,11 @@
|
|||
<ClCompile Include="..\hardware\hw_light.c" />
|
||||
<ClCompile Include="..\hardware\hw_main.c" />
|
||||
<ClCompile Include="..\hardware\hw_md2.c" />
|
||||
<ClCompile Include="..\hardware\hw_md2load.c" />
|
||||
<ClCompile Include="..\hardware\hw_md3load.c" />
|
||||
<ClCompile Include="..\hardware\hw_model.c" />
|
||||
<ClCompile Include="..\hardware\hw_trick.c" />
|
||||
<ClCompile Include="..\hardware\u_list.c" />
|
||||
<ClCompile Include="..\hu_stuff.c" />
|
||||
<ClCompile Include="..\info.c" />
|
||||
<ClCompile Include="..\i_addrinfo.c">
|
||||
|
@ -396,6 +400,10 @@
|
|||
<ClInclude Include="..\hardware\hw_light.h" />
|
||||
<ClInclude Include="..\hardware\hw_main.h" />
|
||||
<ClInclude Include="..\hardware\hw_md2.h" />
|
||||
<ClInclude Include="..\hardware\hw_md2load.h" />
|
||||
<ClInclude Include="..\hardware\hw_md3load.h" />
|
||||
<ClInclude Include="..\hardware\hw_model.h" />
|
||||
<ClInclude Include="..\hardware\u_list.h" />
|
||||
<ClInclude Include="..\hu_stuff.h" />
|
||||
<ClInclude Include="..\info.h" />
|
||||
<ClInclude Include="..\i_addrinfo.h" />
|
||||
|
|
|
@ -453,6 +453,18 @@
|
|||
<ClCompile Include="..\string.c">
|
||||
<Filter>M_Misc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\hardware\hw_md2load.c">
|
||||
<Filter>Hw_Hardware</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\hardware\hw_md3load.c">
|
||||
<Filter>Hw_Hardware</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\hardware\hw_model.c">
|
||||
<Filter>Hw_Hardware</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\hardware\u_list.c">
|
||||
<Filter>Hw_Hardware</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\hardware\hw_clip.c">
|
||||
<Filter>Hw_Hardware</Filter>
|
||||
</ClCompile>
|
||||
|
@ -513,6 +525,15 @@
|
|||
<ClInclude Include="..\hardware\hw_md2.h">
|
||||
<Filter>Hw_Hardware</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\hardware\hw_md2load.h">
|
||||
<Filter>Hw_Hardware</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\hardware\hw_md3load.h">
|
||||
<Filter>Hw_Hardware</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\hardware\hw_model.h">
|
||||
<Filter>Hw_Hardware</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\hardware\hw3dsdrv.h">
|
||||
<Filter>Hw_Hardware</Filter>
|
||||
</ClInclude>
|
||||
|
@ -522,6 +543,9 @@
|
|||
<ClInclude Include="..\hardware\hws_data.h">
|
||||
<Filter>Hw_Hardware</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\hardware\u_list.h">
|
||||
<Filter>Hw_Hardware</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\blua\lapi.h">
|
||||
<Filter>BLUA</Filter>
|
||||
</ClInclude>
|
||||
|
|
|
@ -110,8 +110,7 @@ static loadfunc_t hwdFuncTable[] = {
|
|||
{"GClipRect@20", &hwdriver.pfnGClipRect},
|
||||
{"ClearMipMapCache@0", &hwdriver.pfnClearMipMapCache},
|
||||
{"SetSpecialState@8", &hwdriver.pfnSetSpecialState},
|
||||
{"DrawMD2@16", &hwdriver.pfnDrawMD2},
|
||||
{"DrawMD2i@36", &hwdriver.pfnDrawMD2i},
|
||||
{"DrawModel@16", &hwdriver.pfnDrawModel},
|
||||
{"SetTransform@4", &hwdriver.pfnSetTransform},
|
||||
{"GetTextureUsed@0", &hwdriver.pfnGetTextureUsed},
|
||||
{"GetRenderVersion@0", &hwdriver.pfnGetRenderVersion},
|
||||
|
@ -142,8 +141,7 @@ static loadfunc_t hwdFuncTable[] = {
|
|||
{"GClipRect", &hwdriver.pfnGClipRect},
|
||||
{"ClearMipMapCache", &hwdriver.pfnClearMipMapCache},
|
||||
{"SetSpecialState", &hwdriver.pfnSetSpecialState},
|
||||
{"DrawMD2", &hwdriver.pfnDrawMD2},
|
||||
{"DrawMD2i", &hwdriver.pfnDrawMD2i},
|
||||
{"DrawModel", &hwdriver.pfnDrawModel},
|
||||
{"SetTransform", &hwdriver.pfnSetTransform},
|
||||
{"GetTextureUsed", &hwdriver.pfnGetTextureUsed},
|
||||
{"GetRenderVersion", &hwdriver.pfnGetRenderVersion},
|
||||
|
|
|
@ -2131,7 +2131,7 @@ static void Y_AwardSpecialStageBonus(void)
|
|||
|
||||
data.spec.score = players[consoleplayer].score;
|
||||
memset(data.spec.bonuses, 0, sizeof(data.spec.bonuses));
|
||||
memset(data.spec.bonuspatches, 0, sizeof(data.coop.bonuspatches));
|
||||
memset(data.spec.bonuspatches, 0, sizeof(data.spec.bonuspatches));
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
|
|
|
@ -247,7 +247,11 @@ void Z_Free(void *ptr)
|
|||
static void *xm(size_t size)
|
||||
{
|
||||
const size_t padedsize = size+sizeof (size_t);
|
||||
void *p = malloc(padedsize);
|
||||
void *p;
|
||||
|
||||
if (padedsize < size)/* overflow check */
|
||||
I_Error("You are allocating memory too large!");
|
||||
p = malloc(padedsize);
|
||||
|
||||
if (p == NULL)
|
||||
{
|
||||
|
@ -295,6 +299,9 @@ void *Z_MallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits)
|
|||
CONS_Debug(DBG_MEMORY, "Z_Malloc %s:%d\n", file, line);
|
||||
#endif
|
||||
|
||||
if (blocksize < size)/* overflow check */
|
||||
I_Error("You are allocating memory too large!");
|
||||
|
||||
block = xm(sizeof *block);
|
||||
#ifdef HAVE_VALGRIND
|
||||
padsize += (1<<sizeof(size_t))*2;
|
||||
|
|
Loading…
Reference in a new issue