Merge branch 'master' of https://git.magicalgirl.moe/STJr/SRB2Internal.git into metalrecording

# Conflicts:
#	src/p_user.c
This commit is contained in:
toaster 2019-11-12 21:56:46 +00:00
commit 5729ba3cd2
69 changed files with 5905 additions and 2319 deletions

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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");

View File

@ -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__

View File

@ -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

View File

@ -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,

View File

@ -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",

View File

@ -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;

File diff suppressed because it is too large Load Diff

View File

@ -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);

View File

@ -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();

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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_

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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);
}
//**********************************************************

View File

@ -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

View File

@ -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

View File

@ -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
View 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
View 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
View 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
View 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
View 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
View 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

View File

@ -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

View File

@ -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
// ==========================================================================

View 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
View 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
View 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

View File

@ -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
},

View File

@ -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,

View File

@ -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(");

View File

@ -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);

View File

@ -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)

View File

@ -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.

View File

@ -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;
}

View File

@ -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])
{

View File

@ -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

View File

@ -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;
}

View File

@ -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();

View File

@ -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;

View File

@ -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);
}
}
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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

View File

@ -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)

View File

@ -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++;

View File

@ -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;

View File

@ -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;

View File

@ -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">

View File

@ -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>

View File

@ -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);

View File

@ -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);

View File

@ -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, ""},

View File

@ -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

View File

@ -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
}

View File

@ -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" />

View File

@ -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>

View File

@ -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},

View File

@ -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++)
{

View File

@ -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;