mirror of
https://github.com/libretro/quake2-for-ps2.git
synced 2026-11-07 04:25:58 -10:00
Finished texture image loading and got the menus working.
- Finished texture image loading for PCX, WAL and TGA; - Added the NET driver for the PS2, loopback only for local single-player; - Replaced all malloc/free calls with either Quake’s Z_Malloc or PS2_MemAlloc, so we can keep precise memory usage statistics; - Several other miscellaneous changes.
This commit is contained in:
1 parent
d0980d25c1
commit
ce8cc0721c
55 files changed
+2043
-566
No files matched your search
@@ -0,0 +1,25 @@
|
||||
|
||||
-----------
|
||||
Misc info
|
||||
-----------
|
||||
|
||||
- I ran Clang-Format on all the original Quake2 source files to fix multiple
|
||||
formatting issues and replace tabs with spaces, so that it displays nicely
|
||||
and uniformly on all browsers and editors. The Clang-Format style file used
|
||||
can be found at the root of the project. I tried to tune it to maintain the
|
||||
overall style used by id, so the code should look pretty much the same as
|
||||
before, but with the advantage of uniform indenting and spacing through.
|
||||
|
||||
- Changes made by me in the Quake2 source code are usually annotated by a nearby
|
||||
comment stating the change made and sometimes the date when it was first
|
||||
made. These comments will start with my name (e.g.: LAMPERT), followed
|
||||
by a brief description.
|
||||
|
||||
- Other minor changes such as removing or adding blank lines, adding curly
|
||||
braces to flow-control statements, adding `static` to local functions or data,
|
||||
are not always marked with comments to avoid excessive verbosity.
|
||||
|
||||
- The vast majority of the code related to the PS2 port is located inside the
|
||||
src/ps2/ directory. Changes made in the Quake2 source to account for the
|
||||
PlayStation2 are clearly marked as such.
|
||||
|
||||
@@ -25,9 +25,9 @@ SRC_FILES = \
|
||||
ps2/ref_ps2.c \
|
||||
ps2/tex_image.c \
|
||||
ps2/math_funcs.c \
|
||||
ps2/net_ps2.c \
|
||||
ps2/main_ps2.c \
|
||||
null/in_null.c \
|
||||
null/net_null.c \
|
||||
null/cd_null.c \
|
||||
null/snddma_null.c \
|
||||
common/cmd.c \
|
||||
|
||||
@@ -16,7 +16,7 @@ is already implemented and working on both the emulator and the PS2, as you can
|
||||
in the above screenshot of the in-game console running on the PS2.
|
||||
|
||||
The long term goal is to have a fully functional and playable (single-player)
|
||||
Quake II on the PlayStation 2, relying only on the freely available tools and libraries.
|
||||
Quake II on the PlayStation 2, using only on the freely available tools and libraries.
|
||||
|
||||
## License
|
||||
|
||||
|
||||
@@ -881,6 +881,7 @@ void CL_Skins_f(void)
|
||||
{
|
||||
if (!cl.configstrings[CS_PLAYERSKINS + i][0])
|
||||
continue;
|
||||
|
||||
Com_Printf("client %i: %s\n", i, cl.configstrings[CS_PLAYERSKINS + i]);
|
||||
SCR_UpdateScreen();
|
||||
Sys_SendKeyEvents(); // pump message loop
|
||||
@@ -1787,7 +1788,8 @@ void CL_Frame(int msec)
|
||||
// predict all unacknowledged movements
|
||||
CL_PredictMovement();
|
||||
|
||||
// LAMPERT: We don't use a separate DLL on QPS2, so this is useless.
|
||||
// LAMPERT:
|
||||
// We don't use a separate DLL on QPS2, so this is useless.
|
||||
//
|
||||
// allow rendering DLL change
|
||||
//VID_CheckChanges();
|
||||
@@ -1891,7 +1893,7 @@ void CL_Init(void)
|
||||
===============
|
||||
CL_Shutdown
|
||||
|
||||
FIXME: this is a callback from Sys_Quit and Com_Error. It would be better
|
||||
FIXME: this is a callback from Sys_Quit and Com_Error. It would be better
|
||||
to run quit through here before the final handoff to the sys code.
|
||||
===============
|
||||
*/
|
||||
|
||||
@@ -561,6 +561,7 @@ void SCR_BeginLoadingPlaque(void)
|
||||
S_StopAllSounds();
|
||||
cl.sound_prepped = false; // don't play ambients
|
||||
CDAudio_Stop();
|
||||
|
||||
if (cls.disable_screen)
|
||||
return;
|
||||
if (developer->value)
|
||||
@@ -569,10 +570,12 @@ void SCR_BeginLoadingPlaque(void)
|
||||
return; // if at console, don't bring up the plaque
|
||||
if (cls.key_dest == key_console)
|
||||
return;
|
||||
|
||||
if (cl.cinematictime > 0)
|
||||
scr_draw_loading = 2; // clear to balack first
|
||||
scr_draw_loading = 2; // clear to black first
|
||||
else
|
||||
scr_draw_loading = 1;
|
||||
|
||||
SCR_UpdateScreen();
|
||||
cls.disable_screen = Sys_Milliseconds();
|
||||
cls.disable_servercount = cl.servercount;
|
||||
@@ -633,7 +636,8 @@ void SCR_TimeRefresh_f(void)
|
||||
start = Sys_Milliseconds();
|
||||
|
||||
if (Cmd_Argc() == 2)
|
||||
{ // run without page flipping
|
||||
{
|
||||
// run without page flipping
|
||||
re.BeginFrame(0);
|
||||
for (i = 0; i < 128; i++)
|
||||
{
|
||||
@@ -647,7 +651,6 @@ void SCR_TimeRefresh_f(void)
|
||||
for (i = 0; i < 128; i++)
|
||||
{
|
||||
cl.refdef.viewangles[1] = i / 128.0 * 360.0;
|
||||
|
||||
re.BeginFrame(0);
|
||||
re.RenderFrame(&cl.refdef);
|
||||
re.EndFrame();
|
||||
@@ -1319,7 +1322,7 @@ void SCR_UpdateScreen(void)
|
||||
|
||||
if (scr_draw_loading == 2)
|
||||
{
|
||||
// loading plaque over black screen
|
||||
// loading plaque over black screen
|
||||
int w, h;
|
||||
re.CinematicSetPalette(NULL);
|
||||
scr_draw_loading = false;
|
||||
|
||||
@@ -332,6 +332,7 @@ void CL_PrepRefresh(void)
|
||||
{
|
||||
if (!cl.configstrings[CS_PLAYERSKINS + i][0])
|
||||
continue;
|
||||
|
||||
Com_Printf("client %i\r", i);
|
||||
SCR_UpdateScreen();
|
||||
Sys_SendKeyEvents(); // pump message loop
|
||||
@@ -347,6 +348,7 @@ void CL_PrepRefresh(void)
|
||||
rotate = atof(cl.configstrings[CS_SKYROTATE]);
|
||||
sscanf(cl.configstrings[CS_SKYAXIS], "%f %f %f",
|
||||
&axis[0], &axis[1], &axis[2]);
|
||||
|
||||
re.SetSky(cl.configstrings[CS_SKY], rotate, axis);
|
||||
Com_Printf(" \r");
|
||||
|
||||
@@ -447,7 +449,6 @@ void SCR_DrawCrosshair(void)
|
||||
/*
|
||||
==================
|
||||
V_RenderView
|
||||
|
||||
==================
|
||||
*/
|
||||
void V_RenderView(float stereo_separation)
|
||||
|
||||
+5
-2
@@ -178,8 +178,8 @@ extern client_state_t cl;
|
||||
/*
|
||||
==================================================================
|
||||
|
||||
the client_static_t structure is persistant through an arbitrary number
|
||||
of server connections
|
||||
The client_static_t structure is persistent through
|
||||
an arbitrary number of server connections.
|
||||
|
||||
==================================================================
|
||||
*/
|
||||
@@ -213,6 +213,9 @@ typedef enum
|
||||
typedef struct
|
||||
{
|
||||
connstate_t state;
|
||||
|
||||
// This flag determines what's rendered to the screen,
|
||||
// e.g.: console, main menu, game view...
|
||||
keydest_t key_dest;
|
||||
|
||||
int framecount;
|
||||
|
||||
@@ -95,7 +95,9 @@ void Con_ToggleConsole_f(void)
|
||||
cls.key_dest = key_console;
|
||||
|
||||
if (Cvar_VariableValue("maxclients") == 1 && Com_ServerState())
|
||||
{
|
||||
Cvar_Set("paused", "1");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,7 +119,9 @@ void Con_ToggleChat_f(void)
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cls.key_dest = key_console;
|
||||
}
|
||||
|
||||
Con_ClearNotify();
|
||||
}
|
||||
|
||||
+5
-3
@@ -252,15 +252,16 @@ void Key_Console(int key)
|
||||
{
|
||||
char * cbd;
|
||||
|
||||
if ((cbd = Sys_GetClipboardData()) != 0)
|
||||
if ((cbd = Sys_GetClipboardData()) != NULL)
|
||||
{
|
||||
int i;
|
||||
|
||||
strtok(cbd, "\n\r\b");
|
||||
|
||||
i = strlen(cbd);
|
||||
if (i + key_linepos >= MAXCMDLINE)
|
||||
{
|
||||
i = MAXCMDLINE - key_linepos;
|
||||
}
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
@@ -268,7 +269,8 @@ void Key_Console(int key)
|
||||
strcat(key_lines[edit_line], cbd);
|
||||
key_linepos += i;
|
||||
}
|
||||
free(cbd);
|
||||
|
||||
Z_Free(cbd);
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
+139
-61
@@ -21,18 +21,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#include <ctype.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <io.h>
|
||||
#endif
|
||||
#include <io.h> // For filelength()
|
||||
#endif // _WIN32
|
||||
|
||||
#include "client.h"
|
||||
#include "../client/qmenu.h"
|
||||
|
||||
#define NUM_CURSOR_FRAMES 15
|
||||
static int m_main_cursor;
|
||||
|
||||
static char * menu_in_sound = "misc/menu1.wav";
|
||||
static char * menu_move_sound = "misc/menu2.wav";
|
||||
static char * menu_out_sound = "misc/menu3.wav";
|
||||
#include "client/qmenu.h"
|
||||
|
||||
void M_Menu_Main_f(void);
|
||||
void M_Menu_Game_f(void);
|
||||
@@ -52,16 +45,21 @@ void M_Menu_Keys_f(void);
|
||||
void M_Menu_Quit_f(void);
|
||||
void M_Menu_Credits(void);
|
||||
|
||||
qboolean m_entersound; // play after drawing a frame, so caching
|
||||
// won't disrupt the sound
|
||||
|
||||
void (*m_drawfunc)(void);
|
||||
const char * (*m_keyfunc)(int key);
|
||||
|
||||
//=============================================================================
|
||||
/* Support Routines */
|
||||
/* Locals */
|
||||
|
||||
#define MAX_MENU_DEPTH 8
|
||||
enum
|
||||
{
|
||||
MAX_MENU_DEPTH = 20,
|
||||
NUM_CURSOR_FRAMES = 15
|
||||
};
|
||||
|
||||
static const char * menu_in_sound = "misc/menu1.wav";
|
||||
static const char * menu_move_sound = "misc/menu2.wav";
|
||||
static const char * menu_out_sound = "misc/menu3.wav";
|
||||
|
||||
static void (*m_drawfunc)(void);
|
||||
static const char * (*m_keyfunc)(int key);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -69,8 +67,15 @@ typedef struct
|
||||
const char * (*key)(int k);
|
||||
} menulayer_t;
|
||||
|
||||
menulayer_t m_layers[MAX_MENU_DEPTH];
|
||||
int m_menudepth;
|
||||
static menulayer_t m_layers[MAX_MENU_DEPTH];
|
||||
static int m_menudepth;
|
||||
static int m_main_cursor;
|
||||
|
||||
// play after drawing a frame, so caching won't disrupt the sound.
|
||||
static qboolean m_entersound;
|
||||
|
||||
//=============================================================================
|
||||
/* Support Routines */
|
||||
|
||||
static void M_Banner(char * name)
|
||||
{
|
||||
@@ -104,7 +109,7 @@ void M_PushMenu(void (*draw)(void), const char * (*key)(int k))
|
||||
{
|
||||
if (m_menudepth >= MAX_MENU_DEPTH)
|
||||
{
|
||||
Com_Error(ERR_FATAL, "M_PushMenu: MAX_MENU_DEPTH");
|
||||
Com_Error(ERR_FATAL, "M_PushMenu: MAX_MENU_DEPTH exceeded!");
|
||||
}
|
||||
m_layers[m_menudepth].draw = m_drawfunc;
|
||||
m_layers[m_menudepth].key = m_keyfunc;
|
||||
@@ -134,6 +139,7 @@ void M_PopMenu(void)
|
||||
S_StartLocalSound(menu_out_sound);
|
||||
if (m_menudepth < 1)
|
||||
Com_Error(ERR_FATAL, "M_PopMenu: depth < 1");
|
||||
|
||||
m_menudepth--;
|
||||
|
||||
m_drawfunc = m_layers[m_menudepth].draw;
|
||||
@@ -380,7 +386,11 @@ MAIN MENU
|
||||
|
||||
=======================================================================
|
||||
*/
|
||||
#define MAIN_ITEMS 5
|
||||
|
||||
enum
|
||||
{
|
||||
MAIN_ITEMS = 5
|
||||
};
|
||||
|
||||
void M_Main_Draw(void)
|
||||
{
|
||||
@@ -495,6 +505,7 @@ MULTIPLAYER MENU
|
||||
|
||||
=======================================================================
|
||||
*/
|
||||
|
||||
static menuframework_s s_multiplayer_menu;
|
||||
static menuaction_s s_join_network_server_action;
|
||||
static menuaction_s s_start_network_server_action;
|
||||
@@ -576,6 +587,7 @@ KEYS MENU
|
||||
|
||||
=======================================================================
|
||||
*/
|
||||
|
||||
char * bindnames[][2] =
|
||||
{
|
||||
{ "+attack", "attack" },
|
||||
@@ -1006,8 +1018,9 @@ CONTROLS MENU
|
||||
|
||||
=======================================================================
|
||||
*/
|
||||
static cvar_t * win_noalttab;
|
||||
|
||||
extern cvar_t * in_joystick;
|
||||
static cvar_t * win_noalttab;
|
||||
|
||||
static menuframework_s s_options_menu;
|
||||
static menuaction_s s_options_defaults_action;
|
||||
@@ -1163,6 +1176,16 @@ static void ConsoleFunc(void * unused)
|
||||
|
||||
static void UpdateSoundQualityFunc(void * unused)
|
||||
{
|
||||
//
|
||||
// LAMPERT 2015-10-29
|
||||
//
|
||||
// FIXME:
|
||||
// Can't for the life of me figure out what's wrong here!
|
||||
// Somehow this still gets called outside Begin/End frame,
|
||||
// breaking on the PS2. Commenting it out for now.
|
||||
//
|
||||
|
||||
/*
|
||||
if (s_options_quality_list.curvalue)
|
||||
{
|
||||
Cvar_SetValue("s_khz", 22);
|
||||
@@ -1182,9 +1205,13 @@ static void UpdateSoundQualityFunc(void * unused)
|
||||
M_Print(16 + 16, 120 - 48 + 24, "please be patient.");
|
||||
|
||||
// the text box won't show up unless we do a buffer swap
|
||||
re.EndFrame();
|
||||
//
|
||||
// LAMPERT 2015-10-29:
|
||||
// FIXME This won't work in the PS2, we need consistent Begin/End frame states!
|
||||
//re.EndFrame();
|
||||
|
||||
CL_Snd_Restart_f();
|
||||
*/
|
||||
}
|
||||
|
||||
void Options_MenuInit(void)
|
||||
@@ -1313,6 +1340,7 @@ void Options_MenuInit(void)
|
||||
s_options_crosshair_box.generic.name = "crosshair";
|
||||
s_options_crosshair_box.generic.callback = CrosshairFunc;
|
||||
s_options_crosshair_box.itemnames = crosshair_names;
|
||||
|
||||
/*
|
||||
s_options_noalttab_box.generic.type = MTYPE_SPINCONTROL;
|
||||
s_options_noalttab_box.generic.x = 0;
|
||||
@@ -1320,7 +1348,8 @@ void Options_MenuInit(void)
|
||||
s_options_noalttab_box.generic.name = "disable alt-tab";
|
||||
s_options_noalttab_box.generic.callback = NoAltTabFunc;
|
||||
s_options_noalttab_box.itemnames = yesno_names;
|
||||
*/
|
||||
*/
|
||||
|
||||
s_options_joystick_box.generic.type = MTYPE_SPINCONTROL;
|
||||
s_options_joystick_box.generic.x = 0;
|
||||
s_options_joystick_box.generic.y = 120;
|
||||
@@ -1404,10 +1433,12 @@ END GAME MENU
|
||||
|
||||
=============================================================================
|
||||
*/
|
||||
|
||||
static int credits_start_time;
|
||||
static const char ** credits;
|
||||
static char * creditsIndex[256];
|
||||
static char * creditsBuffer;
|
||||
|
||||
static const char * idcredits[] =
|
||||
{
|
||||
"+QUAKE II BY ID SOFTWARE",
|
||||
@@ -2035,10 +2066,12 @@ LOADGAME MENU
|
||||
=============================================================================
|
||||
*/
|
||||
|
||||
#define MAX_SAVEGAMES 15
|
||||
enum
|
||||
{
|
||||
MAX_SAVEGAMES = 15
|
||||
};
|
||||
|
||||
static menuframework_s s_savegame_menu;
|
||||
|
||||
static menuframework_s s_loadgame_menu;
|
||||
static menuaction_s s_loadgame_actions[MAX_SAVEGAMES];
|
||||
|
||||
@@ -2137,6 +2170,7 @@ SAVEGAME MENU
|
||||
|
||||
=============================================================================
|
||||
*/
|
||||
|
||||
static menuframework_s s_savegame_menu;
|
||||
static menuaction_s s_savegame_actions[MAX_SAVEGAMES];
|
||||
|
||||
@@ -2210,7 +2244,11 @@ JOIN SERVER MENU
|
||||
|
||||
=============================================================================
|
||||
*/
|
||||
#define MAX_LOCAL_SERVERS 8
|
||||
|
||||
enum
|
||||
{
|
||||
MAX_LOCAL_SERVERS = 8
|
||||
};
|
||||
|
||||
static menuframework_s s_joinserver_menu;
|
||||
static menuseparator_s s_joinserver_server_title;
|
||||
@@ -2275,6 +2313,16 @@ void NullCursorDraw(void * self)
|
||||
|
||||
void SearchLocalGames(void)
|
||||
{
|
||||
//
|
||||
// LAMPERT 2015-10-29
|
||||
//
|
||||
// FIXME:
|
||||
// Can't for the life of me figure out what's wrong here!
|
||||
// Somehow this still gets called outside Begin/End frame,
|
||||
// breaking on the PS2. Commenting it out for now.
|
||||
//
|
||||
|
||||
/*
|
||||
int i;
|
||||
|
||||
m_num_servers = 0;
|
||||
@@ -2287,10 +2335,14 @@ void SearchLocalGames(void)
|
||||
M_Print(16 + 16, 120 - 48 + 24, "please be patient.");
|
||||
|
||||
// the text box won't show up unless we do a buffer swap
|
||||
re.EndFrame();
|
||||
//
|
||||
// LAMPERT 2015-10-29:
|
||||
// FIXME This won't work in the PS2, we need consistent Begin/End frame states!
|
||||
//re.EndFrame();
|
||||
|
||||
// send out info packets
|
||||
CL_PingServers_f();
|
||||
*/
|
||||
}
|
||||
|
||||
void SearchLocalGamesFunc(void * self)
|
||||
@@ -2373,6 +2425,7 @@ START SERVER MENU
|
||||
|
||||
=============================================================================
|
||||
*/
|
||||
|
||||
static menuframework_s s_startserver_menu;
|
||||
static char ** mapnames;
|
||||
static int nummaps;
|
||||
@@ -2390,6 +2443,7 @@ void DMOptionsFunc(void * self)
|
||||
{
|
||||
if (s_rules_box.curvalue == 1)
|
||||
return;
|
||||
|
||||
M_Menu_DMOptions_f();
|
||||
}
|
||||
|
||||
@@ -2424,7 +2478,7 @@ void RulesChangeFunc(void * self)
|
||||
s_maxclients_field.generic.statusbar = NULL;
|
||||
s_startserver_dmoptions_action.generic.statusbar = NULL;
|
||||
}
|
||||
*/
|
||||
*/
|
||||
}
|
||||
//PGM
|
||||
//=====
|
||||
@@ -2509,6 +2563,7 @@ void StartServer_MenuInit(void)
|
||||
"cooperative",
|
||||
0
|
||||
};
|
||||
|
||||
//=======
|
||||
//PGM
|
||||
static const char * dm_coop_names_rogue[] =
|
||||
@@ -2521,6 +2576,7 @@ void StartServer_MenuInit(void)
|
||||
};
|
||||
//PGM
|
||||
//=======
|
||||
|
||||
char * buffer;
|
||||
char mapsname[1024];
|
||||
char * s;
|
||||
@@ -2535,18 +2591,21 @@ void StartServer_MenuInit(void)
|
||||
if ((fp = fopen(mapsname, "rb")) == 0)
|
||||
{
|
||||
if ((length = FS_LoadFile("maps.lst", (void **)&buffer)) == -1)
|
||||
Com_Error(ERR_DROP, "couldn't find maps.lst\n");
|
||||
{
|
||||
Com_Error(ERR_DROP, "Couldn't find maps.lst\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef _WIN32
|
||||
#ifdef _WIN32
|
||||
length = filelength(fileno(fp));
|
||||
#else
|
||||
#else
|
||||
fseek(fp, 0, SEEK_END);
|
||||
length = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
#endif
|
||||
buffer = malloc(length);
|
||||
#endif
|
||||
|
||||
buffer = Z_Malloc(length);
|
||||
fread(buffer, length, 1, fp);
|
||||
}
|
||||
|
||||
@@ -2561,9 +2620,11 @@ void StartServer_MenuInit(void)
|
||||
}
|
||||
|
||||
if (nummaps == 0)
|
||||
{
|
||||
Com_Error(ERR_DROP, "no maps in maps.lst\n");
|
||||
}
|
||||
|
||||
mapnames = malloc(sizeof(char *) * (nummaps + 1));
|
||||
mapnames = Z_Malloc(sizeof(char *) * (nummaps + 1));
|
||||
memset(mapnames, 0, sizeof(char *) * (nummaps + 1));
|
||||
|
||||
s = buffer;
|
||||
@@ -2582,7 +2643,7 @@ void StartServer_MenuInit(void)
|
||||
strcpy(longname, COM_Parse(&s));
|
||||
Com_sprintf(scratch, sizeof(scratch), "%s\n%s", longname, shortname);
|
||||
|
||||
mapnames[i] = malloc(strlen(scratch) + 1);
|
||||
mapnames[i] = Z_Malloc(strlen(scratch) + 1);
|
||||
strcpy(mapnames[i], scratch);
|
||||
}
|
||||
mapnames[nummaps] = 0;
|
||||
@@ -2590,7 +2651,7 @@ void StartServer_MenuInit(void)
|
||||
if (fp != 0)
|
||||
{
|
||||
fp = 0;
|
||||
free(buffer);
|
||||
Z_Free(buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2669,6 +2730,7 @@ void StartServer_MenuInit(void)
|
||||
s_maxclients_field.generic.statusbar = NULL;
|
||||
s_maxclients_field.length = 3;
|
||||
s_maxclients_field.visible_length = 3;
|
||||
|
||||
if (Cvar_VariableValue("maxclients") == 1)
|
||||
strcpy(s_maxclients_field.buffer, "8");
|
||||
else
|
||||
@@ -2728,8 +2790,11 @@ const char * StartServer_MenuKey(int key)
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nummaps; i++)
|
||||
free(mapnames[i]);
|
||||
free(mapnames);
|
||||
{
|
||||
Z_Free(mapnames[i]);
|
||||
}
|
||||
|
||||
Z_Free(mapnames);
|
||||
}
|
||||
mapnames = 0;
|
||||
nummaps = 0;
|
||||
@@ -2751,8 +2816,8 @@ DMOPTIONS BOOK MENU
|
||||
|
||||
=============================================================================
|
||||
*/
|
||||
static char dmoptions_statusbar[128];
|
||||
|
||||
static char dmoptions_statusbar[128];
|
||||
static menuframework_s s_dmoptions_menu;
|
||||
|
||||
static menulist_s s_friendlyfire_box;
|
||||
@@ -3152,6 +3217,7 @@ DOWNLOADOPTIONS BOOK MENU
|
||||
|
||||
=============================================================================
|
||||
*/
|
||||
|
||||
static menuframework_s s_downloadoptions_menu;
|
||||
|
||||
static menuseparator_s s_download_title;
|
||||
@@ -3283,7 +3349,11 @@ ADDRESS BOOK MENU
|
||||
|
||||
=============================================================================
|
||||
*/
|
||||
#define NUM_ADDRESSBOOK_ENTRIES 9
|
||||
|
||||
enum
|
||||
{
|
||||
NUM_ADDRESSBOOK_ENTRIES = 9
|
||||
};
|
||||
|
||||
static menuframework_s s_addressbook_menu;
|
||||
static menufield_s s_addressbook_fields[NUM_ADDRESSBOOK_ENTRIES];
|
||||
@@ -3356,6 +3426,7 @@ PLAYER CONFIG MENU
|
||||
|
||||
=============================================================================
|
||||
*/
|
||||
|
||||
static menuframework_s s_player_config_menu;
|
||||
static menufield_s s_player_name_field;
|
||||
static menulist_s s_player_model_box;
|
||||
@@ -3368,8 +3439,11 @@ static menuseparator_s s_player_hand_title;
|
||||
static menuseparator_s s_player_rate_title;
|
||||
static menuaction_s s_player_download_action;
|
||||
|
||||
#define MAX_DISPLAYNAME 16
|
||||
#define MAX_PLAYERMODELS 1024
|
||||
enum
|
||||
{
|
||||
MAX_DISPLAYNAME = 16,
|
||||
MAX_PLAYERMODELS = 1024
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -3417,11 +3491,11 @@ static void FreeFileList(char ** list, int n)
|
||||
{
|
||||
if (list[i])
|
||||
{
|
||||
free(list[i]);
|
||||
Z_Free(list[i]);
|
||||
list[i] = 0;
|
||||
}
|
||||
}
|
||||
free(list);
|
||||
Z_Free(list);
|
||||
}
|
||||
|
||||
static qboolean IconOfSkinExists(char * skin, char ** pcxfiles, int npcxfiles)
|
||||
@@ -3494,7 +3568,7 @@ static qboolean PlayerConfig_ScanDirectories(void)
|
||||
strcat(scratch, "/tris.md2");
|
||||
if (!Sys_FindFirst(scratch, 0, SFF_SUBDIR | SFF_HIDDEN | SFF_SYSTEM))
|
||||
{
|
||||
free(dirnames[i]);
|
||||
Z_Free(dirnames[i]);
|
||||
dirnames[i] = 0;
|
||||
Sys_FindClose();
|
||||
continue;
|
||||
@@ -3508,7 +3582,7 @@ static qboolean PlayerConfig_ScanDirectories(void)
|
||||
|
||||
if (!pcxnames)
|
||||
{
|
||||
free(dirnames[i]);
|
||||
Z_Free(dirnames[i]);
|
||||
dirnames[i] = 0;
|
||||
continue;
|
||||
}
|
||||
@@ -3527,7 +3601,7 @@ static qboolean PlayerConfig_ScanDirectories(void)
|
||||
if (!nskins)
|
||||
continue;
|
||||
|
||||
skinnames = malloc(sizeof(char *) * (nskins + 1));
|
||||
skinnames = Z_Malloc(sizeof(char *) * (nskins + 1));
|
||||
memset(skinnames, 0, sizeof(char *) * (nskins + 1));
|
||||
|
||||
// copy the valid skins
|
||||
@@ -3552,7 +3626,7 @@ static qboolean PlayerConfig_ScanDirectories(void)
|
||||
if (strrchr(scratch, '.'))
|
||||
*strrchr(scratch, '.') = 0;
|
||||
|
||||
skinnames[s] = strdup(scratch);
|
||||
skinnames[s] = Q_CopyString(scratch);
|
||||
s++;
|
||||
}
|
||||
}
|
||||
@@ -3849,10 +3923,14 @@ const char * PlayerConfig_MenuKey(int key)
|
||||
for (j = 0; j < s_pmi[i].nskins; j++)
|
||||
{
|
||||
if (s_pmi[i].skindisplaynames[j])
|
||||
free(s_pmi[i].skindisplaynames[j]);
|
||||
{
|
||||
Z_Free(s_pmi[i].skindisplaynames[j]);
|
||||
}
|
||||
|
||||
s_pmi[i].skindisplaynames[j] = 0;
|
||||
}
|
||||
free(s_pmi[i].skindisplaynames);
|
||||
|
||||
Z_Free(s_pmi[i].skindisplaynames);
|
||||
s_pmi[i].skindisplaynames = 0;
|
||||
s_pmi[i].nskins = 0;
|
||||
}
|
||||
@@ -3878,15 +3956,16 @@ GALLERY MENU
|
||||
|
||||
=======================================================================
|
||||
*/
|
||||
#if 0
|
||||
void M_Menu_Gallery_f( void )
|
||||
{
|
||||
extern void Gallery_MenuDraw( void );
|
||||
extern const char *Gallery_MenuKey( int key );
|
||||
|
||||
M_PushMenu( Gallery_MenuDraw, Gallery_MenuKey );
|
||||
#if 0
|
||||
void M_Menu_Gallery_f(void)
|
||||
{
|
||||
extern void Gallery_MenuDraw(void);
|
||||
extern const char * Gallery_MenuKey(int key);
|
||||
|
||||
M_PushMenu(Gallery_MenuDraw, Gallery_MenuKey);
|
||||
}
|
||||
#endif
|
||||
#endif // 0
|
||||
|
||||
/*
|
||||
=======================================================================
|
||||
@@ -4005,12 +4084,11 @@ M_Keydown
|
||||
void M_Keydown(int key)
|
||||
{
|
||||
const char * s;
|
||||
|
||||
if (m_keyfunc)
|
||||
{
|
||||
if ((s = m_keyfunc(key)) != 0)
|
||||
{
|
||||
S_StartLocalSound((char *)s);
|
||||
S_StartLocalSound(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
+44
-28
@@ -24,28 +24,35 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#include "client.h"
|
||||
#include "qmenu.h"
|
||||
|
||||
void Action_DoEnter(menuaction_s * a);
|
||||
void Action_Draw(menuaction_s * a);
|
||||
void Menu_DrawStatusBar(const char * string);
|
||||
void Menulist_DoEnter(menulist_s * l);
|
||||
void MenuList_Draw(menulist_s * l);
|
||||
void Separator_Draw(menuseparator_s * s);
|
||||
void Slider_DoSlide(menuslider_s * s, int dir);
|
||||
void Slider_Draw(menuslider_s * s);
|
||||
void SpinControl_DoEnter(menulist_s * s);
|
||||
void SpinControl_Draw(menulist_s * s);
|
||||
void SpinControl_DoSlide(menulist_s * s, int dir);
|
||||
static void Action_DoEnter(menuaction_s * a);
|
||||
static void Action_Draw(menuaction_s * a);
|
||||
static void Menu_DrawStatusBar(const char * string);
|
||||
static void Menulist_DoEnter(menulist_s * l);
|
||||
static void MenuList_Draw(menulist_s * l);
|
||||
static void Separator_Draw(menuseparator_s * s);
|
||||
static void Slider_DoSlide(menuslider_s * s, int dir);
|
||||
static void Slider_Draw(menuslider_s * s);
|
||||
static void SpinControl_DoEnter(menulist_s * s);
|
||||
static void SpinControl_Draw(menulist_s * s);
|
||||
static void SpinControl_DoSlide(menulist_s * s, int dir);
|
||||
|
||||
extern refexport_t re;
|
||||
extern viddef_t viddef;
|
||||
|
||||
#define RCOLUMN_OFFSET 16
|
||||
#define LCOLUMN_OFFSET -16
|
||||
enum
|
||||
{
|
||||
RCOLUMN_OFFSET = 16,
|
||||
LCOLUMN_OFFSET = -16
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
|
||||
void Action_DoEnter(menuaction_s * a)
|
||||
{
|
||||
if (a->generic.callback)
|
||||
{
|
||||
a->generic.callback(a);
|
||||
}
|
||||
}
|
||||
|
||||
void Action_Draw(menuaction_s * a)
|
||||
@@ -187,8 +194,8 @@ qboolean Field_Key(menufield_s * f, int key)
|
||||
}
|
||||
|
||||
/*
|
||||
** support pasting from the clipboard
|
||||
*/
|
||||
** support pasting from the clipboard
|
||||
*/
|
||||
if ((toupper(key) == 'V' && keydown[K_CTRL]) ||
|
||||
(((key == K_INS) || (key == K_KP_INS)) && keydown[K_SHIFT]))
|
||||
{
|
||||
@@ -201,10 +208,13 @@ qboolean Field_Key(menufield_s * f, int key)
|
||||
strncpy(f->buffer, cbd, f->length - 1);
|
||||
f->cursor = strlen(f->buffer);
|
||||
f->visible_offset = f->cursor - f->visible_length;
|
||||
if (f->visible_offset < 0)
|
||||
f->visible_offset = 0;
|
||||
|
||||
free(cbd);
|
||||
if (f->visible_offset < 0)
|
||||
{
|
||||
f->visible_offset = 0;
|
||||
}
|
||||
|
||||
Z_Free(cbd);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -284,8 +294,8 @@ void Menu_AdjustCursor(menuframework_s * m, int dir)
|
||||
menucommon_s * citem;
|
||||
|
||||
/*
|
||||
** see if it's in a valid spot
|
||||
*/
|
||||
** see if it's in a valid spot
|
||||
*/
|
||||
if (m->cursor >= 0 && m->cursor < m->nitems)
|
||||
{
|
||||
if ((citem = Menu_ItemAtCursor(m)) != 0)
|
||||
@@ -296,9 +306,9 @@ void Menu_AdjustCursor(menuframework_s * m, int dir)
|
||||
}
|
||||
|
||||
/*
|
||||
** it's not in a valid spot, so crawl in the direction indicated until we
|
||||
** find a valid spot
|
||||
*/
|
||||
** it's not in a valid spot, so crawl in the direction indicated until we
|
||||
** find a valid spot
|
||||
*/
|
||||
if (dir == 1)
|
||||
{
|
||||
while (1)
|
||||
@@ -343,8 +353,8 @@ void Menu_Draw(menuframework_s * menu)
|
||||
menucommon_s * item;
|
||||
|
||||
/*
|
||||
** draw contents
|
||||
*/
|
||||
** draw contents
|
||||
*/
|
||||
for (i = 0; i < menu->nitems; i++)
|
||||
{
|
||||
switch (((menucommon_s *)menu->items[i])->type)
|
||||
@@ -487,10 +497,10 @@ qboolean Menu_SelectItem(menuframework_s * s)
|
||||
Action_DoEnter((menuaction_s *)item);
|
||||
return true;
|
||||
case MTYPE_LIST:
|
||||
// Menulist_DoEnter( ( menulist_s * ) item );
|
||||
// Menulist_DoEnter( ( menulist_s * ) item );
|
||||
return false;
|
||||
case MTYPE_SPINCONTROL:
|
||||
// SpinControl_DoEnter( ( menulist_s * ) item );
|
||||
// SpinControl_DoEnter( ( menulist_s * ) item );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -596,7 +606,10 @@ void Slider_DoSlide(menuslider_s * s, int dir)
|
||||
s->generic.callback(s);
|
||||
}
|
||||
|
||||
#define SLIDER_RANGE 10
|
||||
enum
|
||||
{
|
||||
SLIDER_RANGE = 10
|
||||
};
|
||||
|
||||
void Slider_Draw(menuslider_s * s)
|
||||
{
|
||||
@@ -612,9 +625,12 @@ void Slider_Draw(menuslider_s * s)
|
||||
s->range = 0;
|
||||
if (s->range > 1)
|
||||
s->range = 1;
|
||||
|
||||
re.DrawChar(s->generic.x + s->generic.parent->x + RCOLUMN_OFFSET, s->generic.y + s->generic.parent->y, 128);
|
||||
|
||||
for (i = 0; i < SLIDER_RANGE; i++)
|
||||
re.DrawChar(RCOLUMN_OFFSET + s->generic.x + i * 8 + s->generic.parent->x + 8, s->generic.y + s->generic.parent->y, 129);
|
||||
|
||||
re.DrawChar(RCOLUMN_OFFSET + s->generic.x + i * 8 + s->generic.parent->x + 8, s->generic.y + s->generic.parent->y, 130);
|
||||
re.DrawChar((int)(8 + RCOLUMN_OFFSET + s->generic.parent->x + s->generic.x + (SLIDER_RANGE - 1) * 8 * s->range), s->generic.y + s->generic.parent->y, 131);
|
||||
}
|
||||
|
||||
+16
-21
@@ -23,31 +23,31 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#define MAXMENUITEMS 64
|
||||
|
||||
#define MTYPE_SLIDER 0
|
||||
#define MTYPE_LIST 1
|
||||
#define MTYPE_ACTION 2
|
||||
#define MTYPE_SLIDER 0
|
||||
#define MTYPE_LIST 1
|
||||
#define MTYPE_ACTION 2
|
||||
#define MTYPE_SPINCONTROL 3
|
||||
#define MTYPE_SEPARATOR 4
|
||||
#define MTYPE_FIELD 5
|
||||
#define MTYPE_SEPARATOR 4
|
||||
#define MTYPE_FIELD 5
|
||||
|
||||
#define K_TAB 9
|
||||
#define K_ENTER 13
|
||||
#define K_TAB 9
|
||||
#define K_ENTER 13
|
||||
#define K_ESCAPE 27
|
||||
#define K_SPACE 32
|
||||
#define K_SPACE 32
|
||||
|
||||
// normal keys should be passed as lowercased ascii
|
||||
|
||||
#define K_BACKSPACE 127
|
||||
#define K_UPARROW 128
|
||||
#define K_DOWNARROW 129
|
||||
#define K_LEFTARROW 130
|
||||
#define K_BACKSPACE 127
|
||||
#define K_UPARROW 128
|
||||
#define K_DOWNARROW 129
|
||||
#define K_LEFTARROW 130
|
||||
#define K_RIGHTARROW 131
|
||||
|
||||
#define QMF_LEFT_JUSTIFY 0x00000001
|
||||
#define QMF_GRAYED 0x00000002
|
||||
#define QMF_NUMBERSONLY 0x00000004
|
||||
#define QMF_GRAYED 0x00000002
|
||||
#define QMF_NUMBERSONLY 0x00000004
|
||||
|
||||
typedef struct _tag_menuframework
|
||||
typedef struct menuframework_struct
|
||||
{
|
||||
int x, y;
|
||||
int cursor;
|
||||
@@ -58,7 +58,7 @@ typedef struct _tag_menuframework
|
||||
|
||||
const char * statusbar;
|
||||
|
||||
void (*cursordraw)(struct _tag_menuframework * m);
|
||||
void (*cursordraw)(struct menuframework_struct * m);
|
||||
|
||||
} menuframework_s;
|
||||
|
||||
@@ -83,7 +83,6 @@ typedef struct
|
||||
typedef struct
|
||||
{
|
||||
menucommon_s generic;
|
||||
|
||||
char buffer[80];
|
||||
int cursor;
|
||||
int length;
|
||||
@@ -94,20 +93,16 @@ typedef struct
|
||||
typedef struct
|
||||
{
|
||||
menucommon_s generic;
|
||||
|
||||
float minvalue;
|
||||
float maxvalue;
|
||||
float curvalue;
|
||||
|
||||
float range;
|
||||
} menuslider_s;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
menucommon_s generic;
|
||||
|
||||
int curvalue;
|
||||
|
||||
const char ** itemnames;
|
||||
} menulist_s;
|
||||
|
||||
|
||||
@@ -192,10 +192,9 @@ void S_Shutdown(void)
|
||||
/*
|
||||
==================
|
||||
S_FindName
|
||||
|
||||
==================
|
||||
*/
|
||||
sfx_t * S_FindName(char * name, qboolean create)
|
||||
sfx_t * S_FindName(const char * name, qboolean create)
|
||||
{
|
||||
int i;
|
||||
sfx_t * sfx;
|
||||
@@ -221,7 +220,7 @@ sfx_t * S_FindName(char * name, qboolean create)
|
||||
// find a free sfx
|
||||
for (i = 0; i < num_sfx; i++)
|
||||
if (!known_sfx[i].name[0])
|
||||
// registration_sequence < s_registration_sequence)
|
||||
// registration_sequence < s_registration_sequence)
|
||||
break;
|
||||
|
||||
if (i == num_sfx)
|
||||
@@ -293,7 +292,7 @@ S_RegisterSound
|
||||
|
||||
==================
|
||||
*/
|
||||
sfx_t * S_RegisterSound(char * name)
|
||||
sfx_t * S_RegisterSound(const char * name)
|
||||
{
|
||||
sfx_t * sfx;
|
||||
|
||||
@@ -716,7 +715,7 @@ void S_StartSound(vec3_t origin, int entnum, int entchannel, sfx_t * sfx, float
|
||||
S_StartLocalSound
|
||||
==================
|
||||
*/
|
||||
void S_StartLocalSound(char * sound)
|
||||
void S_StartLocalSound(const char * sound)
|
||||
{
|
||||
sfx_t * sfx;
|
||||
|
||||
|
||||
+6
-4
@@ -27,8 +27,10 @@ void S_Init(void);
|
||||
void S_Shutdown(void);
|
||||
|
||||
// if origin is NULL, the sound will be dynamically sourced from the entity
|
||||
void S_StartSound(vec3_t origin, int entnum, int entchannel, struct sfx_s * sfx, float fvol, float attenuation, float timeofs);
|
||||
void S_StartLocalSound(char * s);
|
||||
void S_StartSound(vec3_t origin, int entnum, int entchannel, struct sfx_s * sfx,
|
||||
float fvol, float attenuation, float timeofs);
|
||||
|
||||
void S_StartLocalSound(const char * s);
|
||||
|
||||
void S_RawSamples(int samples, int rate, int width, int channels, byte * data);
|
||||
|
||||
@@ -38,10 +40,10 @@ void S_Update(vec3_t origin, vec3_t v_forward, vec3_t v_right, vec3_t v_up);
|
||||
void S_Activate(qboolean active);
|
||||
|
||||
void S_BeginRegistration(void);
|
||||
struct sfx_s * S_RegisterSound(char * sample);
|
||||
struct sfx_s * S_RegisterSound(const char * sample);
|
||||
void S_EndRegistration(void);
|
||||
|
||||
struct sfx_s * S_FindName(char * name, qboolean create);
|
||||
struct sfx_s * S_FindName(const char * name, qboolean create);
|
||||
|
||||
// the sound code makes callbacks to the client for entitiy position
|
||||
// information, so entities can be dynamically re-spatialized
|
||||
|
||||
+1
-1
@@ -475,7 +475,7 @@ void Cmd_Alias_f(void)
|
||||
}
|
||||
strcat(cmd, "\n");
|
||||
|
||||
a->value = CopyString(cmd);
|
||||
a->value = Q_CopyString(cmd);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+100
-74
@@ -61,60 +61,67 @@ typedef struct
|
||||
int floodvalid;
|
||||
} carea_t;
|
||||
|
||||
int checkcount;
|
||||
|
||||
char map_name[MAX_QPATH];
|
||||
|
||||
int numbrushsides;
|
||||
cbrushside_t map_brushsides[MAX_MAP_BRUSHSIDES];
|
||||
//
|
||||
// LAMPERT 2015-10-27
|
||||
// Made a bunch local data in this file 'static',
|
||||
// since most global variables in here are never exported.
|
||||
//
|
||||
|
||||
// Referenced by cl_main.c
|
||||
int numtexinfo;
|
||||
mapsurface_t map_surfaces[MAX_MAP_TEXINFO];
|
||||
|
||||
int numplanes;
|
||||
cplane_t map_planes[MAX_MAP_PLANES + 6]; // extra for box hull
|
||||
static int checkcount;
|
||||
static char map_name[MAX_QPATH];
|
||||
|
||||
int numnodes;
|
||||
cnode_t map_nodes[MAX_MAP_NODES + 6]; // extra for box hull
|
||||
static int numbrushsides;
|
||||
static cbrushside_t map_brushsides[MAX_MAP_BRUSHSIDES];
|
||||
|
||||
int numleafs = 1; // allow leaf funcs to be called without a map
|
||||
cleaf_t map_leafs[MAX_MAP_LEAFS];
|
||||
int emptyleaf, solidleaf;
|
||||
static int numplanes;
|
||||
static cplane_t map_planes[MAX_MAP_PLANES + 6]; // extra for box hull
|
||||
|
||||
int numleafbrushes;
|
||||
unsigned short map_leafbrushes[MAX_MAP_LEAFBRUSHES];
|
||||
static int numnodes;
|
||||
static cnode_t map_nodes[MAX_MAP_NODES + 6]; // extra for box hull
|
||||
|
||||
int numcmodels;
|
||||
cmodel_t map_cmodels[MAX_MAP_MODELS];
|
||||
static int numleafs = 1; // allow leaf funcs to be called without a map
|
||||
static cleaf_t map_leafs[MAX_MAP_LEAFS];
|
||||
static int emptyleaf, solidleaf;
|
||||
|
||||
int numbrushes;
|
||||
cbrush_t map_brushes[MAX_MAP_BRUSHES];
|
||||
static int numleafbrushes;
|
||||
static unsigned short map_leafbrushes[MAX_MAP_LEAFBRUSHES];
|
||||
|
||||
int numvisibility;
|
||||
byte map_visibility[MAX_MAP_VISIBILITY];
|
||||
dvis_t * map_vis = (dvis_t *)map_visibility;
|
||||
static int numcmodels;
|
||||
static cmodel_t map_cmodels[MAX_MAP_MODELS];
|
||||
|
||||
int numentitychars;
|
||||
char map_entitystring[MAX_MAP_ENTSTRING];
|
||||
static int numbrushes;
|
||||
static cbrush_t map_brushes[MAX_MAP_BRUSHES];
|
||||
|
||||
int numareas = 1;
|
||||
carea_t map_areas[MAX_MAP_AREAS];
|
||||
static int numvisibility;
|
||||
static byte map_visibility[MAX_MAP_VISIBILITY];
|
||||
static dvis_t * map_vis = (dvis_t *)map_visibility;
|
||||
|
||||
int numareaportals;
|
||||
dareaportal_t map_areaportals[MAX_MAP_AREAPORTALS];
|
||||
static int numentitychars;
|
||||
static char map_entitystring[MAX_MAP_ENTSTRING];
|
||||
|
||||
int numclusters = 1;
|
||||
static int numareas = 1;
|
||||
static carea_t map_areas[MAX_MAP_AREAS];
|
||||
|
||||
mapsurface_t nullsurface;
|
||||
static int numareaportals;
|
||||
static dareaportal_t map_areaportals[MAX_MAP_AREAPORTALS];
|
||||
|
||||
int floodvalid;
|
||||
static int numclusters = 1;
|
||||
static int floodvalid;
|
||||
|
||||
qboolean portalopen[MAX_MAP_AREAPORTALS];
|
||||
static mapsurface_t nullsurface;
|
||||
static qboolean portalopen[MAX_MAP_AREAPORTALS];
|
||||
|
||||
cvar_t * map_noareas;
|
||||
static byte * cmod_base;
|
||||
static cvar_t * map_noareas;
|
||||
|
||||
// These counters are referenced by Qcommon_Frame().
|
||||
int c_pointcontents;
|
||||
int c_traces, c_brush_traces;
|
||||
int c_traces;
|
||||
int c_brush_traces;
|
||||
|
||||
void CM_InitBoxHull(void);
|
||||
void FloodAreaConnections(void);
|
||||
@@ -122,13 +129,11 @@ void FloodAreaConnections(void);
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
MAP LOADING
|
||||
MAP LOADING
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
byte * cmod_base;
|
||||
|
||||
/*
|
||||
=================
|
||||
CMod_LoadSubmodels
|
||||
@@ -143,10 +148,12 @@ void CMod_LoadSubmodels(lump_t * l)
|
||||
in = (void *)(cmod_base + l->fileofs);
|
||||
if (l->filelen % sizeof(*in))
|
||||
Com_Error(ERR_DROP, "MOD_LoadBmodel: funny lump size");
|
||||
|
||||
count = l->filelen / sizeof(*in);
|
||||
|
||||
if (count < 1)
|
||||
Com_Error(ERR_DROP, "Map with no models");
|
||||
|
||||
if (count > MAX_MAP_MODELS)
|
||||
Com_Error(ERR_DROP, "Map has too many models");
|
||||
|
||||
@@ -180,9 +187,11 @@ void CMod_LoadSurfaces(lump_t * l)
|
||||
in = (void *)(cmod_base + l->fileofs);
|
||||
if (l->filelen % sizeof(*in))
|
||||
Com_Error(ERR_DROP, "MOD_LoadBmodel: funny lump size");
|
||||
|
||||
count = l->filelen / sizeof(*in);
|
||||
if (count < 1)
|
||||
Com_Error(ERR_DROP, "Map with no surfaces");
|
||||
|
||||
if (count > MAX_MAP_TEXINFO)
|
||||
Com_Error(ERR_DROP, "Map has too many surfaces");
|
||||
|
||||
@@ -201,7 +210,6 @@ void CMod_LoadSurfaces(lump_t * l)
|
||||
/*
|
||||
=================
|
||||
CMod_LoadNodes
|
||||
|
||||
=================
|
||||
*/
|
||||
void CMod_LoadNodes(lump_t * l)
|
||||
@@ -214,10 +222,12 @@ void CMod_LoadNodes(lump_t * l)
|
||||
in = (void *)(cmod_base + l->fileofs);
|
||||
if (l->filelen % sizeof(*in))
|
||||
Com_Error(ERR_DROP, "MOD_LoadBmodel: funny lump size");
|
||||
|
||||
count = l->filelen / sizeof(*in);
|
||||
|
||||
if (count < 1)
|
||||
Com_Error(ERR_DROP, "Map has no nodes");
|
||||
|
||||
if (count > MAX_MAP_NODES)
|
||||
Com_Error(ERR_DROP, "Map has too many nodes");
|
||||
|
||||
@@ -239,7 +249,6 @@ void CMod_LoadNodes(lump_t * l)
|
||||
/*
|
||||
=================
|
||||
CMod_LoadBrushes
|
||||
|
||||
=================
|
||||
*/
|
||||
void CMod_LoadBrushes(lump_t * l)
|
||||
@@ -251,6 +260,7 @@ void CMod_LoadBrushes(lump_t * l)
|
||||
in = (void *)(cmod_base + l->fileofs);
|
||||
if (l->filelen % sizeof(*in))
|
||||
Com_Error(ERR_DROP, "MOD_LoadBmodel: funny lump size");
|
||||
|
||||
count = l->filelen / sizeof(*in);
|
||||
|
||||
if (count > MAX_MAP_BRUSHES)
|
||||
@@ -283,10 +293,12 @@ void CMod_LoadLeafs(lump_t * l)
|
||||
in = (void *)(cmod_base + l->fileofs);
|
||||
if (l->filelen % sizeof(*in))
|
||||
Com_Error(ERR_DROP, "MOD_LoadBmodel: funny lump size");
|
||||
|
||||
count = l->filelen / sizeof(*in);
|
||||
|
||||
if (count < 1)
|
||||
Com_Error(ERR_DROP, "Map with no leafs");
|
||||
|
||||
// need to save space for box planes
|
||||
if (count > MAX_MAP_PLANES)
|
||||
Com_Error(ERR_DROP, "Map has too many planes");
|
||||
@@ -309,6 +321,7 @@ void CMod_LoadLeafs(lump_t * l)
|
||||
|
||||
if (map_leafs[0].contents != CONTENTS_SOLID)
|
||||
Com_Error(ERR_DROP, "Map leaf 0 is not CONTENTS_SOLID");
|
||||
|
||||
solidleaf = 0;
|
||||
emptyleaf = -1;
|
||||
for (i = 1; i < numleafs; i++)
|
||||
@@ -319,6 +332,7 @@ void CMod_LoadLeafs(lump_t * l)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (emptyleaf == -1)
|
||||
Com_Error(ERR_DROP, "Map does not have an empty leaf");
|
||||
}
|
||||
@@ -339,10 +353,12 @@ void CMod_LoadPlanes(lump_t * l)
|
||||
in = (void *)(cmod_base + l->fileofs);
|
||||
if (l->filelen % sizeof(*in))
|
||||
Com_Error(ERR_DROP, "MOD_LoadBmodel: funny lump size");
|
||||
|
||||
count = l->filelen / sizeof(*in);
|
||||
|
||||
if (count < 1)
|
||||
Com_Error(ERR_DROP, "Map with no planes");
|
||||
|
||||
// need to save space for box planes
|
||||
if (count > MAX_MAP_PLANES)
|
||||
Com_Error(ERR_DROP, "Map has too many planes");
|
||||
@@ -381,10 +397,12 @@ void CMod_LoadLeafBrushes(lump_t * l)
|
||||
in = (void *)(cmod_base + l->fileofs);
|
||||
if (l->filelen % sizeof(*in))
|
||||
Com_Error(ERR_DROP, "MOD_LoadBmodel: funny lump size");
|
||||
|
||||
count = l->filelen / sizeof(*in);
|
||||
|
||||
if (count < 1)
|
||||
Com_Error(ERR_DROP, "Map with no planes");
|
||||
|
||||
// need to save space for box planes
|
||||
if (count > MAX_MAP_LEAFBRUSHES)
|
||||
Com_Error(ERR_DROP, "Map has too many leafbrushes");
|
||||
@@ -412,6 +430,7 @@ void CMod_LoadBrushSides(lump_t * l)
|
||||
in = (void *)(cmod_base + l->fileofs);
|
||||
if (l->filelen % sizeof(*in))
|
||||
Com_Error(ERR_DROP, "MOD_LoadBmodel: funny lump size");
|
||||
|
||||
count = l->filelen / sizeof(*in);
|
||||
|
||||
// need to save space for box planes
|
||||
@@ -426,8 +445,10 @@ void CMod_LoadBrushSides(lump_t * l)
|
||||
num = LittleShort(in->planenum);
|
||||
out->plane = &map_planes[num];
|
||||
j = LittleShort(in->texinfo);
|
||||
|
||||
if (j >= numtexinfo)
|
||||
Com_Error(ERR_DROP, "Bad brushside texinfo");
|
||||
|
||||
out->surface = &map_surfaces[j];
|
||||
}
|
||||
}
|
||||
@@ -447,6 +468,7 @@ void CMod_LoadAreas(lump_t * l)
|
||||
in = (void *)(cmod_base + l->fileofs);
|
||||
if (l->filelen % sizeof(*in))
|
||||
Com_Error(ERR_DROP, "MOD_LoadBmodel: funny lump size");
|
||||
|
||||
count = l->filelen / sizeof(*in);
|
||||
|
||||
if (count > MAX_MAP_AREAS)
|
||||
@@ -479,6 +501,7 @@ void CMod_LoadAreaPortals(lump_t * l)
|
||||
in = (void *)(cmod_base + l->fileofs);
|
||||
if (l->filelen % sizeof(*in))
|
||||
Com_Error(ERR_DROP, "MOD_LoadBmodel: funny lump size");
|
||||
|
||||
count = l->filelen / sizeof(*in);
|
||||
|
||||
if (count > MAX_MAP_AREAS)
|
||||
@@ -593,7 +616,10 @@ cmodel_t * CM_LoadMap(char * name, qboolean clientload, unsigned * checksum)
|
||||
((int *)&header)[i] = LittleLong(((int *)&header)[i]);
|
||||
|
||||
if (header.version != BSPVERSION)
|
||||
Com_Error(ERR_DROP, "CMod_LoadBrushModel: %s has wrong version number (%i should be %i)", name, header.version, BSPVERSION);
|
||||
{
|
||||
Com_Error(ERR_DROP, "CMod_LoadBrushModel: %s has wrong version number (%i should be %i)",
|
||||
name, header.version, BSPVERSION);
|
||||
}
|
||||
|
||||
cmod_base = (byte *)buf;
|
||||
|
||||
@@ -634,7 +660,9 @@ cmodel_t * CM_InlineModel(char * name)
|
||||
|
||||
if (!name || name[0] != '*')
|
||||
Com_Error(ERR_DROP, "CM_InlineModel: bad name");
|
||||
|
||||
num = atoi(name + 1);
|
||||
|
||||
if (num < 1 || num >= numcmodels)
|
||||
Com_Error(ERR_DROP, "CM_InlineModel: bad number");
|
||||
|
||||
@@ -679,10 +707,10 @@ int CM_LeafArea(int leafnum)
|
||||
|
||||
//=======================================================================
|
||||
|
||||
cplane_t * box_planes;
|
||||
int box_headnode;
|
||||
cbrush_t * box_brush;
|
||||
cleaf_t * box_leaf;
|
||||
static int box_headnode;
|
||||
static cplane_t * box_planes;
|
||||
static cbrush_t * box_brush;
|
||||
static cleaf_t * box_leaf;
|
||||
|
||||
/*
|
||||
===================
|
||||
@@ -779,7 +807,6 @@ int CM_HeadnodeForBox(vec3_t mins, vec3_t maxs)
|
||||
/*
|
||||
==================
|
||||
CM_PointLeafnum_r
|
||||
|
||||
==================
|
||||
*/
|
||||
int CM_PointLeafnum_r(vec3_t p, int num)
|
||||
@@ -815,18 +842,20 @@ int CM_PointLeafnum(vec3_t p)
|
||||
return CM_PointLeafnum_r(p, 0);
|
||||
}
|
||||
|
||||
static int leaf_topnode;
|
||||
static int leaf_count;
|
||||
static int leaf_maxcount;
|
||||
static int * leaf_list;
|
||||
static float * leaf_mins;
|
||||
static float * leaf_maxs;
|
||||
|
||||
/*
|
||||
=============
|
||||
CM_BoxLeafnums
|
||||
CM_BoxLeafnums_r
|
||||
|
||||
Fills in a list of all the leafs touched
|
||||
=============
|
||||
*/
|
||||
int leaf_count, leaf_maxcount;
|
||||
int * leaf_list;
|
||||
float *leaf_mins, *leaf_maxs;
|
||||
int leaf_topnode;
|
||||
|
||||
void CM_BoxLeafnums_r(int nodenum)
|
||||
{
|
||||
cplane_t * plane;
|
||||
@@ -839,7 +868,7 @@ void CM_BoxLeafnums_r(int nodenum)
|
||||
{
|
||||
if (leaf_count >= leaf_maxcount)
|
||||
{
|
||||
// Com_Printf ("CM_BoxLeafnums_r: overflow\n");
|
||||
// Com_Printf ("CM_BoxLeafnums_r: overflow\n");
|
||||
return;
|
||||
}
|
||||
leaf_list[leaf_count++] = -1 - nodenum;
|
||||
@@ -848,7 +877,7 @@ void CM_BoxLeafnums_r(int nodenum)
|
||||
|
||||
node = &map_nodes[nodenum];
|
||||
plane = node->plane;
|
||||
// s = BoxOnPlaneSide (leaf_mins, leaf_maxs, plane);
|
||||
// s = BoxOnPlaneSide (leaf_mins, leaf_maxs, plane);
|
||||
s = BOX_ON_PLANE_SIDE(leaf_mins, leaf_maxs, plane);
|
||||
if (s == 1)
|
||||
nodenum = node->children[0];
|
||||
@@ -885,13 +914,13 @@ int CM_BoxLeafnums_headnode(vec3_t mins, vec3_t maxs, int * list, int listsize,
|
||||
int CM_BoxLeafnums(vec3_t mins, vec3_t maxs, int * list, int listsize, int * topnode)
|
||||
{
|
||||
return CM_BoxLeafnums_headnode(mins, maxs, list,
|
||||
listsize, map_cmodels[0].headnode, topnode);
|
||||
listsize, map_cmodels[0].headnode,
|
||||
topnode);
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CM_PointContents
|
||||
|
||||
==================
|
||||
*/
|
||||
int CM_PointContents(vec3_t p, int headnode)
|
||||
@@ -952,13 +981,15 @@ BOX TRACING
|
||||
// 1/32 epsilon to keep floating point happy
|
||||
#define DIST_EPSILON (0.03125)
|
||||
|
||||
vec3_t trace_start, trace_end;
|
||||
vec3_t trace_mins, trace_maxs;
|
||||
vec3_t trace_extents;
|
||||
static vec3_t trace_start;
|
||||
static vec3_t trace_end;
|
||||
static vec3_t trace_mins;
|
||||
static vec3_t trace_maxs;
|
||||
static vec3_t trace_extents;
|
||||
|
||||
trace_t trace_trace;
|
||||
int trace_contents;
|
||||
qboolean trace_ispoint; // optimized case
|
||||
static trace_t trace_trace;
|
||||
static int trace_contents;
|
||||
static qboolean trace_ispoint; // optimized case
|
||||
|
||||
/*
|
||||
================
|
||||
@@ -1149,10 +1180,12 @@ void CM_TraceToLeaf(int leafnum)
|
||||
b = &map_brushes[brushnum];
|
||||
if (b->checkcount == checkcount)
|
||||
continue; // already checked this brush in another leaf
|
||||
|
||||
b->checkcount = checkcount;
|
||||
|
||||
if (!(b->contents & trace_contents))
|
||||
continue;
|
||||
|
||||
CM_ClipBoxToBrush(trace_mins, trace_maxs, trace_start, trace_end, &trace_trace, b);
|
||||
if (!trace_trace.fraction)
|
||||
return;
|
||||
@@ -1181,10 +1214,12 @@ void CM_TestInLeaf(int leafnum)
|
||||
b = &map_brushes[brushnum];
|
||||
if (b->checkcount == checkcount)
|
||||
continue; // already checked this brush in another leaf
|
||||
|
||||
b->checkcount = checkcount;
|
||||
|
||||
if (!(b->contents & trace_contents))
|
||||
continue;
|
||||
|
||||
CM_TestBoxInBrush(trace_mins, trace_maxs, trace_start, &trace_trace, b);
|
||||
if (!trace_trace.fraction)
|
||||
return;
|
||||
@@ -1194,7 +1229,6 @@ void CM_TestInLeaf(int leafnum)
|
||||
/*
|
||||
==================
|
||||
CM_RecursiveHullCheck
|
||||
|
||||
==================
|
||||
*/
|
||||
void CM_RecursiveHullCheck(int num, float p1f, float p2f, vec3_t p1, vec3_t p2)
|
||||
@@ -1323,8 +1357,7 @@ trace_t CM_BoxTrace(vec3_t start, vec3_t end,
|
||||
int i;
|
||||
|
||||
checkcount++; // for multi-check avoidance
|
||||
|
||||
c_traces++; // for statistics, may be zeroed
|
||||
c_traces++; // for statistics, may be zeroed
|
||||
|
||||
// fill in a default trace
|
||||
memset(&trace_trace, 0, sizeof(trace_trace));
|
||||
@@ -1482,12 +1515,7 @@ PVS / PHS
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
===================
|
||||
CM_DecompressVis
|
||||
===================
|
||||
*/
|
||||
void CM_DecompressVis(byte * in, byte * out)
|
||||
static void CM_DecompressVis(byte * in, byte * out)
|
||||
{
|
||||
int c;
|
||||
byte * out_p;
|
||||
@@ -1529,8 +1557,8 @@ void CM_DecompressVis(byte * in, byte * out)
|
||||
} while (out_p - out < row);
|
||||
}
|
||||
|
||||
byte pvsrow[MAX_MAP_LEAFS / 8];
|
||||
byte phsrow[MAX_MAP_LEAFS / 8];
|
||||
static byte pvsrow[MAX_MAP_LEAFS / 8];
|
||||
static byte phsrow[MAX_MAP_LEAFS / 8];
|
||||
|
||||
byte * CM_ClusterPVS(int cluster)
|
||||
{
|
||||
@@ -1583,8 +1611,6 @@ void FloodArea_r(carea_t * area, int floodnum)
|
||||
/*
|
||||
====================
|
||||
FloodAreaConnections
|
||||
|
||||
|
||||
====================
|
||||
*/
|
||||
void FloodAreaConnections(void)
|
||||
|
||||
+31
-23
@@ -1031,7 +1031,7 @@ int memsearch(const byte * start, int count, int search)
|
||||
return -1;
|
||||
}
|
||||
|
||||
char * CopyString(const char * in)
|
||||
char * Q_CopyString(const char * in)
|
||||
{
|
||||
char * out;
|
||||
out = Z_Malloc(strlen(in) + 1);
|
||||
@@ -1087,11 +1087,16 @@ void Info_Print(char * s)
|
||||
|
||||
ZONE MEMORY ALLOCATION
|
||||
|
||||
just cleared malloc with counters now...
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
//
|
||||
// LAMPERT 2015-10-28
|
||||
// Replaced malloc/free with the PS2 memory allocation wrappers to keep
|
||||
// count of all memory allocations, plus a few other minor changes.
|
||||
//
|
||||
#include "ps2/mem_alloc.h"
|
||||
|
||||
enum
|
||||
{
|
||||
Z_MAGIC = 0x1D1D
|
||||
@@ -1099,14 +1104,16 @@ enum
|
||||
|
||||
typedef struct zhead_s
|
||||
{
|
||||
struct zhead_s *prev, *next;
|
||||
struct zhead_s * prev;
|
||||
struct zhead_s * next;
|
||||
short magic;
|
||||
short tag; // for group free
|
||||
int size;
|
||||
} zhead_t;
|
||||
|
||||
zhead_t z_chain;
|
||||
int z_count, z_bytes;
|
||||
static zhead_t z_chain;
|
||||
static int z_count;
|
||||
static int z_bytes;
|
||||
|
||||
/*
|
||||
========================
|
||||
@@ -1115,8 +1122,7 @@ Z_Free
|
||||
*/
|
||||
void Z_Free(void * ptr)
|
||||
{
|
||||
zhead_t * z;
|
||||
z = ((zhead_t *)ptr) - 1;
|
||||
zhead_t * z = ((zhead_t *)ptr) - 1;
|
||||
|
||||
if (z->magic != Z_MAGIC)
|
||||
{
|
||||
@@ -1128,17 +1134,8 @@ void Z_Free(void * ptr)
|
||||
|
||||
z_count--;
|
||||
z_bytes -= z->size;
|
||||
free(z);
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
Z_Stats_f
|
||||
========================
|
||||
*/
|
||||
void Z_Stats_f(void)
|
||||
{
|
||||
Com_Printf("%i bytes in %i blocks\n", z_bytes, z_count);
|
||||
PS2_MemFree(z, z->size, MEMTAG_QUAKE);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1148,7 +1145,8 @@ Z_FreeTags
|
||||
*/
|
||||
void Z_FreeTags(int tag)
|
||||
{
|
||||
zhead_t *z, *next;
|
||||
zhead_t * z;
|
||||
zhead_t * next;
|
||||
for (z = z_chain.next; z != &z_chain; z = next)
|
||||
{
|
||||
next = z->next;
|
||||
@@ -1169,9 +1167,9 @@ void * Z_TagMalloc(int size, int tag)
|
||||
zhead_t * z;
|
||||
|
||||
size = size + sizeof(zhead_t);
|
||||
z = malloc(size);
|
||||
z = PS2_MemAlloc(size, MEMTAG_QUAKE);
|
||||
|
||||
if (!z)
|
||||
if (z == NULL)
|
||||
{
|
||||
Sys_Error("Z_Malloc: Failed on allocation of %i bytes!", size);
|
||||
}
|
||||
@@ -1180,8 +1178,8 @@ void * Z_TagMalloc(int size, int tag)
|
||||
z_count++;
|
||||
z_bytes += size;
|
||||
z->magic = Z_MAGIC;
|
||||
z->tag = tag;
|
||||
z->size = size;
|
||||
z->tag = tag;
|
||||
z->size = size;
|
||||
|
||||
z->next = z_chain.next;
|
||||
z->prev = &z_chain;
|
||||
@@ -1201,6 +1199,16 @@ void * Z_Malloc(int size)
|
||||
return Z_TagMalloc(size, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
Z_Stats_f
|
||||
========================
|
||||
*/
|
||||
void Z_Stats_f(void)
|
||||
{
|
||||
Com_Printf("%i bytes in %i blocks\n", z_bytes, z_count);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
||||
/*
|
||||
|
||||
+6
-6
@@ -174,8 +174,8 @@ cvar_t * Cvar_Get(const char * var_name, const char * var_value, int flags)
|
||||
}
|
||||
|
||||
var = Z_Malloc(sizeof(*var));
|
||||
var->name = CopyString(var_name);
|
||||
var->string = CopyString(var_value);
|
||||
var->name = Q_CopyString(var_name);
|
||||
var->string = Q_CopyString(var_value);
|
||||
var->modified = true;
|
||||
var->value = atof(var->string);
|
||||
|
||||
@@ -240,11 +240,11 @@ cvar_t * Cvar_Set2(const char * var_name, const char * value, qboolean force)
|
||||
if (Com_ServerState())
|
||||
{
|
||||
Com_Printf("%s will be changed for next game.\n", var_name);
|
||||
var->latched_string = CopyString(value);
|
||||
var->latched_string = Q_CopyString(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
var->string = CopyString(value);
|
||||
var->string = Q_CopyString(value);
|
||||
var->value = atof(var->string);
|
||||
if (!strcmp(var->name, "game"))
|
||||
{
|
||||
@@ -278,7 +278,7 @@ cvar_t * Cvar_Set2(const char * var_name, const char * value, qboolean force)
|
||||
|
||||
Z_Free(var->string); // free the old value string
|
||||
|
||||
var->string = CopyString(value);
|
||||
var->string = Q_CopyString(value);
|
||||
var->value = atof(var->string);
|
||||
|
||||
return var;
|
||||
@@ -329,7 +329,7 @@ cvar_t * Cvar_FullSet(const char * var_name, const char * value, int flags)
|
||||
|
||||
Z_Free(var->string); // free the old value string
|
||||
|
||||
var->string = CopyString(value);
|
||||
var->string = Q_CopyString(value);
|
||||
var->value = atof(var->string);
|
||||
var->flags = flags;
|
||||
|
||||
|
||||
+25
-19
@@ -72,17 +72,24 @@ typedef struct searchpath_s
|
||||
struct searchpath_s * next;
|
||||
} searchpath_t;
|
||||
|
||||
char fs_gamedir[MAX_OSPATH];
|
||||
cvar_t * fs_basedir;
|
||||
cvar_t * fs_cddir;
|
||||
cvar_t * fs_gamedirvar;
|
||||
// LAMPERT 2015-10-27
|
||||
// Marked these locals as 'static'
|
||||
|
||||
static char fs_gamedir[MAX_OSPATH];
|
||||
static cvar_t * fs_basedir;
|
||||
static cvar_t * fs_cddir;
|
||||
|
||||
static filelink_t * fs_links;
|
||||
static searchpath_t * fs_searchpaths;
|
||||
static searchpath_t * fs_base_searchpaths; // without gamedirs
|
||||
static char fs_default_base_path[MAX_OSPATH] = ".";
|
||||
static searchpath_t * fs_base_searchpaths; // Without gamedirs
|
||||
static char fs_default_base_path[MAX_OSPATH] = "."; // Added for QPS2
|
||||
|
||||
// Externally referenced:
|
||||
int file_from_pak = 0;
|
||||
cvar_t * fs_gamedirvar = NULL;
|
||||
|
||||
/* ===========================================================================
|
||||
|
||||
/*
|
||||
All of Quake's data access is through a hierarchical file system, but the contents of
|
||||
the file system can be transparently merged from several sources.
|
||||
|
||||
@@ -96,7 +103,8 @@ files (savegames, screenshots, demos, config files) will be saved to. This can b
|
||||
with the "-game" command line parameter. The game directory can never be changed while quake
|
||||
is executing. This is a precaution against having a malicious server instruct clients to
|
||||
write files over areas they shouldn't.
|
||||
*/
|
||||
|
||||
============================================================================== */
|
||||
|
||||
/*
|
||||
================
|
||||
@@ -187,8 +195,6 @@ int Developer_searchpath(int who)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int file_from_pak = 0;
|
||||
|
||||
/*
|
||||
===========
|
||||
FS_FOpenFile
|
||||
@@ -714,7 +720,7 @@ void FS_Link_f(void)
|
||||
Z_Free(l);
|
||||
return;
|
||||
}
|
||||
l->to = CopyString(Cmd_Argv(2));
|
||||
l->to = Q_CopyString(Cmd_Argv(2));
|
||||
return;
|
||||
}
|
||||
prev = &l->next;
|
||||
@@ -724,9 +730,9 @@ void FS_Link_f(void)
|
||||
l = Z_Malloc(sizeof(*l));
|
||||
l->next = fs_links;
|
||||
fs_links = l;
|
||||
l->from = CopyString(Cmd_Argv(1));
|
||||
l->from = Q_CopyString(Cmd_Argv(1));
|
||||
l->fromlength = strlen(l->from);
|
||||
l->to = CopyString(Cmd_Argv(2));
|
||||
l->to = Q_CopyString(Cmd_Argv(2));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -757,7 +763,7 @@ char ** FS_ListFiles(char * findname, int * numfiles, unsigned musthave, unsigne
|
||||
nfiles++; // add space for a guard
|
||||
*numfiles = nfiles;
|
||||
|
||||
list = malloc(sizeof(char *) * nfiles);
|
||||
list = Z_Malloc(sizeof(char *) * nfiles);
|
||||
memset(list, 0, sizeof(char *) * nfiles);
|
||||
|
||||
s = Sys_FindFirst(findname, musthave, canthave);
|
||||
@@ -766,7 +772,7 @@ char ** FS_ListFiles(char * findname, int * numfiles, unsigned musthave, unsigne
|
||||
{
|
||||
if (s[strlen(s) - 1] != '.')
|
||||
{
|
||||
list[nfiles] = strdup(s);
|
||||
list[nfiles] = Q_CopyString(s);
|
||||
#ifdef _WIN32
|
||||
strlwr(list[nfiles]);
|
||||
#endif // _WIN32
|
||||
@@ -825,9 +831,9 @@ void FS_Dir_f(void)
|
||||
{
|
||||
Com_Printf("%s\n", dirnames[i]);
|
||||
}
|
||||
free(dirnames[i]);
|
||||
Z_Free(dirnames[i]);
|
||||
}
|
||||
free(dirnames);
|
||||
Z_Free(dirnames);
|
||||
}
|
||||
Com_Printf("\n");
|
||||
}
|
||||
@@ -836,7 +842,6 @@ void FS_Dir_f(void)
|
||||
/*
|
||||
============
|
||||
FS_Path_f
|
||||
|
||||
============
|
||||
*/
|
||||
void FS_Path_f(void)
|
||||
@@ -907,6 +912,7 @@ char * FS_NextPath(char * prevpath)
|
||||
================
|
||||
FS_SetDefaultBasePath
|
||||
|
||||
LAMPERT:
|
||||
Added for QPS2 so we can change the game path prior to
|
||||
FS init and look for files in the USB drive or CDFS.
|
||||
================
|
||||
@@ -930,7 +936,7 @@ void FS_InitFilesystem(void)
|
||||
|
||||
Cmd_AddCommand("path", FS_Path_f);
|
||||
Cmd_AddCommand("link", FS_Link_f);
|
||||
Cmd_AddCommand("dir", FS_Dir_f);
|
||||
Cmd_AddCommand("dir", FS_Dir_f);
|
||||
|
||||
//
|
||||
// basedir <path>
|
||||
|
||||
@@ -74,18 +74,17 @@ then a packet only needs to be delivered if there is something in the
|
||||
unacknowledged reliable
|
||||
*/
|
||||
|
||||
cvar_t * showpackets;
|
||||
cvar_t * showdrop;
|
||||
cvar_t * qport;
|
||||
static cvar_t * showpackets;
|
||||
static cvar_t * showdrop;
|
||||
static cvar_t * qport;
|
||||
|
||||
netadr_t net_from;
|
||||
sizebuf_t net_message;
|
||||
byte net_message_buffer[MAX_MSGLEN];
|
||||
netadr_t net_from = {0};
|
||||
sizebuf_t net_message = {0};
|
||||
byte net_message_buffer[MAX_MSGLEN] = {0};
|
||||
|
||||
/*
|
||||
===============
|
||||
Netchan_Init
|
||||
|
||||
===============
|
||||
*/
|
||||
void Netchan_Init(void)
|
||||
|
||||
+4
-2
@@ -45,8 +45,10 @@ typedef struct
|
||||
qboolean ladder;
|
||||
} pml_t;
|
||||
|
||||
pmove_t * pm;
|
||||
pml_t pml;
|
||||
// LAMPERT 2015-10-27
|
||||
// Marked these locals as 'static'
|
||||
static pmove_t * pm;
|
||||
static pml_t pml;
|
||||
|
||||
// movement parameters
|
||||
float pm_stopspeed = 100;
|
||||
|
||||
+10
-9
@@ -69,6 +69,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#elif defined PS2_QUAKE
|
||||
|
||||
// LAMPERT: 2015-10-26
|
||||
// So the console prints a proper version string, instead of "NON-WIN32"
|
||||
#define BUILDSTRING "PS2-QUAKE"
|
||||
#define CPUSTRING "EE-MIPS-R5900-LE"
|
||||
|
||||
@@ -158,7 +159,7 @@ void COM_AddParm(char * parm);
|
||||
void COM_Init(void);
|
||||
void COM_InitArgv(int argc, char ** argv);
|
||||
|
||||
char * CopyString(const char * in);
|
||||
char * Q_CopyString(const char * in); // strdup replaces that used Z_Malloc.
|
||||
|
||||
//============================================================================
|
||||
|
||||
@@ -512,7 +513,7 @@ extern qboolean userinfo_modified;
|
||||
/*
|
||||
==============================================================
|
||||
|
||||
NET
|
||||
NET layer
|
||||
|
||||
==============================================================
|
||||
*/
|
||||
@@ -544,26 +545,25 @@ typedef enum
|
||||
typedef struct
|
||||
{
|
||||
netadrtype_t type;
|
||||
|
||||
byte ip[4];
|
||||
byte ipx[10];
|
||||
|
||||
unsigned short port;
|
||||
} netadr_t;
|
||||
|
||||
void NET_Init(void);
|
||||
void NET_Shutdown(void);
|
||||
void NET_Config(qboolean multiplayer);
|
||||
void NET_Sleep(int msec);
|
||||
|
||||
qboolean NET_GetPacket(netsrc_t sock, netadr_t * net_from, sizebuf_t * net_message);
|
||||
void NET_SendPacket(netsrc_t sock, int length, void * data, netadr_t to);
|
||||
void NET_SendPacket(netsrc_t sock, int length, const void * data, netadr_t to);
|
||||
|
||||
qboolean NET_CompareAdr(netadr_t a, netadr_t b);
|
||||
qboolean NET_CompareBaseAdr(netadr_t a, netadr_t b);
|
||||
qboolean NET_IsLocalAddress(netadr_t adr);
|
||||
char * NET_AdrToString(netadr_t a);
|
||||
qboolean NET_StringToAdr(char * s, netadr_t * a);
|
||||
void NET_Sleep(int msec);
|
||||
|
||||
char * NET_AdrToString(netadr_t addr);
|
||||
qboolean NET_StringToAdr(const char * s, netadr_t * addr);
|
||||
|
||||
//============================================================================
|
||||
|
||||
@@ -613,12 +613,13 @@ extern byte net_message_buffer[MAX_MSGLEN];
|
||||
void Netchan_Init(void);
|
||||
void Netchan_Setup(netsrc_t sock, netchan_t * chan, netadr_t adr, int qport);
|
||||
|
||||
qboolean Netchan_NeedReliable(netchan_t * chan);
|
||||
void Netchan_Transmit(netchan_t * chan, int length, byte * data);
|
||||
void Netchan_OutOfBand(int net_socket, netadr_t adr, int length, byte * data);
|
||||
void Netchan_OutOfBandPrint(int net_socket, netadr_t adr, char * format, ...);
|
||||
|
||||
qboolean Netchan_Process(netchan_t * chan, sizebuf_t * msg);
|
||||
qboolean Netchan_CanReliable(netchan_t * chan);
|
||||
qboolean Netchan_NeedReliable(netchan_t * chan);
|
||||
|
||||
/*
|
||||
==============================================================
|
||||
|
||||
+4
-13
@@ -8,7 +8,7 @@ of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
@@ -182,9 +182,8 @@ typedef enum
|
||||
MOVETYPE_NOCLIP, // origin and angles change with no interaction
|
||||
MOVETYPE_PUSH, // no clip to world, push on box contact
|
||||
MOVETYPE_STOP, // no clip to world, stops on box contact
|
||||
|
||||
MOVETYPE_WALK, // gravity
|
||||
MOVETYPE_STEP, // gravity, special edge handling
|
||||
MOVETYPE_WALK, // gravity
|
||||
MOVETYPE_STEP, // gravity, special edge handling
|
||||
MOVETYPE_FLY,
|
||||
MOVETYPE_TOSS, // gravity
|
||||
MOVETYPE_FLYMISSILE, // extra size to monsters
|
||||
@@ -482,10 +481,9 @@ extern int body_armor_index;
|
||||
#define MOD_FRIENDLY_FIRE 0x8000000
|
||||
|
||||
extern int meansOfDeath;
|
||||
|
||||
extern edict_t * g_edicts;
|
||||
|
||||
#define FOFS(x) (int) & (((edict_t *)0)->x)
|
||||
#define FOFS(x) (int) & (((edict_t *)0)->x)
|
||||
#define STOFS(x) (int) & (((spawn_temp_t *)0)->x)
|
||||
#define LLOFS(x) (int) & (((level_locals_t *)0)->x)
|
||||
#define CLOFS(x) (int) & (((gclient_t *)0)->x)
|
||||
@@ -504,30 +502,23 @@ extern cvar_t * password;
|
||||
extern cvar_t * spectator_password;
|
||||
extern cvar_t * g_select_empty;
|
||||
extern cvar_t * dedicated;
|
||||
|
||||
extern cvar_t * filterban;
|
||||
|
||||
extern cvar_t * sv_gravity;
|
||||
extern cvar_t * sv_maxvelocity;
|
||||
|
||||
extern cvar_t *gun_x, *gun_y, *gun_z;
|
||||
extern cvar_t * sv_rollspeed;
|
||||
extern cvar_t * sv_rollangle;
|
||||
|
||||
extern cvar_t * run_pitch;
|
||||
extern cvar_t * run_roll;
|
||||
extern cvar_t * bob_up;
|
||||
extern cvar_t * bob_pitch;
|
||||
extern cvar_t * bob_roll;
|
||||
|
||||
extern cvar_t * sv_cheats;
|
||||
extern cvar_t * maxclients;
|
||||
extern cvar_t * maxspectators;
|
||||
|
||||
extern cvar_t * flood_msgs;
|
||||
extern cvar_t * flood_persecond;
|
||||
extern cvar_t * flood_waitdelay;
|
||||
|
||||
extern cvar_t * sv_maplist;
|
||||
|
||||
#define world (&g_edicts[0])
|
||||
|
||||
+15
-14
@@ -45,30 +45,23 @@ cvar_t * maxspectators;
|
||||
cvar_t * maxentities;
|
||||
cvar_t * g_select_empty;
|
||||
cvar_t * dedicated;
|
||||
|
||||
cvar_t * filterban;
|
||||
|
||||
cvar_t * sv_maxvelocity;
|
||||
cvar_t * sv_gravity;
|
||||
|
||||
cvar_t * sv_rollspeed;
|
||||
cvar_t * sv_rollangle;
|
||||
cvar_t * gun_x;
|
||||
cvar_t * gun_y;
|
||||
cvar_t * gun_z;
|
||||
|
||||
cvar_t * run_pitch;
|
||||
cvar_t * run_roll;
|
||||
cvar_t * bob_up;
|
||||
cvar_t * bob_pitch;
|
||||
cvar_t * bob_roll;
|
||||
|
||||
cvar_t * sv_cheats;
|
||||
|
||||
cvar_t * flood_msgs;
|
||||
cvar_t * flood_persecond;
|
||||
cvar_t * flood_waitdelay;
|
||||
|
||||
cvar_t * sv_maplist;
|
||||
|
||||
void SpawnEntities(char * mapname, char * entities, char * spawnpoint);
|
||||
@@ -132,9 +125,10 @@ game_export_t * GetGameAPI(game_import_t * import)
|
||||
return &globals;
|
||||
}
|
||||
|
||||
#ifndef GAME_HARD_LINKED
|
||||
// this is only here so the functions in q_shared.c and q_shwin.c can link
|
||||
void Sys_Error(char * error, ...)
|
||||
#ifndef GAME_HARD_LINKED
|
||||
|
||||
void Sys_Error(const char * error, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
char text[1024];
|
||||
@@ -146,7 +140,7 @@ void Sys_Error(char * error, ...)
|
||||
gi.error(ERR_FATAL, "%s", text);
|
||||
}
|
||||
|
||||
void Com_Printf(char * msg, ...)
|
||||
void Com_Printf(const char * msg, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
char text[1024];
|
||||
@@ -158,7 +152,7 @@ void Com_Printf(char * msg, ...)
|
||||
gi.dprintf("%s", text);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // GAME_HARD_LINKED
|
||||
|
||||
//======================================================================
|
||||
|
||||
@@ -224,7 +218,7 @@ void EndDMLevel(void)
|
||||
// see if it's in the map list
|
||||
if (*sv_maplist->string)
|
||||
{
|
||||
s = strdup(sv_maplist->string);
|
||||
s = G_CopyString(sv_maplist->string);
|
||||
f = NULL;
|
||||
t = strtok(s, seps);
|
||||
while (t != NULL)
|
||||
@@ -241,19 +235,26 @@ void EndDMLevel(void)
|
||||
BeginIntermission(CreateTargetChangeLevel(f));
|
||||
}
|
||||
else
|
||||
{
|
||||
BeginIntermission(CreateTargetChangeLevel(t));
|
||||
free(s);
|
||||
}
|
||||
|
||||
gi.TagFree(s);
|
||||
return;
|
||||
}
|
||||
if (!f)
|
||||
{
|
||||
f = t;
|
||||
}
|
||||
t = strtok(NULL, seps);
|
||||
}
|
||||
free(s);
|
||||
gi.TagFree(s);
|
||||
}
|
||||
|
||||
if (level.nextmap[0]) // go to a specific map
|
||||
{
|
||||
BeginIntermission(CreateTargetChangeLevel(level.nextmap));
|
||||
}
|
||||
else
|
||||
{ // search for a changelevel
|
||||
ent = G_Find(NULL, FOFS(classname), "target_changelevel");
|
||||
|
||||
+2
-1
@@ -119,7 +119,6 @@ field_t fields[] = {
|
||||
{ "nextmap", STOFS(nextmap), F_LSTRING, FFL_SPAWNTEMP },
|
||||
|
||||
{ 0, 0, 0, 0 }
|
||||
|
||||
};
|
||||
|
||||
field_t levelfields[] =
|
||||
@@ -760,7 +759,9 @@ void ReadLevel(char * filename)
|
||||
|
||||
// fire any cross-level triggers
|
||||
if (ent->classname)
|
||||
{
|
||||
if (strcmp(ent->classname, "target_crosslevel_target") == 0)
|
||||
ent->nextthink = level.time + ent->delay;
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-2
@@ -8,7 +8,7 @@ of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
@@ -379,7 +379,6 @@ void vectoangles(vec3_t value1, vec3_t angles)
|
||||
char * G_CopyString(char * in)
|
||||
{
|
||||
char * out;
|
||||
|
||||
out = gi.TagMalloc(strlen(in) + 1, TAG_LEVEL);
|
||||
strcpy(out, in);
|
||||
return out;
|
||||
|
||||
+7
-6
@@ -118,10 +118,13 @@ struct edict_s
|
||||
typedef struct
|
||||
{
|
||||
// special messages
|
||||
void (*bprintf)(int printlevel, char * fmt, ...);
|
||||
void (*dprintf)(char * fmt, ...);
|
||||
void (*cprintf)(edict_t * ent, int printlevel, char * fmt, ...);
|
||||
void (*centerprintf)(edict_t * ent, char * fmt, ...);
|
||||
void (*bprintf)(int printlevel, const char * fmt, ...);
|
||||
void (*dprintf)(const char * fmt, ...);
|
||||
void (*cprintf)(edict_t * ent, int printlevel, const char * fmt, ...);
|
||||
void (*centerprintf)(edict_t * ent, const char * fmt, ...);
|
||||
void (*error)(const char * fmt, ...);
|
||||
|
||||
// sound system:
|
||||
void (*sound)(edict_t * ent, int channel, int soundindex, float volume, float attenuation, float timeofs);
|
||||
void (*positioned_sound)(vec3_t origin, edict_t * ent, int channel, int soundinedex, float volume, float attenuation, float timeofs);
|
||||
|
||||
@@ -131,8 +134,6 @@ typedef struct
|
||||
// they connect, and changes are sent to all connected clients.
|
||||
void (*configstring)(int num, char * string);
|
||||
|
||||
void (*error)(char * fmt, ...);
|
||||
|
||||
// the *index functions create configstrings and some internal server state
|
||||
int (*modelindex)(char * name);
|
||||
int (*soundindex)(char * name);
|
||||
|
||||
+1
-1
@@ -368,7 +368,7 @@ void SV_CalcGunOffset(edict_t * ent)
|
||||
|
||||
// gun height
|
||||
VectorClear(ent->client->ps.gunoffset);
|
||||
// ent->ps->gunorigin[2] += bob;
|
||||
// ent->ps->gunorigin[2] += bob;
|
||||
|
||||
// gun_x / gun_y / gun_z are development tools
|
||||
for (i = 0; i < 3; i++)
|
||||
|
||||
+8
-11
@@ -314,20 +314,18 @@ COLLISION DETECTION
|
||||
*/
|
||||
|
||||
// lower bits are stronger, and will eat weaker brushes completely
|
||||
#define CONTENTS_SOLID 1 // an eye is never valid in a solid
|
||||
#define CONTENTS_SOLID 1 // an eye is never valid in a solid
|
||||
#define CONTENTS_WINDOW 2 // translucent, but not watery
|
||||
#define CONTENTS_AUX 4
|
||||
#define CONTENTS_LAVA 8
|
||||
#define CONTENTS_SLIME 16
|
||||
#define CONTENTS_WATER 32
|
||||
#define CONTENTS_MIST 64
|
||||
#define CONTENTS_AUX 4
|
||||
#define CONTENTS_LAVA 8
|
||||
#define CONTENTS_SLIME 16
|
||||
#define CONTENTS_WATER 32
|
||||
#define CONTENTS_MIST 64
|
||||
#define LAST_VISIBLE_CONTENTS 64
|
||||
|
||||
// remaining contents are non-visible, and don't eat brushes
|
||||
|
||||
#define CONTENTS_AREAPORTAL 0x8000
|
||||
|
||||
#define CONTENTS_PLAYERCLIP 0x10000
|
||||
#define CONTENTS_AREAPORTAL 0x8000
|
||||
#define CONTENTS_PLAYERCLIP 0x10000
|
||||
#define CONTENTS_MONSTERCLIP 0x20000
|
||||
|
||||
// currents can be added to any other contents, and may be mixed
|
||||
@@ -847,7 +845,6 @@ typedef struct
|
||||
#define MZ2_WIDOW2_BEAM_SWEEP_9 208
|
||||
#define MZ2_WIDOW2_BEAM_SWEEP_10 209
|
||||
#define MZ2_WIDOW2_BEAM_SWEEP_11 210
|
||||
|
||||
// ROGUE
|
||||
|
||||
extern vec3_t monster_flash_offset[];
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
/*
|
||||
Copyright (C) 1997-2001 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
// cd_null.c -- null CD audio API
|
||||
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
/*
|
||||
Copyright (C) 1997-2001 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
// cl_null.c -- this file can stub out the entire client system
|
||||
// for pure dedicated servers
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
/*
|
||||
Copyright (C) 1997-2001 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
// glimp_null.c -- null OpenGL context.
|
||||
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
/*
|
||||
Copyright (C) 1997-2001 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
// in_null.c -- for systems without a mouse
|
||||
|
||||
|
||||
+61
-73
@@ -1,5 +1,24 @@
|
||||
/*
|
||||
Copyright (C) 1997-2001 Id Software, Inc.
|
||||
|
||||
// net_null.c -- null network functions.
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
// net_null.c -- null network driver.
|
||||
|
||||
#include "common/q_common.h"
|
||||
|
||||
@@ -11,22 +30,30 @@ NET_CompareAdr
|
||||
qboolean NET_CompareAdr(netadr_t a, netadr_t b)
|
||||
{
|
||||
if (a.type != b.type)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (a.type == NA_LOOPBACK)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (a.type == NA_IP)
|
||||
{
|
||||
if (a.ip[0] == b.ip[0] && a.ip[1] == b.ip[1] && a.ip[2] == b.ip[2] && a.ip[3] == b.ip[3] && a.port == b.port)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (a.type == NA_IPX)
|
||||
{
|
||||
if ((memcmp(a.ipx, b.ipx, 10) == 0) && a.port == b.port)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -34,33 +61,51 @@ qboolean NET_CompareAdr(netadr_t a, netadr_t b)
|
||||
/*
|
||||
===================
|
||||
NET_CompareBaseAdr
|
||||
|
||||
Compares without the port
|
||||
===================
|
||||
*/
|
||||
qboolean NET_CompareBaseAdr(netadr_t a, netadr_t b)
|
||||
{
|
||||
// Compares without the port
|
||||
|
||||
if (a.type != b.type)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (a.type == NA_LOOPBACK)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (a.type == NA_IP)
|
||||
{
|
||||
if (a.ip[0] == b.ip[0] && a.ip[1] == b.ip[1] && a.ip[2] == b.ip[2] && a.ip[3] == b.ip[3])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (a.type == NA_IPX)
|
||||
{
|
||||
if ((memcmp(a.ipx, b.ipx, 10) == 0))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
NET_IsLocalAddress
|
||||
=============
|
||||
*/
|
||||
qboolean NET_IsLocalAddress(netadr_t adr)
|
||||
{
|
||||
return adr.type == NA_LOOPBACK;
|
||||
}
|
||||
|
||||
/*
|
||||
===================
|
||||
NET_AdrToString
|
||||
@@ -77,105 +122,48 @@ char * NET_AdrToString(netadr_t a)
|
||||
NET_StringToAdr
|
||||
=============
|
||||
*/
|
||||
qboolean NET_StringToAdr(char * s, netadr_t * a)
|
||||
qboolean NET_StringToAdr(const char * s, netadr_t * a)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
NET_IsLocalAddress
|
||||
=============
|
||||
====================
|
||||
NET_GetPacket
|
||||
====================
|
||||
*/
|
||||
qboolean NET_IsLocalAddress(netadr_t adr)
|
||||
{
|
||||
return adr.type == NA_LOOPBACK;
|
||||
}
|
||||
|
||||
/*
|
||||
=============================================================================
|
||||
|
||||
LOOPBACK BUFFERS FOR LOCAL PLAYER
|
||||
|
||||
=============================================================================
|
||||
*/
|
||||
|
||||
qboolean NET_GetLoopPacket(netsrc_t sock, netadr_t * net_from, sizebuf_t * net_message)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void NET_SendLoopPacket(netsrc_t sock, int length, void * data, netadr_t to)
|
||||
{
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
qboolean NET_GetPacket(netsrc_t sock, netadr_t * net_from, sizebuf_t * net_message)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
void NET_SendPacket(netsrc_t sock, int length, void * data, netadr_t to)
|
||||
{
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
/*
|
||||
====================
|
||||
NET_Socket
|
||||
NET_SendPacket
|
||||
====================
|
||||
*/
|
||||
int NET_IPSocket(char * net_interface, int port)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
NET_OpenIP
|
||||
====================
|
||||
*/
|
||||
void NET_OpenIP(void)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
IPX_Socket
|
||||
====================
|
||||
*/
|
||||
int NET_IPXSocket(int port)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
NET_OpenIPX
|
||||
====================
|
||||
*/
|
||||
void NET_OpenIPX(void)
|
||||
void NET_SendPacket(netsrc_t sock, int length, const void * data, netadr_t to)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
NET_Config
|
||||
|
||||
A single player game will only use the loopback code
|
||||
====================
|
||||
*/
|
||||
void NET_Config(qboolean multiplayer)
|
||||
{
|
||||
// A single player game will only use the loopback code
|
||||
}
|
||||
|
||||
// sleeps msec or until net socket is ready
|
||||
/*
|
||||
====================
|
||||
NET_Sleep
|
||||
====================
|
||||
*/
|
||||
void NET_Sleep(int msec)
|
||||
{
|
||||
// Sleeps msec or until net socket is ready
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
/*
|
||||
Copyright (C) 1997-2001 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
// snddma_null.c
|
||||
// all other sound mixing is portable
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
/*
|
||||
Copyright (C) 1997-2001 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
// sv_null.c -- this file can stub out the entire server system
|
||||
// for pure net-only clients
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
/*
|
||||
Copyright (C) 1997-2001 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
// swimp_null.h -- null software renderer driver
|
||||
|
||||
#include "client/client.h"
|
||||
|
||||
|
||||
+21
-6
@@ -1,3 +1,22 @@
|
||||
/*
|
||||
Copyright (C) 1997-2001 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
// sys_null.h -- null system driver to aid porting efforts
|
||||
|
||||
@@ -8,11 +27,7 @@ unsigned sys_frame_time;
|
||||
|
||||
//=============================================================================
|
||||
|
||||
void Sys_mkdir(char * path)
|
||||
{
|
||||
}
|
||||
|
||||
void Sys_Error(char * error, ...)
|
||||
void Sys_Error(const char * error, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
|
||||
@@ -44,7 +59,7 @@ char * Sys_ConsoleInput(void)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void Sys_ConsoleOutput(char * string)
|
||||
void Sys_ConsoleOutput(const char * string)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
+22
-3
@@ -1,3 +1,22 @@
|
||||
/*
|
||||
Copyright (C) 1997-2001 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
// vid_null.c -- null video driver to aid porting efforts
|
||||
// this assumes that one of the refs is statically linked to the executable
|
||||
@@ -24,9 +43,9 @@ DIRECT LINK GLUE
|
||||
enum
|
||||
{
|
||||
MAXPRINTMSG = 4096
|
||||
}
|
||||
};
|
||||
|
||||
void VID_Printf(int print_level, char * fmt, ...)
|
||||
void VID_Printf(int print_level, const char * fmt, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
char msg[MAXPRINTMSG];
|
||||
@@ -45,7 +64,7 @@ void VID_Printf(int print_level, char * fmt, ...)
|
||||
}
|
||||
}
|
||||
|
||||
void VID_Error(int err_level, char * fmt, ...)
|
||||
void VID_Error(int err_level, const char * fmt, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
char msg[MAXPRINTMSG];
|
||||
|
||||
+45
-2
@@ -15,10 +15,13 @@
|
||||
//
|
||||
// TODO:
|
||||
//
|
||||
// - move main to a separate file (main_ps2.c)
|
||||
// - replace raw malloc calls so we can account for memory
|
||||
// - bring up the optimized asm math functions for the PS2 (on math_funcs.c)
|
||||
//
|
||||
// - Need to find this 'ps2mkisofs' to be able to make a proper PS2 ISO!!!
|
||||
//
|
||||
// - probably add a "welcome screen" right after load to display idSoftware
|
||||
// copyright and maybe some self promoting as well ;)
|
||||
//
|
||||
|
||||
//FIXME TEMP testing stuff
|
||||
#include "client/client.h"
|
||||
@@ -26,6 +29,35 @@ extern refexport_t re;
|
||||
extern void Test_PS2_Draw2D(void);
|
||||
extern void Test_PS2_Cinematics(void);
|
||||
|
||||
static const char * all_menu_names[] =
|
||||
{
|
||||
"menu_main",
|
||||
"menu_game",
|
||||
"menu_loadgame",
|
||||
"menu_savegame",
|
||||
"menu_joinserver",
|
||||
"menu_addressbook",
|
||||
"menu_startserver",
|
||||
"menu_dmoptions",
|
||||
"menu_playerconfig",
|
||||
"menu_downloadoptions",
|
||||
"menu_credits",
|
||||
"menu_multiplayer",
|
||||
"menu_video",
|
||||
"menu_options",
|
||||
"menu_keys",
|
||||
"menu_quit"
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
NUM_MENUS = sizeof(all_menu_names) / sizeof(all_menu_names[0]),
|
||||
MENU_MSEC = 6 * 1000
|
||||
};
|
||||
|
||||
static int next_menu = 0;
|
||||
static int time_til_next_menu = MENU_MSEC;
|
||||
|
||||
/*
|
||||
================
|
||||
PS2 main() function
|
||||
@@ -75,6 +107,8 @@ int main(void)
|
||||
char * argv[] = { "QPS2.ELF" };
|
||||
Qcommon_Init(argc, argv);
|
||||
|
||||
Cbuf_AddText((char *)all_menu_names[next_menu]);
|
||||
|
||||
oldtime = Sys_Milliseconds();
|
||||
for (;;)
|
||||
{
|
||||
@@ -87,6 +121,15 @@ int main(void)
|
||||
|
||||
Qcommon_Frame(time);
|
||||
oldtime = newtime;
|
||||
|
||||
//TEST cycling all the menus
|
||||
if (time_til_next_menu <= 0 && next_menu < NUM_MENUS)
|
||||
{
|
||||
Cbuf_AddText((char *)all_menu_names[next_menu++]);
|
||||
time_til_next_menu = MENU_MSEC;
|
||||
}
|
||||
time_til_next_menu -= time;
|
||||
//TEST cycling all the menus
|
||||
}
|
||||
#endif //0
|
||||
|
||||
|
||||
+112
-19
@@ -18,16 +18,21 @@
|
||||
extern void Sys_Error(const char * error, ...);
|
||||
|
||||
// For debug printing
|
||||
static const char * mem_tag_names[MEMTAG_COUNT] =
|
||||
const char * ps2_mem_tag_names[MEMTAG_COUNT] =
|
||||
{
|
||||
"MEMTAG_FILESYS",
|
||||
"MEMTAG_HUNK_ALLOC",
|
||||
"MEMTAG_TEXIMAGE"
|
||||
"MISC",
|
||||
"QUAKE",
|
||||
"RENDERER",
|
||||
"TEX_IMAGE",
|
||||
"HUNK_ALLOC"
|
||||
};
|
||||
|
||||
// Tags updated on every alloc/free.
|
||||
unsigned int ps2_mem_tag_counts[MEMTAG_COUNT] = {0};
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// malloc/memalign hooks:
|
||||
// malloc/free hooks:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
@@ -43,15 +48,14 @@ void * PS2_MemAlloc(int size_bytes, ps2_mem_tag_t tag)
|
||||
Sys_Error("Trying to allocate zero or negative size (%d)!", size_bytes);
|
||||
}
|
||||
|
||||
//TODO add tracking counters!
|
||||
(void)tag;
|
||||
|
||||
void * ptr = malloc(size_bytes);
|
||||
if (ptr == NULL)
|
||||
{
|
||||
Sys_Error("Out-of-memory for tag %s!", mem_tag_names[tag]);
|
||||
Sys_Error("Out-of-memory for tag %s! Failed to alloc %d bytes.",
|
||||
ps2_mem_tag_names[tag], size_bytes);
|
||||
}
|
||||
|
||||
ps2_mem_tag_counts[tag] += size_bytes;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
@@ -60,29 +64,118 @@ void * PS2_MemAlloc(int size_bytes, ps2_mem_tag_t tag)
|
||||
PS2_MemFree
|
||||
================
|
||||
*/
|
||||
void PS2_MemFree(void * ptr, ps2_mem_tag_t tag)
|
||||
void PS2_MemFree(void * ptr, int size_bytes, ps2_mem_tag_t tag)
|
||||
{
|
||||
if (ptr == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//TODO add tracking counters!
|
||||
(void)tag;
|
||||
|
||||
ps2_mem_tag_counts[tag] -= size_bytes;
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
PS2_AddRenderPacketMem
|
||||
PS2_FormatMemoryUnit
|
||||
================
|
||||
*/
|
||||
void PS2_AddRenderPacketMem(unsigned int size_bytes)
|
||||
const char * PS2_FormatMemoryUnit(unsigned int size_bytes, int abbreviated)
|
||||
{
|
||||
// TODO so we can keep track of memory allocated
|
||||
// externally by the SDK for render packets!
|
||||
(void)size_bytes;
|
||||
enum
|
||||
{
|
||||
KILOBYTE = 1024,
|
||||
MEGABYTE = 1024 * KILOBYTE,
|
||||
GIGABYTE = 1024 * MEGABYTE
|
||||
};
|
||||
|
||||
const char * mem_unit_str;
|
||||
float adjusted_size;
|
||||
|
||||
if (size_bytes < KILOBYTE)
|
||||
{
|
||||
mem_unit_str = abbreviated ? "B" : "Bytes";
|
||||
adjusted_size = (float)size_bytes;
|
||||
}
|
||||
else if (size_bytes < MEGABYTE)
|
||||
{
|
||||
mem_unit_str = abbreviated ? "KB" : "Kilobytes";
|
||||
adjusted_size = size_bytes / 1024.0f;
|
||||
}
|
||||
else if (size_bytes < GIGABYTE)
|
||||
{
|
||||
mem_unit_str = abbreviated ? "MB" : "Megabytes";
|
||||
adjusted_size = size_bytes / 1024.0f / 1024.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
mem_unit_str = abbreviated ? "GB" : "Gigabytes";
|
||||
adjusted_size = size_bytes / 1024.0f / 1024.0f / 1024.0f;
|
||||
}
|
||||
|
||||
char * fmtbuf;
|
||||
int chars_written;
|
||||
char num_str_buf[100];
|
||||
|
||||
// Max chars reserved for the output string, max `num_str_buf + 28` chars for the unit str:
|
||||
enum
|
||||
{
|
||||
MEM_UNIT_STR_MAXLEN = sizeof(num_str_buf) + 28
|
||||
};
|
||||
static int bufnum = 0;
|
||||
static char local_str_buf[8][MEM_UNIT_STR_MAXLEN];
|
||||
|
||||
fmtbuf = local_str_buf[bufnum];
|
||||
bufnum = (bufnum + 1) & 7;
|
||||
|
||||
// We only care about the first 2 decimal digs
|
||||
chars_written = snprintf(num_str_buf, 100, "%.2f", adjusted_size);
|
||||
if (chars_written <= 0)
|
||||
{
|
||||
fmtbuf[0] = '?';
|
||||
fmtbuf[1] = '?';
|
||||
fmtbuf[2] = '?';
|
||||
fmtbuf[3] = '\0';
|
||||
return fmtbuf; // Error return
|
||||
}
|
||||
|
||||
// Remove trailing zeros if no significant decimal digits:
|
||||
char * p = num_str_buf;
|
||||
for (; *p; ++p)
|
||||
{
|
||||
if (*p == '.')
|
||||
{
|
||||
// Find the end of the string
|
||||
while (*++p)
|
||||
{
|
||||
}
|
||||
|
||||
// Remove trailing zeros
|
||||
while (*--p == '0')
|
||||
{
|
||||
*p = '\0';
|
||||
}
|
||||
// If the dot was left alone at the end, remove it too
|
||||
if (*p == '.')
|
||||
{
|
||||
*p = '\0';
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Consolidate the strings:
|
||||
chars_written = snprintf(fmtbuf, MEM_UNIT_STR_MAXLEN, "%s %s", num_str_buf, mem_unit_str);
|
||||
if (chars_written <= 0)
|
||||
{
|
||||
fmtbuf[0] = '?';
|
||||
fmtbuf[1] = '?';
|
||||
fmtbuf[2] = '?';
|
||||
fmtbuf[3] = '\0';
|
||||
return fmtbuf; // Error return
|
||||
}
|
||||
|
||||
return fmtbuf;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
@@ -148,7 +241,7 @@ void Hunk_Free(void * base)
|
||||
{
|
||||
if (base != NULL)
|
||||
{
|
||||
PS2_MemFree(base, MEMTAG_HUNK_ALLOC);
|
||||
PS2_MemFree(base, hunk_max_size, MEMTAG_HUNK_ALLOC);
|
||||
}
|
||||
--hunk_count;
|
||||
}
|
||||
+15
-6
@@ -14,19 +14,28 @@
|
||||
#define PS2_MEM_ALLOC_H
|
||||
|
||||
// NOTE:
|
||||
// Be sure to updated mem_tag_names[] in the .c when changing this!
|
||||
// Be sure to updated ps2_mem_tag_names[] in the .c when changing this!
|
||||
typedef enum
|
||||
{
|
||||
MEMTAG_FILESYS, // Miscellaneous file systems allocations.
|
||||
MEMTAG_HUNK_ALLOC, // Allocs for the Hunk_*() functions.
|
||||
MEMTAG_MISC, // Miscellaneous/uncategorized (includes the estimate size of the ELF executable).
|
||||
MEMTAG_QUAKE, // Game allocations: Z_Malloc/Z_TagMalloc/etc.
|
||||
MEMTAG_RENDERER, // Things related to rendering / the refresh module.
|
||||
MEMTAG_TEXIMAGE, // Allocs related to images/textures/palettes.
|
||||
MEMTAG_HUNK_ALLOC, // Allocs for the Hunk_*() functions.
|
||||
MEMTAG_COUNT // Number of entries in this enum. Internal use only.
|
||||
} ps2_mem_tag_t;
|
||||
|
||||
void * PS2_MemAlloc(int size_bytes, ps2_mem_tag_t tag);
|
||||
void PS2_MemFree(void * ptr, ps2_mem_tag_t tag);
|
||||
void PS2_AddRenderPacketMem(unsigned int size_bytes);
|
||||
extern const char * ps2_mem_tag_names[MEMTAG_COUNT]; // Printable strings for the above enum.
|
||||
extern unsigned int ps2_mem_tag_counts[MEMTAG_COUNT]; // Current memory counts for each of the above tags.
|
||||
|
||||
// Allocators:
|
||||
void * PS2_MemAlloc(int size_bytes, ps2_mem_tag_t tag);
|
||||
void PS2_MemFree(void * ptr, int size_bytes, ps2_mem_tag_t tag);
|
||||
|
||||
// Formatter for printing the memory tags.
|
||||
const char * PS2_FormatMemoryUnit(unsigned int memorySizeInBytes, int abbreviated);
|
||||
|
||||
// Wrapper for memseting pointers to objects/structures.
|
||||
#define PS2_MemClearObj(obj_ptr) memset((obj_ptr), 0, sizeof(*(obj_ptr)))
|
||||
|
||||
#endif // PS2_MEM_ALLOC_H
|
||||
@@ -0,0 +1,329 @@
|
||||
|
||||
/* ================================================================================================
|
||||
* -*- C -*-
|
||||
* File: net_ps2.c
|
||||
* Author: Guilherme R. Lampert
|
||||
* Created on: 27/10/15
|
||||
* Brief: Implementation of Quake2 NET_ functions (network module) for the PS2.
|
||||
*
|
||||
* This source code is released under the GNU GPL v2 license.
|
||||
* Check the accompanying LICENSE file for details.
|
||||
* ================================================================================================ */
|
||||
|
||||
#include "common/q_common.h"
|
||||
|
||||
//
|
||||
// Local loopback (localhost) buffers, adapted from net_wins.c
|
||||
//
|
||||
|
||||
enum
|
||||
{
|
||||
MAX_LOOPBACK = 4
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int datalen;
|
||||
byte data[MAX_MSGLEN];
|
||||
} loopmsg_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int get;
|
||||
int send;
|
||||
loopmsg_t msgs[MAX_LOOPBACK];
|
||||
} loopback_t;
|
||||
|
||||
// Alignment is not strictly necessary here, but might boost memcpy/memset perf.
|
||||
static loopback_t loopbacks[2] __attribute__((aligned(16)));
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// Misc NET helpers:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
/*
|
||||
===================
|
||||
NET_CompareAdr
|
||||
===================
|
||||
*/
|
||||
qboolean NET_CompareAdr(netadr_t a, netadr_t b)
|
||||
{
|
||||
if (a.type == NA_LOOPBACK)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (a.type != b.type)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (a.type == NA_IP)
|
||||
{
|
||||
if (a.ip[0] == b.ip[0] &&
|
||||
a.ip[1] == b.ip[1] &&
|
||||
a.ip[2] == b.ip[2] &&
|
||||
a.ip[3] == b.ip[3] &&
|
||||
a.port == b.port)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (a.type == NA_IPX)
|
||||
{
|
||||
if ((memcmp(a.ipx, b.ipx, 10) == 0) && a.port == b.port)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===================
|
||||
NET_CompareBaseAdr
|
||||
===================
|
||||
*/
|
||||
qboolean NET_CompareBaseAdr(netadr_t a, netadr_t b)
|
||||
{
|
||||
// Compares without the port num.
|
||||
|
||||
if (a.type == NA_LOOPBACK)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (a.type != b.type)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (a.type == NA_IP)
|
||||
{
|
||||
if (a.ip[0] == b.ip[0] &&
|
||||
a.ip[1] == b.ip[1] &&
|
||||
a.ip[2] == b.ip[2] &&
|
||||
a.ip[3] == b.ip[3])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (a.type == NA_IPX)
|
||||
{
|
||||
if ((memcmp(a.ipx, b.ipx, 10) == 0))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===================
|
||||
NET_AdrToString
|
||||
===================
|
||||
*/
|
||||
char * NET_AdrToString(netadr_t addr)
|
||||
{
|
||||
// FIXME temp but fine, since we are currently localhost bound
|
||||
#define ntohs(x) (x)
|
||||
|
||||
static char s[64];
|
||||
|
||||
if (addr.type == NA_LOOPBACK)
|
||||
{
|
||||
Com_sprintf(s, sizeof(s), "loopback");
|
||||
}
|
||||
else if (addr.type == NA_IP)
|
||||
{
|
||||
Com_sprintf(s, sizeof(s), "%i.%i.%i.%i:%i",
|
||||
addr.ip[0], addr.ip[1], addr.ip[2], addr.ip[3],
|
||||
ntohs(addr.port));
|
||||
}
|
||||
else
|
||||
{
|
||||
Com_sprintf(s, sizeof(s), "%02x%02x%02x%02x:%02x%02x%02x%02x%02x%02x:%i",
|
||||
addr.ipx[0], addr.ipx[1], addr.ipx[2], addr.ipx[3], addr.ipx[4],
|
||||
addr.ipx[5], addr.ipx[6], addr.ipx[7], addr.ipx[8], addr.ipx[9],
|
||||
ntohs(addr.port));
|
||||
}
|
||||
|
||||
return s;
|
||||
|
||||
#undef ntohs
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
NET_StringToAdr
|
||||
=============
|
||||
*/
|
||||
qboolean NET_StringToAdr(const char * s, netadr_t * addr)
|
||||
{
|
||||
if (strcmp(s, "localhost") == 0 || strcmp(s, "loopback") == 0)
|
||||
{
|
||||
memset(addr, 0, sizeof(*addr));
|
||||
addr->type = NA_LOOPBACK;
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO Only localhost is currently supported!
|
||||
memset(addr, 0, sizeof(*addr));
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
NET_IsLocalAddress
|
||||
=============
|
||||
*/
|
||||
qboolean NET_IsLocalAddress(netadr_t adr)
|
||||
{
|
||||
return adr.type == NA_LOOPBACK;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// Loopback buffers for the local player:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
/*
|
||||
====================
|
||||
NET_GetLoopPacket
|
||||
====================
|
||||
*/
|
||||
static qboolean NET_GetLoopPacket(netsrc_t sock, netadr_t * net_from, sizebuf_t * net_message)
|
||||
{
|
||||
// Same code from net_wins.c, Win32 Quake2.
|
||||
|
||||
loopback_t * loop = &loopbacks[sock];
|
||||
|
||||
if (loop->send - loop->get > MAX_LOOPBACK)
|
||||
{
|
||||
loop->get = loop->send - MAX_LOOPBACK;
|
||||
}
|
||||
|
||||
if (loop->get >= loop->send)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int i = loop->get & (MAX_LOOPBACK - 1);
|
||||
loop->get++;
|
||||
|
||||
memcpy(net_message->data, loop->msgs[i].data, loop->msgs[i].datalen);
|
||||
net_message->cursize = loop->msgs[i].datalen;
|
||||
|
||||
memset(net_from, 0, sizeof(*net_from));
|
||||
net_from->type = NA_LOOPBACK;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
NET_GetPacket
|
||||
====================
|
||||
*/
|
||||
qboolean NET_GetPacket(netsrc_t sock, netadr_t * net_from, sizebuf_t * net_message)
|
||||
{
|
||||
if (NET_GetLoopPacket(sock, net_from, net_message))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO Only localhost is currently supported!
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
NET_SendLoopPacket
|
||||
====================
|
||||
*/
|
||||
static void NET_SendLoopPacket(netsrc_t sock, int length, const void * data, netadr_t to)
|
||||
{
|
||||
loopback_t * loop = &loopbacks[sock ^ 1];
|
||||
|
||||
int i = loop->send & (MAX_LOOPBACK - 1);
|
||||
loop->send++;
|
||||
|
||||
memcpy(loop->msgs[i].data, data, length);
|
||||
loop->msgs[i].datalen = length;
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
NET_SendPacket
|
||||
====================
|
||||
*/
|
||||
void NET_SendPacket(netsrc_t sock, int length, const void * data, netadr_t to)
|
||||
{
|
||||
if (to.type == NA_LOOPBACK)
|
||||
{
|
||||
NET_SendLoopPacket(sock, length, data, to);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO Only localhost is currently supported!
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// NET startup/shutdown:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
/*
|
||||
====================
|
||||
NET_Config
|
||||
====================
|
||||
*/
|
||||
void NET_Config(qboolean multiplayer)
|
||||
{
|
||||
Com_DPrintf("---- NET_Config ----\n");
|
||||
|
||||
// A single player game will only use the loopback code
|
||||
if (multiplayer)
|
||||
{
|
||||
Com_Error(ERR_DROP, "Quake2 multiplayer currently unsupported!\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
NET_Sleep
|
||||
====================
|
||||
*/
|
||||
void NET_Sleep(int msec)
|
||||
{
|
||||
// TODO This is where Quake calls select() with msec timeout.
|
||||
(void)msec;
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
NET_Init
|
||||
====================
|
||||
*/
|
||||
void NET_Init(void)
|
||||
{
|
||||
Com_DPrintf("---- NET_Init ----\n");
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
NET_Shutdown
|
||||
====================
|
||||
*/
|
||||
void NET_Shutdown(void)
|
||||
{
|
||||
Com_DPrintf("---- NET_Shutdown ----\n");
|
||||
}
|
||||
+102
-90
@@ -31,6 +31,7 @@ static cvar_t * r_ps2_vid_height = NULL;
|
||||
static cvar_t * r_ps2_ui_brightness = NULL;
|
||||
static cvar_t * r_ps2_fade_scr_alpha = NULL;
|
||||
static cvar_t * r_ps2_show_fps = NULL;
|
||||
static cvar_t * r_ps2_show_mem_tags = NULL;
|
||||
|
||||
// Average multiple frames together to smooth changes out a bit.
|
||||
enum { MAX_FPS_HIST = 4 };
|
||||
@@ -55,7 +56,7 @@ typedef struct
|
||||
u16 u0, v0;
|
||||
u16 u1, v1;
|
||||
byte r, g, b, a;
|
||||
} ps2_2d_quad_t;
|
||||
} screen_quad_t;
|
||||
|
||||
enum
|
||||
{
|
||||
@@ -75,7 +76,7 @@ static int fade_scr_index = -1;
|
||||
|
||||
// 2D draw calls are always batched to try avoiding unnecessary texture switches.
|
||||
static int next_in_2d_batch = 0;
|
||||
static ps2_2d_quad_t draw2d_batch[DRAW2D_BATCH_SIZE] __attribute__((aligned(16)));
|
||||
static screen_quad_t draw2d_batch[DRAW2D_BATCH_SIZE] __attribute__((aligned(16)));
|
||||
#define DRAW2D_NEXT_BATCH_ELEMENT() (&draw2d_batch[next_in_2d_batch++])
|
||||
|
||||
//
|
||||
@@ -265,30 +266,6 @@ static void PS2_InitDrawingEnvironment(void)
|
||||
wrap.maxv = MAX_TEXIMAGE_SIZE;
|
||||
q = draw_texture_wrapping(q, 0, &wrap);
|
||||
|
||||
/////////
|
||||
|
||||
//FIXME TEMP clean this up
|
||||
/*
|
||||
atest_t atest;
|
||||
dtest_t dtest;
|
||||
ztest_t ztest;
|
||||
|
||||
atest.enable = DRAW_ENABLE;
|
||||
atest.method = ATEST_METHOD_GREATER;
|
||||
atest.compval = 0;
|
||||
atest.keep = ATEST_KEEP_FRAMEBUFFER;
|
||||
|
||||
dtest.enable = DRAW_DISABLE;
|
||||
dtest.pass = DRAW_DISABLE;
|
||||
|
||||
ztest.enable = DRAW_ENABLE;
|
||||
ztest.method = ZTEST_METHOD_GREATER_EQUAL;
|
||||
|
||||
q = draw_pixel_test(q, 0, &atest, &dtest, &ztest);
|
||||
//*/
|
||||
|
||||
/////////
|
||||
|
||||
q = draw_finish(q);
|
||||
dma_channel_send_normal(DMA_CHANNEL_GIF, packet->data, (q - packet->data), 0, 0);
|
||||
dma_wait_fast();
|
||||
@@ -391,7 +368,7 @@ enum elem2d_type
|
||||
ELEM_2D_COLOR_ONLY,
|
||||
ELEM_2D_FADE_SCR
|
||||
};
|
||||
static qword_t * PS2_Draw2DAddToPacket(qword_t * qwptr, const ps2_2d_quad_t * quad, enum elem2d_type type)
|
||||
static qword_t * PS2_Draw2DAddToPacket(qword_t * qwptr, const screen_quad_t * quad, enum elem2d_type type)
|
||||
{
|
||||
rect_t rect;
|
||||
texrect_t texrect;
|
||||
@@ -509,8 +486,8 @@ PS2_Draw2DBatchSortPredicate
|
||||
*/
|
||||
static int PS2_Draw2DBatchSortPredicate(const void * a, const void * b)
|
||||
{
|
||||
const ps2_2d_quad_t * q1 = (const ps2_2d_quad_t *)a;
|
||||
const ps2_2d_quad_t * q2 = (const ps2_2d_quad_t *)b;
|
||||
const screen_quad_t * q1 = (const screen_quad_t *)a;
|
||||
const screen_quad_t * q2 = (const screen_quad_t *)b;
|
||||
|
||||
// Group by texture:
|
||||
int result = q1->tex_index - q2->tex_index;
|
||||
@@ -530,7 +507,7 @@ static int PS2_Draw2DBatchSortPredicate(const void * a, const void * b)
|
||||
PS2_SortAndDraw2DElements
|
||||
================
|
||||
*/
|
||||
static void PS2_SortAndDraw2DElements(ps2_2d_quad_t * batch, int batch_size)
|
||||
static void PS2_SortAndDraw2DElements(screen_quad_t * batch, int batch_size)
|
||||
{
|
||||
if (batch_size <= 0)
|
||||
{
|
||||
@@ -538,7 +515,7 @@ static void PS2_SortAndDraw2DElements(ps2_2d_quad_t * batch, int batch_size)
|
||||
}
|
||||
|
||||
// Sort by texture, so we only switch once per texture image:
|
||||
qsort(batch, batch_size, sizeof(ps2_2d_quad_t), &PS2_Draw2DBatchSortPredicate);
|
||||
qsort(batch, batch_size, sizeof(screen_quad_t), &PS2_Draw2DBatchSortPredicate);
|
||||
|
||||
// Non-textured elements draw first. Since those have negative
|
||||
// tex_index, they are at the front of the sorted batch.
|
||||
@@ -546,7 +523,7 @@ static void PS2_SortAndDraw2DElements(ps2_2d_quad_t * batch, int batch_size)
|
||||
|
||||
int i;
|
||||
enum elem2d_type quad_type;
|
||||
const ps2_2d_quad_t * quad;
|
||||
const screen_quad_t * quad;
|
||||
|
||||
for (i = 0; i < batch_size; ++i)
|
||||
{
|
||||
@@ -647,17 +624,14 @@ PS2_DrawFullScreenCinematic
|
||||
*/
|
||||
static void PS2_DrawFullScreenCinematic(void)
|
||||
{
|
||||
if (!cinematic_frame.draw_pending)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
texrect_t texrect;
|
||||
|
||||
texrect.v0.x = cinematic_frame.x - 2;
|
||||
texrect.v0.y = cinematic_frame.y - 2;
|
||||
texrect.v1.x = cinematic_frame.x + cinematic_frame.w + 2;
|
||||
texrect.v1.y = cinematic_frame.y + cinematic_frame.h + 2;
|
||||
// Cinematic are not filling the screen properly on my tests...
|
||||
// Adding these hackish offsets for now.
|
||||
texrect.v0.x = cinematic_frame.x - 1;
|
||||
texrect.v0.y = cinematic_frame.y - 1;
|
||||
texrect.v1.x = cinematic_frame.x + cinematic_frame.w + 1;
|
||||
texrect.v1.y = cinematic_frame.y + cinematic_frame.h + 45;
|
||||
texrect.v0.z = 0xFFFFFFFF;
|
||||
texrect.v1.z = 0xFFFFFFFF;
|
||||
|
||||
@@ -694,39 +668,63 @@ PS2_DrawFPSCounter
|
||||
*/
|
||||
static void PS2_DrawFPSCounter(void)
|
||||
{
|
||||
if (!ps2ref.show_fps_count)
|
||||
{
|
||||
return;
|
||||
}
|
||||
int time_millisec = Sys_Milliseconds(); // Real time clock
|
||||
int frame_time = time_millisec - fps.previous_time;
|
||||
|
||||
int time_millisec = Sys_Milliseconds(); // Real time clock
|
||||
int frame_time = time_millisec - fps.previous_time;
|
||||
|
||||
fps.times_hist[fps.index++] = frame_time;
|
||||
fps.previous_time = time_millisec;
|
||||
fps.times_hist[fps.index++] = frame_time;
|
||||
fps.previous_time = time_millisec;
|
||||
|
||||
// Average our time history when we get enough samples:
|
||||
if (fps.index == MAX_FPS_HIST)
|
||||
{
|
||||
int i, total = 0;
|
||||
for (i = 0; i < MAX_FPS_HIST; ++i)
|
||||
{
|
||||
total += fps.times_hist[i];
|
||||
}
|
||||
if (fps.index == MAX_FPS_HIST)
|
||||
{
|
||||
int i, total = 0;
|
||||
for (i = 0; i < MAX_FPS_HIST; ++i)
|
||||
{
|
||||
total += fps.times_hist[i];
|
||||
}
|
||||
|
||||
if (total == 0)
|
||||
{
|
||||
total = 1;
|
||||
}
|
||||
if (total == 0)
|
||||
{
|
||||
total = 1;
|
||||
}
|
||||
|
||||
fps.fps_count = (10000 * MAX_FPS_HIST / total);
|
||||
fps.fps_count = (fps.fps_count + 5) / 10;
|
||||
fps.index = 0;
|
||||
}
|
||||
fps.fps_count = (10000 * MAX_FPS_HIST / total);
|
||||
fps.fps_count = (fps.fps_count + 5) / 10;
|
||||
fps.index = 0;
|
||||
}
|
||||
|
||||
// Draw it at the top-right corner of the screen:
|
||||
// Draw it at the top-right corner of the screen:
|
||||
PS2_DrawFill(viddef.width - 65, 3, viddef.width - 10, 15, 0); // A black bg to give the text more contrast.
|
||||
PS2_DrawString(viddef.width - 60, 6, va("FPS %u", fps.fps_count));
|
||||
PS2_DrawString(viddef.width - 60, 6, va("FPS %u", fps.fps_count));
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
PS2_DrawMemTags
|
||||
================
|
||||
*/
|
||||
static void PS2_DrawMemTags(void)
|
||||
{
|
||||
int i;
|
||||
int y = 35;
|
||||
u32 total = 0;
|
||||
|
||||
for (i = 0; i < MEMTAG_COUNT; ++i)
|
||||
{
|
||||
total += ps2_mem_tag_counts[i];
|
||||
|
||||
const char * count_str = PS2_FormatMemoryUnit(ps2_mem_tag_counts[i], true);
|
||||
const char * formatted_str = va("%-10s %s", ps2_mem_tag_names[i], count_str);
|
||||
|
||||
PS2_DrawString(viddef.width - 170, y, formatted_str);
|
||||
y += 12;
|
||||
}
|
||||
|
||||
// Total memory currently allocated (approximately):
|
||||
PS2_DrawString(viddef.width - 170, y + 6, va("TOTAL: %s", PS2_FormatMemoryUnit(total, true)));
|
||||
|
||||
// A darker background to give the text more contrast.
|
||||
PS2_DrawFill(viddef.width - 180, 30, viddef.width - 10, 85, 2);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
@@ -754,7 +752,8 @@ qboolean PS2_RendererInit(void * unused1, void * unused2)
|
||||
r_ps2_vid_height = Cvar_Get("r_ps2_vid_height", va("%d", DEFAULT_VID_HEIGHT), 0);
|
||||
r_ps2_ui_brightness = Cvar_Get("r_ps2_ui_brightness", "128", 0);
|
||||
r_ps2_fade_scr_alpha = Cvar_Get("r_ps2_fade_scr_alpha", "100", 0);
|
||||
r_ps2_show_fps = Cvar_Get("r_ps2_show_fps", "1", 0);
|
||||
r_ps2_show_fps = Cvar_Get("r_ps2_show_fps", "1", 0);
|
||||
r_ps2_show_mem_tags = Cvar_Get("r_ps2_show_mem_tags", "1", 0);
|
||||
|
||||
// Cache these, since on the PS2 we don't have a way of interacting with the console.
|
||||
viddef.width = (int)r_ps2_vid_width->value;
|
||||
@@ -762,6 +761,7 @@ qboolean PS2_RendererInit(void * unused1, void * unused2)
|
||||
ps2ref.ui_brightness = (u32)r_ps2_ui_brightness->value;
|
||||
ps2ref.fade_scr_alpha = (u32)r_ps2_fade_scr_alpha->value;
|
||||
ps2ref.show_fps_count = (qboolean)r_ps2_show_fps->value;
|
||||
ps2ref.show_mem_tags = (qboolean)r_ps2_show_mem_tags->value;
|
||||
|
||||
// Renderer id. Used in a couple places by the game.
|
||||
vidref_val = VIDREF_OTHER;
|
||||
@@ -803,7 +803,7 @@ qboolean PS2_RendererInit(void * unused1, void * unused2)
|
||||
|
||||
// Plus the five packet_ts just allocated above.
|
||||
renderer_packet_mem += sizeof(packet_t) * 5;
|
||||
PS2_AddRenderPacketMem(renderer_packet_mem);
|
||||
ps2_mem_tag_counts[MEMTAG_RENDERER] += renderer_packet_mem;
|
||||
|
||||
// Reset these, to be sure...
|
||||
ps2ref.current_frame_packet = NULL;
|
||||
@@ -811,7 +811,7 @@ qboolean PS2_RendererInit(void * unused1, void * unused2)
|
||||
ps2ref.dmatag_draw2d = NULL;
|
||||
ps2ref.current_tex = NULL;
|
||||
ps2ref.frame_index = 0;
|
||||
memset(&fps, 0, sizeof(fps));
|
||||
memset(&fps, 0, sizeof(fps));
|
||||
|
||||
// Init other aux data and default render states:
|
||||
ps2ref.prim_desc.type = PRIM_TRIANGLE;
|
||||
@@ -929,9 +929,9 @@ PS2_RegisterModel
|
||||
*/
|
||||
struct model_s * PS2_RegisterModel(const char * name)
|
||||
{
|
||||
Com_DPrintf("PS2_RegisterModel: '%s'\n", name);
|
||||
//TODO
|
||||
return NULL;
|
||||
static int dummy1;
|
||||
return (struct model_s *)&dummy1;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -941,9 +941,7 @@ PS2_RegisterSkin
|
||||
*/
|
||||
struct image_s * PS2_RegisterSkin(const char * name)
|
||||
{
|
||||
Com_DPrintf("PS2_RegisterSkin: '%s'\n", name);
|
||||
//TODO
|
||||
return NULL;
|
||||
return (struct image_s *)PS2_TexImageFindOrLoad(name, IT_SKIN);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -953,9 +951,7 @@ PS2_RegisterPic
|
||||
*/
|
||||
struct image_s * PS2_RegisterPic(const char * name)
|
||||
{
|
||||
Com_DPrintf("PS2_RegisterPic: '%s'\n", name);
|
||||
//TODO
|
||||
return NULL;
|
||||
return (struct image_s *)PS2_TexImageFindOrLoad(name, IT_PIC | IT_BUILTIN);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -967,6 +963,10 @@ void PS2_SetSky(const char * name, float rotate, vec3_t axis)
|
||||
{
|
||||
Com_DPrintf("PS2_SetSky: '%s'\n", name);
|
||||
//TODO
|
||||
//
|
||||
// Looking at ref_gl, it seems that the renderer can decide
|
||||
// between using TGA or PCX for the skyboxes. TGA should be
|
||||
// a good choice for the PS2.
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1021,15 +1021,26 @@ void PS2_EndFrame(void)
|
||||
Sys_Error("EndFrame: Inconsistent frame states!!!");
|
||||
}
|
||||
|
||||
//
|
||||
// Finalize pending 2D draws.
|
||||
//
|
||||
// All of our 2D drawings are now batched, so we concentrate
|
||||
// All of our 2D drawings are batched, so we concentrate
|
||||
// 2D draw call here to ensure only one texture switch per
|
||||
// image being used by the 2D elements.
|
||||
//
|
||||
PS2_Draw2DBegin();
|
||||
PS2_DrawFullScreenCinematic();
|
||||
PS2_DrawFPSCounter();
|
||||
|
||||
// Extra debug overlays:
|
||||
if (ps2ref.show_fps_count)
|
||||
{
|
||||
PS2_DrawFPSCounter();
|
||||
}
|
||||
if (ps2ref.show_mem_tags)
|
||||
{
|
||||
PS2_DrawMemTags();
|
||||
}
|
||||
|
||||
PS2_Flush2DBatch();
|
||||
PS2_Draw2DEnd();
|
||||
|
||||
@@ -1078,12 +1089,13 @@ PS2_RenderFrame
|
||||
void PS2_RenderFrame(refdef_t * view_def)
|
||||
{
|
||||
CHECK_FRAME_STARTED();
|
||||
//
|
||||
// Quake2 default render mode was 2D, only switching to 3D in here
|
||||
// (probably in account of the software renderer).
|
||||
//
|
||||
|
||||
//
|
||||
// Quake2 default render mode was 2D, only switching to 3D in here.
|
||||
// So RenderFrame always "restores" 2D when done.
|
||||
//
|
||||
Sys_Error("Not ready yet!");//TODO
|
||||
(void)view_def;
|
||||
//TODO
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1279,7 +1291,7 @@ void PS2_DrawChar(int x, int y, int c)
|
||||
row = (c >> 4) * GLYPH_SIZE;
|
||||
col = (c & 15) * GLYPH_SIZE;
|
||||
|
||||
ps2_2d_quad_t * quad = DRAW2D_NEXT_BATCH_ELEMENT();
|
||||
screen_quad_t * quad = DRAW2D_NEXT_BATCH_ELEMENT();
|
||||
|
||||
quad->z_index = DRAW2D_NEXT_Z_INDEX();
|
||||
quad->tex_index = TEXIMAGE_INDEX(builtin_tex_conchars);
|
||||
@@ -1367,7 +1379,7 @@ void PS2_DrawTileClear(int x, int y, int w, int h, const char * name)
|
||||
return;
|
||||
}
|
||||
|
||||
ps2_2d_quad_t * quad = DRAW2D_NEXT_BATCH_ELEMENT();
|
||||
screen_quad_t * quad = DRAW2D_NEXT_BATCH_ELEMENT();
|
||||
|
||||
quad->z_index = DRAW2D_NEXT_Z_INDEX();
|
||||
quad->tex_index = TEXIMAGE_INDEX(teximage);
|
||||
@@ -1406,7 +1418,7 @@ void PS2_DrawFill(int x, int y, int w, int h, int c)
|
||||
Sys_Error("PS2_DrawFill: Bad color index %d!", c);
|
||||
}
|
||||
|
||||
ps2_2d_quad_t * quad;
|
||||
screen_quad_t * quad;
|
||||
|
||||
// Full screen wipe with black (happens on pause and menus), treat it as a screen fade.
|
||||
if (c == 0 && x == 0 && y == 0 && w == viddef.width && h == viddef.height)
|
||||
@@ -1474,7 +1486,7 @@ void PS2_DrawFadeScreen(void)
|
||||
return; // Already issued one this frame!
|
||||
}
|
||||
|
||||
ps2_2d_quad_t * quad = DRAW2D_NEXT_BATCH_ELEMENT();
|
||||
screen_quad_t * quad = DRAW2D_NEXT_BATCH_ELEMENT();
|
||||
|
||||
quad->z_index = DRAW2D_NEXT_Z_INDEX();
|
||||
quad->tex_index = DRAW2D_TEX_INDEX_FADE_SCR;
|
||||
@@ -1600,7 +1612,7 @@ void PS2_DrawStretchTexImage(int x, int y, int w, int h, ps2_teximage_t * texima
|
||||
return; // No more space this frame!
|
||||
}
|
||||
|
||||
ps2_2d_quad_t * quad = DRAW2D_NEXT_BATCH_ELEMENT();
|
||||
screen_quad_t * quad = DRAW2D_NEXT_BATCH_ELEMENT();
|
||||
|
||||
quad->z_index = DRAW2D_NEXT_Z_INDEX();
|
||||
quad->tex_index = TEXIMAGE_INDEX(teximage);
|
||||
|
||||
+15
-3
@@ -76,6 +76,7 @@ typedef struct
|
||||
{
|
||||
qboolean initialized; // Flag to keep track of initialization of our global ps2ref.
|
||||
qboolean show_fps_count; // Draws a frames per sec counter in the top-right corner of the screen.
|
||||
qboolean show_mem_tags; // Draws a debug overlay with the current values of the memory tags.
|
||||
qboolean frame_started; // Set by BeginFrame, cleared at EndFrame. Some calls must be in between.
|
||||
zbuffer_t z_buffer; // PS2 depth buffer information.
|
||||
framebuffer_t frame_buffers[2]; // PS2 color framebuffers (double buffered).
|
||||
@@ -203,9 +204,6 @@ void PS2_TexImageSetup(ps2_teximage_t * teximage, const char * name, int w, int
|
||||
int func, int psm, int mag_filter, int min_filter, ps2_imagetype_t type, byte * pic);
|
||||
void PS2_TexImageFree(ps2_teximage_t * teximage);
|
||||
|
||||
// Scrap texture atlas:
|
||||
ps2_teximage_t * Scrap_AllocBlock(const byte * pic8in, int w, int h, const char * pic_name);
|
||||
|
||||
/*
|
||||
* Image loading for textures/sprites:
|
||||
*/
|
||||
@@ -214,6 +212,8 @@ qboolean PCX_LoadFromMemory(const char * filename, const byte * data, int data_l
|
||||
byte ** pic, u32 * palette, int * width, int * height);
|
||||
qboolean PCX_LoadFromFile(const char * filename, byte ** pic,
|
||||
u32 * palette, int * width, int * height);
|
||||
qboolean TGA_LoadFromFile(const char * filename, byte ** pic,
|
||||
int * width, int * height);
|
||||
|
||||
/*
|
||||
* Convert from 8bit palettized to RGB[A]:
|
||||
@@ -226,4 +226,16 @@ void Img_UnPalettize24(int width, int height, const byte * restrict pic8in, // P
|
||||
void Img_UnPalettize16(int width, int height, const byte * restrict pic8in, // Palettized 8bits to RGBA 16bits (1-5-5-5).
|
||||
const u32 * restrict palette, byte * restrict pic16out);
|
||||
|
||||
/*
|
||||
* Other image utilities:
|
||||
*/
|
||||
|
||||
// Scrap texture atlas allocation. This is based on the same atlas used by ref_gl.
|
||||
// Returns null if the atlas is full, a unique ps2_teximage_t handle referencing the atlas otherwise.
|
||||
ps2_teximage_t * Scrap_AllocBlock(const byte * pic8in, int w, int h, const char * pic_name);
|
||||
|
||||
// Resize the input RGBA image using a box filter. Output and input must point to different buffers.
|
||||
void Img_Resample32(const u32 * restrict in_img, int in_width, int in_height,
|
||||
u32 * restrict out_img, int out_width, int out_height);
|
||||
|
||||
#endif // PS2_REFRESH_H
|
||||
+13
-2
@@ -24,6 +24,13 @@
|
||||
// ref_ps2.c
|
||||
extern void PS2_RendererShutdown(void);
|
||||
|
||||
// The program code and static data will use a fair slice of
|
||||
// the main memory at all times. This is a rough estimate of that.
|
||||
enum
|
||||
{
|
||||
PROG_MEGABYTES = 2
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// System init/shutdown and misc helpers:
|
||||
@@ -77,6 +84,10 @@ void Sys_Init(void)
|
||||
|
||||
// Load the built-in IOP modules we need for the game.
|
||||
Sys_LoadIOPModules();
|
||||
|
||||
// Add our estimate of the amount of memory used to allocate
|
||||
// the program executable and all the prog data:
|
||||
ps2_mem_tag_counts[MEMTAG_MISC] += (PROG_MEGABYTES * 1024 * 1024);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -355,7 +366,7 @@ qboolean Sys_LoadBinaryFile(const char * filename, int * size_bytes, void ** dat
|
||||
fioLseek(fd, 0, SEEK_SET); // rewind
|
||||
|
||||
// Alloc or fail with a Sys_Error.
|
||||
file_data = PS2_MemAlloc(file_len, MEMTAG_FILESYS);
|
||||
file_data = PS2_MemAlloc(file_len, MEMTAG_MISC);
|
||||
|
||||
num_read = fioRead(fd, file_data, file_len);
|
||||
if (num_read != file_len)
|
||||
@@ -375,7 +386,7 @@ BAIL:
|
||||
{
|
||||
if (file_data != NULL)
|
||||
{
|
||||
PS2_MemFree(file_data, MEMTAG_FILESYS);
|
||||
PS2_MemFree(file_data, file_len, MEMTAG_MISC);
|
||||
file_data = NULL;
|
||||
}
|
||||
file_len = 0;
|
||||
|
||||
+646
-23
@@ -182,17 +182,265 @@ ps2_teximage_t * PS2_TexImageAlloc(void)
|
||||
}
|
||||
|
||||
//TODO assume always sequential, or allow empty gaps???
|
||||
// -- should also look into the registration_sequence trick used by ref_gl
|
||||
return &ps2ref.teximages[ps2ref.num_teximages++];
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
Img_NameHash
|
||||
Local helpers:
|
||||
- IsPowerOfTwo
|
||||
- RoundToPowerOfTwo
|
||||
==============
|
||||
*/
|
||||
|
||||
static inline int IsPowerOfTwo(int x)
|
||||
{
|
||||
return (x > 0) && (x & (x - 1)) == 0;
|
||||
}
|
||||
|
||||
static inline int RoundToPowerOfTwo(int x)
|
||||
{
|
||||
if (IsPowerOfTwo(x))
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
// Round nearest:
|
||||
int k;
|
||||
for (k = sizeof(int) * 8 - 1; ((1 << k) & x) == 0; --k)
|
||||
{
|
||||
}
|
||||
|
||||
if (((1 << (k - 1)) & x) == 0)
|
||||
{
|
||||
return 1 << k;
|
||||
}
|
||||
|
||||
int pot = 1 << (k + 1);
|
||||
return (pot < MAX_TEXIMAGE_SIZE) ? pot : MAX_TEXIMAGE_SIZE;
|
||||
|
||||
// Round down:
|
||||
/*
|
||||
int p2;
|
||||
for (p2 = 1; (p2 * 2) <= x; p2 <<= 1) { }
|
||||
return (p2 < MAX_TEXIMAGE_SIZE) ? p2 : MAX_TEXIMAGE_SIZE;
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
PS2_Common8BitTexSetup
|
||||
==============
|
||||
*/
|
||||
static ps2_teximage_t * PS2_Common8BitTexSetup(const byte * pic8, int width, int height, const char * name, int flags)
|
||||
{
|
||||
byte * expanded_pic;
|
||||
byte * scaled_pic;
|
||||
ps2_teximage_t * teximage;
|
||||
|
||||
int psm = GS_PSM_16;
|
||||
int format = TEXTURE_COMPONENTS_RGB;
|
||||
int mag_filter = LOD_MAG_LINEAR;
|
||||
int min_filter = LOD_MIN_LINEAR;
|
||||
|
||||
// Clamp down to our size limit or round to PoT. This will also force RGBA32.
|
||||
if (width > MAX_TEXIMAGE_SIZE ||
|
||||
height > MAX_TEXIMAGE_SIZE ||
|
||||
!IsPowerOfTwo(width) ||
|
||||
!IsPowerOfTwo(height))
|
||||
{
|
||||
psm = GS_PSM_32;
|
||||
format = TEXTURE_COMPONENTS_RGBA;
|
||||
|
||||
const int scaled_width = (width >= MAX_TEXIMAGE_SIZE) ? MAX_TEXIMAGE_SIZE : RoundToPowerOfTwo(width);
|
||||
const int scaled_height = (height >= MAX_TEXIMAGE_SIZE) ? MAX_TEXIMAGE_SIZE : RoundToPowerOfTwo(height);
|
||||
|
||||
expanded_pic = PS2_MemAlloc(width * height * 4, MEMTAG_TEXIMAGE);
|
||||
scaled_pic = PS2_MemAlloc(scaled_width * scaled_height * 4, MEMTAG_TEXIMAGE);
|
||||
|
||||
Img_UnPalettize32(width, height, pic8, global_palette, expanded_pic);
|
||||
Img_Resample32((u32 *)expanded_pic, width, height, (u32 *)scaled_pic, scaled_width, scaled_height);
|
||||
|
||||
PS2_MemFree(expanded_pic, (width * height * 4), MEMTAG_TEXIMAGE);
|
||||
|
||||
width = scaled_width;
|
||||
height = scaled_height;
|
||||
expanded_pic = scaled_pic;
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
const int pixel_count = width * height;
|
||||
|
||||
// Check if the image has transparency, if so, we need 32bit color.
|
||||
for (i = 0; i < pixel_count; ++i)
|
||||
{
|
||||
if (pic8[i] == 255) // Transparent color
|
||||
{
|
||||
// Need 32bit RGBA.
|
||||
psm = GS_PSM_32;
|
||||
format = TEXTURE_COMPONENTS_RGBA;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (format == TEXTURE_COMPONENTS_RGBA)
|
||||
{
|
||||
expanded_pic = PS2_MemAlloc(width * height * 4, MEMTAG_TEXIMAGE);
|
||||
Img_UnPalettize32(width, height, pic8, global_palette, expanded_pic);
|
||||
}
|
||||
else // Use more compact 16bit RGB color.
|
||||
{
|
||||
expanded_pic = PS2_MemAlloc(width * height * 2, MEMTAG_TEXIMAGE);
|
||||
Img_UnPalettize16(width, height, pic8, global_palette, expanded_pic);
|
||||
}
|
||||
}
|
||||
|
||||
// IT_BUILTIN is only used internally as a type.
|
||||
// Can't be present if loaded from file, so mask it off.
|
||||
const int img_type = flags & (~IT_BUILTIN);
|
||||
|
||||
// Sprites can do with a cheaper filtering.
|
||||
// Pics (2D UI elements and such) actually look better with nearest sampling.
|
||||
if (img_type & (IT_PIC | IT_SPRITE))
|
||||
{
|
||||
mag_filter = LOD_MAG_NEAREST;
|
||||
min_filter = LOD_MIN_NEAREST;
|
||||
}
|
||||
|
||||
// Finally, allocate and set up the image handle:
|
||||
teximage = PS2_TexImageAlloc();
|
||||
PS2_TexImageSetup(teximage, name, width, height, format, TEXTURE_FUNCTION_MODULATE,
|
||||
psm, mag_filter, min_filter, (ps2_imagetype_t)img_type, expanded_pic);
|
||||
|
||||
return teximage;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
PS2_LoadPcxImpl
|
||||
==============
|
||||
*/
|
||||
static ps2_teximage_t * PS2_LoadPcxImpl(const char * name, int flags)
|
||||
{
|
||||
int width;
|
||||
int height;
|
||||
byte * pic8;
|
||||
ps2_teximage_t * teximage = NULL;
|
||||
|
||||
if (!PCX_LoadFromFile(name, &pic8, NULL, &width, &height))
|
||||
{
|
||||
Com_DPrintf("WARNING: Can't load PCX pic for '%s'\n", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Try placing small images in the scrap atlas:
|
||||
if ((flags & IT_PIC) && width <= 64 && height <= 166)
|
||||
{
|
||||
// Notice that we allow some pretty tall images (h <= 166).
|
||||
// That's the size of m_main_plaque, the Quake2 logo on
|
||||
// the main menu. This image was impossible to resize in
|
||||
// a descent way on allocation, so I've change the atlas
|
||||
// allocation criteria here to allow it's height, so it
|
||||
// will not be a standalone image and won't require a resize.
|
||||
teximage = Scrap_AllocBlock(pic8, width, height, name);
|
||||
}
|
||||
|
||||
// Atlas full or image too big, create a standalone texture:
|
||||
if (teximage == NULL)
|
||||
{
|
||||
teximage = PS2_Common8BitTexSetup(pic8, width, height, name, flags);
|
||||
}
|
||||
|
||||
// The palettized image is no longer needed.
|
||||
PS2_MemFree(pic8, width * height, MEMTAG_TEXIMAGE);
|
||||
return teximage;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
PS2_LoadWalImpl
|
||||
==============
|
||||
*/
|
||||
static ps2_teximage_t * PS2_LoadWalImpl(const char * name, int flags)
|
||||
{
|
||||
ps2_teximage_t * teximage;
|
||||
const miptex_t * wall;
|
||||
const byte * pic8;
|
||||
int width;
|
||||
int height;
|
||||
int offset;
|
||||
int data_len;
|
||||
|
||||
data_len = FS_LoadFile(name, (void **)&wall);
|
||||
if (wall == NULL || data_len <= 0)
|
||||
{
|
||||
Com_DPrintf("WARNING: Can't load WAL texture for '%s'\n", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
width = LittleLong(wall->width);
|
||||
height = LittleLong(wall->height);
|
||||
offset = LittleLong(wall->offsets[0]);
|
||||
pic8 = (const byte *)wall + offset;
|
||||
|
||||
teximage = PS2_Common8BitTexSetup(pic8, width, height, name, flags | IT_WALL);
|
||||
|
||||
FS_FreeFile((void *)wall);
|
||||
return teximage;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
PS2_LoadTgaImpl
|
||||
==============
|
||||
*/
|
||||
static ps2_teximage_t * PS2_LoadTgaImpl(const char * name, int flags)
|
||||
{
|
||||
byte * pic32;
|
||||
int width;
|
||||
int height;
|
||||
|
||||
if (!TGA_LoadFromFile(name, &pic32, &width, &height))
|
||||
{
|
||||
Com_DPrintf("WARNING: Can't load TGA texture for '%s'\n", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// IT_BUILTIN is only used internally as a type.
|
||||
// Can't be present if loaded from file, so mask it off.
|
||||
const int img_type = flags & (~IT_BUILTIN);
|
||||
|
||||
// TGA defaults:
|
||||
const int psm = GS_PSM_32;
|
||||
const int format = TEXTURE_COMPONENTS_RGBA;
|
||||
const int mag_filter = LOD_MAG_LINEAR;
|
||||
const int min_filter = LOD_MIN_LINEAR;
|
||||
|
||||
//
|
||||
// TGAs are always expanded to RGBA, so no extra conversion is needed.
|
||||
//
|
||||
// NOTE: We assume TGAs will always be under the maximum texture size (256^2).
|
||||
// This should be true, since TGAs are only used for the skyboxes in Quake2.
|
||||
// If that assumption is violated, you'll get a Sys_Error in the image setup.
|
||||
//
|
||||
ps2_teximage_t * teximage = PS2_TexImageAlloc();
|
||||
PS2_TexImageSetup(teximage, name, width, height, format, TEXTURE_FUNCTION_MODULATE,
|
||||
psm, mag_filter, min_filter, (ps2_imagetype_t)img_type, pic32);
|
||||
|
||||
return teximage;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
PS2_ImageNameHash
|
||||
|
||||
OAT - One-At-a-Time hash of the filename of an image.
|
||||
https://en.wikipedia.org/wiki/Jenkins_hash_function
|
||||
==============
|
||||
*/
|
||||
static inline u32 Img_NameHash(const char * name)
|
||||
static inline u32 PS2_ImageNameHash(const char * name)
|
||||
{
|
||||
u32 hash = 0;
|
||||
|
||||
@@ -212,28 +460,30 @@ static inline u32 Img_NameHash(const char * name)
|
||||
|
||||
/*
|
||||
==============
|
||||
Img_FindImpl
|
||||
PS2_FindImageImpl
|
||||
==============
|
||||
*/
|
||||
static ps2_teximage_t * Img_FindImpl(const char * name, int flags)
|
||||
static ps2_teximage_t * PS2_FindImageImpl(const char * name, int flags)
|
||||
{
|
||||
if (name == NULL)
|
||||
{
|
||||
Com_DPrintf("FindImage: Null name!");
|
||||
Com_DPrintf("PS2_FindImageImpl: Null name!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const u32 name_len = strlen(name);
|
||||
if (name_len < 5)
|
||||
if (name_len < 5 || name_len >= MAX_QPATH)
|
||||
{
|
||||
Com_DPrintf("FindImage: Bad name, too short: %s", name);
|
||||
Com_DPrintf("PS2_FindImageImpl: Bad image name: '%s'\n", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Compare by hash code, much cheaper.
|
||||
const u32 name_hash = Img_NameHash(name);
|
||||
const u32 name_hash = PS2_ImageNameHash(name);
|
||||
|
||||
//
|
||||
// First, lookup our cache:
|
||||
//
|
||||
u32 i;
|
||||
const u32 num_teximages = ps2ref.num_teximages;
|
||||
ps2_teximage_t * teximages = ps2ref.teximages;
|
||||
@@ -246,7 +496,25 @@ static ps2_teximage_t * Img_FindImpl(const char * name, int flags)
|
||||
}
|
||||
}
|
||||
|
||||
//TODO load form file
|
||||
//
|
||||
// Load from file for the first time:
|
||||
//
|
||||
if (strcmp(name + name_len - 4, ".pcx") == 0)
|
||||
{
|
||||
return PS2_LoadPcxImpl(name, flags);
|
||||
}
|
||||
|
||||
if (strcmp(name + name_len - 4, ".wal") == 0)
|
||||
{
|
||||
return PS2_LoadWalImpl(name, flags);
|
||||
}
|
||||
|
||||
if (strcmp(name + name_len - 4, ".tga") == 0)
|
||||
{
|
||||
return PS2_LoadTgaImpl(name, flags);
|
||||
}
|
||||
|
||||
Com_DPrintf("WARNING: Unable to find image '%s'\n", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -260,17 +528,25 @@ ps2_teximage_t * PS2_TexImageFindOrLoad(const char * name, int flags)
|
||||
ps2_teximage_t * teximage;
|
||||
char fullname[MAX_QPATH];
|
||||
|
||||
// This is the same logic used by ref_gl.
|
||||
// If the name doesn't start with a path separator, its just the base
|
||||
// filename, like "conchars", otherwise the full file path is specified in 'name'.
|
||||
if (name[0] != '/' && name[0] != '\\')
|
||||
if (flags & (IT_PIC | IT_BUILTIN))
|
||||
{
|
||||
Com_sprintf(fullname, sizeof(fullname), "pics/%s.pcx", name);
|
||||
teximage = Img_FindImpl(fullname, flags);
|
||||
// This is the same logic used by ref_gl.
|
||||
// If the name doesn't start with a path separator, its just the base
|
||||
// filename, like "conchars", otherwise the full file path is specified in 'name'.
|
||||
if (name[0] != '/' && name[0] != '\\')
|
||||
{
|
||||
Com_sprintf(fullname, sizeof(fullname), "pics/%s.pcx", name);
|
||||
teximage = PS2_FindImageImpl(fullname, flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
teximage = PS2_FindImageImpl(name + 1, flags);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
teximage = Img_FindImpl(name + 1, flags);
|
||||
// Skins, walls, etc.
|
||||
teximage = PS2_FindImageImpl(name, flags);
|
||||
}
|
||||
|
||||
return teximage;
|
||||
@@ -318,7 +594,7 @@ void PS2_TexImageSetup(ps2_teximage_t * teximage, const char * name, int w, int
|
||||
|
||||
// Finally, copy and hash the name string:
|
||||
strncpy(teximage->name, name, MAX_QPATH);
|
||||
teximage->hash = Img_NameHash(name);
|
||||
teximage->hash = PS2_ImageNameHash(name);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -331,12 +607,88 @@ void PS2_TexImageFree(ps2_teximage_t * teximage)
|
||||
// Built-ins will always be referencing static program data.
|
||||
if (teximage->pic != NULL && teximage->type != IT_BUILTIN)
|
||||
{
|
||||
PS2_MemFree(teximage->pic, MEMTAG_TEXIMAGE);
|
||||
int size_bytes;
|
||||
switch (teximage->texbuf.psm)
|
||||
{
|
||||
case GS_PSM_32 :
|
||||
size_bytes = (teximage->width * teximage->height * 4);
|
||||
break;
|
||||
case GS_PSM_16 :
|
||||
size_bytes = (teximage->width * teximage->height * 2);
|
||||
break;
|
||||
default : // Assume 8bits palettized.
|
||||
size_bytes = (teximage->width * teximage->height * 1);
|
||||
break;
|
||||
} // switch (teximage->texbuf.psm)
|
||||
|
||||
PS2_MemFree(teximage->pic, size_bytes, MEMTAG_TEXIMAGE);
|
||||
}
|
||||
|
||||
PS2_MemClearObj(teximage);
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
Img_Resample32
|
||||
|
||||
Adapted from ref_gl GL_ResampleTexture.
|
||||
NOTE: Input and out images must be different buffers!
|
||||
==============
|
||||
*/
|
||||
void Img_Resample32(const u32 * restrict in_img, int in_width, int in_height,
|
||||
u32 * restrict out_img, int out_width, int out_height)
|
||||
{
|
||||
int i, j;
|
||||
u32 frac;
|
||||
const u32 * inrow;
|
||||
const u32 * inrow2;
|
||||
const byte * pix1;
|
||||
const byte * pix2;
|
||||
const byte * pix3;
|
||||
const byte * pix4;
|
||||
|
||||
// 512 is the max output w|h. We only really use up to 256 (MAX_TEXIMAGE_SIZE).
|
||||
u32 p1[512] __attribute__((aligned(16)));
|
||||
u32 p2[512] __attribute__((aligned(16)));
|
||||
|
||||
const u32 fracstep = in_width * 0x10000 / out_width;
|
||||
|
||||
frac = fracstep >> 2;
|
||||
for (i = 0; i < out_width; i++)
|
||||
{
|
||||
p1[i] = 4 * (frac >> 16);
|
||||
frac += fracstep;
|
||||
}
|
||||
|
||||
frac = 3 * (fracstep >> 2);
|
||||
for (i = 0; i < out_width; i++)
|
||||
{
|
||||
p2[i] = 4 * (frac >> 16);
|
||||
frac += fracstep;
|
||||
}
|
||||
|
||||
// This is a box filter, I think...
|
||||
for (i = 0; i < out_height; i++, out_img += out_width)
|
||||
{
|
||||
inrow = in_img + in_width * (int)((i + 0.25) * in_height / out_height);
|
||||
inrow2 = in_img + in_width * (int)((i + 0.75) * in_height / out_height);
|
||||
frac = fracstep >> 1;
|
||||
|
||||
for (j = 0; j < out_width; j++)
|
||||
{
|
||||
pix1 = (const byte *)inrow + p1[j];
|
||||
pix2 = (const byte *)inrow + p2[j];
|
||||
pix3 = (const byte *)inrow2 + p1[j];
|
||||
pix4 = (const byte *)inrow2 + p2[j];
|
||||
|
||||
((byte *)(out_img + j))[0] = (pix1[0] + pix2[0] + pix3[0] + pix4[0]) >> 2;
|
||||
((byte *)(out_img + j))[1] = (pix1[1] + pix2[1] + pix3[1] + pix4[1]) >> 2;
|
||||
((byte *)(out_img + j))[2] = (pix1[2] + pix2[2] + pix3[2] + pix4[2]) >> 2;
|
||||
((byte *)(out_img + j))[3] = (pix1[3] + pix2[3] + pix3[3] + pix4[3]) >> 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// Scrap allocation - AKA texture atlas
|
||||
@@ -435,6 +787,7 @@ ps2_teximage_t * Scrap_AllocBlock(const byte * pic8in, int w, int h, const char
|
||||
/*
|
||||
==============
|
||||
PCX_LoadFromMemory
|
||||
|
||||
'pic' and 'palette' can be null if you want to ignore one or the other.
|
||||
If 'palette' is not null, it must point to an array of 256 32bit integers.
|
||||
Mostly adapted from ref_gl/gl_image.c
|
||||
@@ -466,7 +819,7 @@ qboolean PCX_LoadFromMemory(const char * filename, const byte * data, int data_l
|
||||
if (manufacturer != 0x0A || version != 5 || encoding != 1 ||
|
||||
bits_per_pixel != 8 || xmax >= 640 || ymax >= 480)
|
||||
{
|
||||
Sys_Error("Bad PCX file %s. Invalid header value(s)!", filename);
|
||||
Com_DPrintf("Bad PCX file %s. Invalid header value(s)!\n", filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -537,9 +890,12 @@ qboolean PCX_LoadFromMemory(const char * filename, const byte * data, int data_l
|
||||
|
||||
if ((data - (const byte *)pcx) > data_len)
|
||||
{
|
||||
Sys_Error("PCX image %s was malformed!", filename);
|
||||
PS2_MemFree(*pic, MEMTAG_TEXIMAGE);
|
||||
Com_DPrintf("PCX image %s was malformed!\n", filename);
|
||||
|
||||
int size_bytes = (xmax + 1) * (ymax + 1);
|
||||
PS2_MemFree(*pic, size_bytes, MEMTAG_TEXIMAGE);
|
||||
*pic = NULL;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -549,6 +905,7 @@ qboolean PCX_LoadFromMemory(const char * filename, const byte * data, int data_l
|
||||
/*
|
||||
==============
|
||||
PCX_LoadFromFile
|
||||
|
||||
Mostly adapted from ref_gl/gl_image.c
|
||||
==============
|
||||
*/
|
||||
@@ -562,7 +919,7 @@ qboolean PCX_LoadFromFile(const char * filename, byte ** pic,
|
||||
data_len = FS_LoadFile(filename, (void **)&data);
|
||||
if (data == NULL || data_len <= 0)
|
||||
{
|
||||
Sys_Error("Bad PCX file %s", filename);
|
||||
Com_DPrintf("Bad PCX file '%s'\n", filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -572,6 +929,271 @@ qboolean PCX_LoadFromFile(const char * filename, byte ** pic,
|
||||
return result;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// TGA image loading helpers:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
typedef struct
|
||||
{
|
||||
byte id_length;
|
||||
byte colormap_type;
|
||||
byte image_type;
|
||||
u16 colormap_index;
|
||||
u16 colormap_length;
|
||||
byte colormap_size;
|
||||
u16 x_origin;
|
||||
u16 y_origin;
|
||||
u16 width;
|
||||
u16 height;
|
||||
byte pixel_size;
|
||||
byte attributes;
|
||||
} tga_header_t;
|
||||
|
||||
/*
|
||||
==============
|
||||
TGA_LoadFromFile
|
||||
|
||||
Mostly adapted from LoadTGA, ref_gl/gl_image.c
|
||||
NOTE: Output image is always RGBA 32bits.
|
||||
==============
|
||||
*/
|
||||
qboolean TGA_LoadFromFile(const char * filename, byte ** pic, int * width, int * height)
|
||||
{
|
||||
tga_header_t targa_header;
|
||||
|
||||
int data_len;
|
||||
int pixel_count;
|
||||
int column, columns;
|
||||
int row, rows;
|
||||
|
||||
byte * pixbuf;
|
||||
byte * buf_p;
|
||||
byte * buffer;
|
||||
byte * targa_rgba;
|
||||
byte tmp[2];
|
||||
|
||||
*pic = NULL;
|
||||
|
||||
data_len = FS_LoadFile(filename, (void **)&buffer);
|
||||
if (buffer == NULL || data_len <= 0)
|
||||
{
|
||||
Com_DPrintf("Bad TGA file '%s'\n", filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
buf_p = buffer;
|
||||
targa_header.id_length = *buf_p++;
|
||||
targa_header.colormap_type = *buf_p++;
|
||||
targa_header.image_type = *buf_p++;
|
||||
|
||||
tmp[0] = buf_p[0];
|
||||
tmp[1] = buf_p[1];
|
||||
targa_header.colormap_index = LittleShort(*((short *)tmp));
|
||||
buf_p += 2;
|
||||
|
||||
tmp[0] = buf_p[0];
|
||||
tmp[1] = buf_p[1];
|
||||
targa_header.colormap_length = LittleShort(*((short *)tmp));
|
||||
buf_p += 2;
|
||||
|
||||
targa_header.colormap_size = *buf_p++;
|
||||
|
||||
targa_header.x_origin = LittleShort(*((short *)buf_p));
|
||||
buf_p += 2;
|
||||
|
||||
targa_header.y_origin = LittleShort(*((short *)buf_p));
|
||||
buf_p += 2;
|
||||
|
||||
targa_header.width = LittleShort(*((short *)buf_p));
|
||||
buf_p += 2;
|
||||
|
||||
targa_header.height = LittleShort(*((short *)buf_p));
|
||||
buf_p += 2;
|
||||
|
||||
targa_header.pixel_size = *buf_p++;
|
||||
targa_header.attributes = *buf_p++;
|
||||
|
||||
if (targa_header.image_type != 2 && targa_header.image_type != 10)
|
||||
{
|
||||
Com_DPrintf("TGA_LoadFromFile: Only type 2 and 10 targa RGB images supported! %s\n", filename);
|
||||
FS_FreeFile(buffer);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (targa_header.colormap_type != 0 || (targa_header.pixel_size != 32 && targa_header.pixel_size != 24))
|
||||
{
|
||||
Com_DPrintf("TGA_LoadFromFile: Only 32 or 24 bit images supported (no colormaps)! %s\n", filename);
|
||||
FS_FreeFile(buffer);
|
||||
return false;
|
||||
}
|
||||
|
||||
columns = targa_header.width;
|
||||
rows = targa_header.height;
|
||||
pixel_count = columns * rows;
|
||||
|
||||
if (width != NULL)
|
||||
{
|
||||
*width = columns;
|
||||
}
|
||||
if (height != NULL)
|
||||
{
|
||||
*height = rows;
|
||||
}
|
||||
|
||||
targa_rgba = PS2_MemAlloc(pixel_count * 4, MEMTAG_TEXIMAGE);
|
||||
*pic = targa_rgba;
|
||||
|
||||
if (targa_header.id_length != 0)
|
||||
{
|
||||
buf_p += targa_header.id_length; // skip TARGA image comment
|
||||
}
|
||||
|
||||
if (targa_header.image_type == 2) // Uncompressed, RGB images
|
||||
{
|
||||
for (row = rows - 1; row >= 0; --row)
|
||||
{
|
||||
pixbuf = targa_rgba + row * columns * 4;
|
||||
for (column = 0; column < columns; ++column)
|
||||
{
|
||||
byte red, green, blue, alpha;
|
||||
|
||||
switch (targa_header.pixel_size)
|
||||
{
|
||||
case 24 :
|
||||
blue = *buf_p++;
|
||||
green = *buf_p++;
|
||||
red = *buf_p++;
|
||||
*pixbuf++ = red;
|
||||
*pixbuf++ = green;
|
||||
*pixbuf++ = blue;
|
||||
*pixbuf++ = 255;
|
||||
break;
|
||||
|
||||
case 32 :
|
||||
blue = *buf_p++;
|
||||
green = *buf_p++;
|
||||
red = *buf_p++;
|
||||
alpha = *buf_p++;
|
||||
*pixbuf++ = red;
|
||||
*pixbuf++ = green;
|
||||
*pixbuf++ = blue;
|
||||
*pixbuf++ = alpha;
|
||||
break;
|
||||
} // switch
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (targa_header.image_type == 10) // Run-length encoded RGB images
|
||||
{
|
||||
byte red, green, blue, alpha;
|
||||
byte packetHeader, packetSize, j;
|
||||
|
||||
for (row = rows - 1; row >= 0; --row)
|
||||
{
|
||||
pixbuf = targa_rgba + row * columns * 4;
|
||||
for (column = 0; column < columns;)
|
||||
{
|
||||
packetHeader = *buf_p++;
|
||||
packetSize = 1 + (packetHeader & 0x7F);
|
||||
|
||||
if (packetHeader & 0x80) // Run-length packet
|
||||
{
|
||||
switch (targa_header.pixel_size)
|
||||
{
|
||||
case 24 :
|
||||
blue = *buf_p++;
|
||||
green = *buf_p++;
|
||||
red = *buf_p++;
|
||||
alpha = 255;
|
||||
break;
|
||||
|
||||
case 32 :
|
||||
blue = *buf_p++;
|
||||
green = *buf_p++;
|
||||
red = *buf_p++;
|
||||
alpha = *buf_p++;
|
||||
break;
|
||||
} // switch
|
||||
|
||||
for (j = 0; j < packetSize; ++j)
|
||||
{
|
||||
*pixbuf++ = red;
|
||||
*pixbuf++ = green;
|
||||
*pixbuf++ = blue;
|
||||
*pixbuf++ = alpha;
|
||||
|
||||
++column;
|
||||
if (column == columns) // run spans across rows
|
||||
{
|
||||
column = 0;
|
||||
if (row > 0)
|
||||
{
|
||||
--row;
|
||||
}
|
||||
else
|
||||
{
|
||||
goto BREAKOUT;
|
||||
}
|
||||
pixbuf = targa_rgba + row * columns * 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
else // Non run-length packet
|
||||
{
|
||||
for (j = 0; j < packetSize; ++j)
|
||||
{
|
||||
switch (targa_header.pixel_size)
|
||||
{
|
||||
case 24 :
|
||||
blue = *buf_p++;
|
||||
green = *buf_p++;
|
||||
red = *buf_p++;
|
||||
*pixbuf++ = red;
|
||||
*pixbuf++ = green;
|
||||
*pixbuf++ = blue;
|
||||
*pixbuf++ = 255;
|
||||
break;
|
||||
|
||||
case 32 :
|
||||
blue = *buf_p++;
|
||||
green = *buf_p++;
|
||||
red = *buf_p++;
|
||||
alpha = *buf_p++;
|
||||
*pixbuf++ = red;
|
||||
*pixbuf++ = green;
|
||||
*pixbuf++ = blue;
|
||||
*pixbuf++ = alpha;
|
||||
break;
|
||||
} // switch
|
||||
|
||||
++column;
|
||||
if (column == columns) // pixel packet run spans across rows
|
||||
{
|
||||
column = 0;
|
||||
if (row > 0)
|
||||
{
|
||||
--row;
|
||||
}
|
||||
else
|
||||
{
|
||||
goto BREAKOUT;
|
||||
}
|
||||
pixbuf = targa_rgba + row * columns * 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
BREAKOUT:
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
FS_FreeFile(buffer);
|
||||
return true;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// Palettized image expansion:
|
||||
@@ -581,7 +1203,8 @@ qboolean PCX_LoadFromFile(const char * filename, byte ** pic,
|
||||
/*
|
||||
==============
|
||||
Img_UnPalettize32
|
||||
Base algorithm adapted from GL_Upload8 in ref_gl/gl_image.c
|
||||
|
||||
Transparency algorithm adapted from GL_Upload8 in ref_gl/gl_image.c
|
||||
==============
|
||||
*/
|
||||
void Img_UnPalettize32(int width, int height, const byte * restrict pic8in,
|
||||
|
||||
+6
-1
@@ -29,6 +29,8 @@ VID_MenuInit
|
||||
*/
|
||||
void VID_MenuInit(void)
|
||||
{
|
||||
// TODO
|
||||
// Video config menu for Quake2.
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -38,6 +40,8 @@ VID_MenuDraw
|
||||
*/
|
||||
void VID_MenuDraw(void)
|
||||
{
|
||||
// TODO
|
||||
// Video config menu for Quake2.
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -47,7 +51,8 @@ VID_MenuKey
|
||||
*/
|
||||
const char * VID_MenuKey(int k)
|
||||
{
|
||||
return NULL;
|
||||
// TODO
|
||||
return NULL; // Video config menu for Quake2.
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+3
-3
@@ -255,9 +255,9 @@ void SV_Multicast(vec3_t origin, multicast_t to);
|
||||
void SV_StartSound(vec3_t origin, edict_t * entity, int channel, int soundindex,
|
||||
float volume, float attenuation, float timeofs);
|
||||
|
||||
void SV_ClientPrintf(client_t * cl, int level, char * fmt, ...);
|
||||
void SV_BroadcastPrintf(int level, char * fmt, ...);
|
||||
void SV_BroadcastCommand(char * fmt, ...);
|
||||
void SV_ClientPrintf(client_t * cl, int level, const char * fmt, ...);
|
||||
void SV_BroadcastPrintf(int level, const char * fmt, ...);
|
||||
void SV_BroadcastCommand(const char * fmt, ...);
|
||||
|
||||
//
|
||||
// sv_user.c
|
||||
|
||||
@@ -512,7 +512,7 @@ void SV_GameMap_f(void)
|
||||
// clear all the client inuse flags before saving so that
|
||||
// when the level is re-entered, the clients will spawn
|
||||
// at spawn points instead of occupying body shells
|
||||
savedInuse = malloc(maxclients->value * sizeof(qboolean));
|
||||
savedInuse = Z_Malloc(maxclients->value * sizeof(qboolean));
|
||||
for (i = 0, cl = svs.clients; i < maxclients->value; i++, cl++)
|
||||
{
|
||||
savedInuse[i] = cl->edict->inuse;
|
||||
@@ -523,8 +523,11 @@ void SV_GameMap_f(void)
|
||||
|
||||
// we must restore these for clients to transfer over correctly
|
||||
for (i = 0, cl = svs.clients; i < maxclients->value; i++, cl++)
|
||||
{
|
||||
cl->edict->inuse = savedInuse[i];
|
||||
free(savedInuse);
|
||||
}
|
||||
|
||||
Z_Free(savedInuse);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ PF_dprintf
|
||||
Debug print to server console
|
||||
===============
|
||||
*/
|
||||
void PF_dprintf(char * fmt, ...)
|
||||
void PF_dprintf(const char * fmt, ...)
|
||||
{
|
||||
char msg[1024];
|
||||
va_list argptr;
|
||||
@@ -78,7 +78,7 @@ PF_cprintf
|
||||
Print to a single client
|
||||
===============
|
||||
*/
|
||||
void PF_cprintf(edict_t * ent, int level, char * fmt, ...)
|
||||
void PF_cprintf(edict_t * ent, int level, const char * fmt, ...)
|
||||
{
|
||||
char msg[1024];
|
||||
va_list argptr;
|
||||
@@ -114,7 +114,7 @@ PF_centerprintf
|
||||
centerprint to a single client
|
||||
===============
|
||||
*/
|
||||
void PF_centerprintf(edict_t * ent, char * fmt, ...)
|
||||
void PF_centerprintf(edict_t * ent, const char * fmt, ...)
|
||||
{
|
||||
char msg[1024];
|
||||
va_list argptr;
|
||||
@@ -142,7 +142,7 @@ PF_error
|
||||
Abort the server with a game error
|
||||
===============
|
||||
*/
|
||||
void PF_error(char * fmt, ...)
|
||||
void PF_error(const char * fmt, ...)
|
||||
{
|
||||
char msg[1024];
|
||||
va_list argptr;
|
||||
|
||||
@@ -247,11 +247,15 @@ void SV_SpawnServer(char * server, char * spawnpoint, server_state_t serverstate
|
||||
}
|
||||
else
|
||||
{
|
||||
Com_sprintf(sv.configstrings[CS_MODELS + 1], sizeof(sv.configstrings[CS_MODELS + 1]),
|
||||
Com_sprintf(sv.configstrings[CS_MODELS + 1],
|
||||
sizeof(sv.configstrings[CS_MODELS + 1]),
|
||||
"maps/%s.bsp", server);
|
||||
|
||||
sv.models[1] = CM_LoadMap(sv.configstrings[CS_MODELS + 1], false, &checksum);
|
||||
}
|
||||
Com_sprintf(sv.configstrings[CS_MAPCHECKSUM], sizeof(sv.configstrings[CS_MAPCHECKSUM]),
|
||||
|
||||
Com_sprintf(sv.configstrings[CS_MAPCHECKSUM],
|
||||
sizeof(sv.configstrings[CS_MAPCHECKSUM]),
|
||||
"%i", checksum);
|
||||
|
||||
//
|
||||
@@ -261,8 +265,10 @@ void SV_SpawnServer(char * server, char * spawnpoint, server_state_t serverstate
|
||||
|
||||
for (i = 1; i < CM_NumInlineModels(); i++)
|
||||
{
|
||||
Com_sprintf(sv.configstrings[CS_MODELS + 1 + i], sizeof(sv.configstrings[CS_MODELS + 1 + i]),
|
||||
Com_sprintf(sv.configstrings[CS_MODELS + 1 + i],
|
||||
sizeof(sv.configstrings[CS_MODELS + 1 + i]),
|
||||
"*%i", i);
|
||||
|
||||
sv.models[i + 1] = CM_InlineModel(sv.configstrings[CS_MODELS + 1 + i]);
|
||||
}
|
||||
|
||||
|
||||
@@ -734,7 +734,6 @@ void SV_RunGameFrame(void)
|
||||
/*
|
||||
==================
|
||||
SV_Frame
|
||||
|
||||
==================
|
||||
*/
|
||||
void SV_Frame(int msec)
|
||||
|
||||
@@ -60,7 +60,7 @@ SV_ClientPrintf
|
||||
Sends text across to be displayed if the level passes
|
||||
=================
|
||||
*/
|
||||
void SV_ClientPrintf(client_t * cl, int level, char * fmt, ...)
|
||||
void SV_ClientPrintf(client_t * cl, int level, const char * fmt, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
char string[1024];
|
||||
@@ -84,7 +84,7 @@ SV_BroadcastPrintf
|
||||
Sends text to all active clients
|
||||
=================
|
||||
*/
|
||||
void SV_BroadcastPrintf(int level, char * fmt, ...)
|
||||
void SV_BroadcastPrintf(int level, const char * fmt, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
char string[2048];
|
||||
@@ -128,7 +128,7 @@ SV_BroadcastCommand
|
||||
Sends text to all active clients
|
||||
=================
|
||||
*/
|
||||
void SV_BroadcastCommand(char * fmt, ...)
|
||||
void SV_BroadcastCommand(const char * fmt, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
char string[1024];
|
||||
@@ -492,7 +492,9 @@ void SV_SendClientMessages(void)
|
||||
if (sv.state == ss_demo && sv.demofile)
|
||||
{
|
||||
if (sv_paused->value)
|
||||
{
|
||||
msglen = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// get the next message
|
||||
@@ -510,6 +512,7 @@ void SV_SendClientMessages(void)
|
||||
}
|
||||
if (msglen > MAX_MSGLEN)
|
||||
Com_Error(ERR_DROP, "SV_SendClientMessages: msglen > MAX_MSGLEN");
|
||||
|
||||
r = fread(msgbuf, msglen, 1, sv.demofile);
|
||||
if (r != 1)
|
||||
{
|
||||
@@ -535,7 +538,9 @@ void SV_SendClientMessages(void)
|
||||
}
|
||||
|
||||
if (sv.state == ss_cinematic || sv.state == ss_demo || sv.state == ss_pic)
|
||||
{
|
||||
Netchan_Transmit(&c->netchan, msglen, msgbuf);
|
||||
}
|
||||
else if (c->state == cs_spawned)
|
||||
{
|
||||
// don't overrun bandwidth
|
||||
|
||||
@@ -43,8 +43,11 @@ void SV_BeginDemoserver(void)
|
||||
|
||||
Com_sprintf(name, sizeof(name), "demos/%s", sv.name);
|
||||
FS_FOpenFile(name, &sv.demofile);
|
||||
|
||||
if (!sv.demofile)
|
||||
{
|
||||
Com_Error(ERR_DROP, "Couldn't open %s\n", name);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -93,6 +96,7 @@ void SV_New_f(void)
|
||||
playernum = -1;
|
||||
else
|
||||
playernum = sv_client - svs.clients;
|
||||
|
||||
MSG_WriteShort(&sv_client->netchan.message, playernum);
|
||||
|
||||
// send full levelname
|
||||
@@ -408,12 +412,16 @@ void SV_Nextserver(void)
|
||||
|
||||
//ZOID, ss_pic can be nextserver'd in coop mode
|
||||
if (sv.state == ss_game || (sv.state == ss_pic && !Cvar_VariableValue("coop")))
|
||||
{
|
||||
return; // can't nextserver while playing a normal game
|
||||
}
|
||||
|
||||
svs.spawncount++; // make sure another doesn't sneak in
|
||||
v = Cvar_VariableString("nextserver");
|
||||
if (!v[0])
|
||||
{
|
||||
Cbuf_AddText("killserver\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
Cbuf_AddText(v);
|
||||
|
||||
Reference in new issue
Block a user