From 49ae9573b8679d97b77f7137f94ba3033adbe9ea Mon Sep 17 00:00:00 2001 From: Spoike Date: Thu, 11 Oct 2018 10:31:23 +0000 Subject: [PATCH] reworked clipboard handling to avoid stalls when pasting in linux. made a load of functions static (just code style stuff). downloads menu now deselects any autoselected items, to avoid confusion. csqc traces can now hit networked ents. I probably need to make some more tweaks to this. arg completion for flocate+dir+modelviewer commands. fix autosave not cycling saves when using the vanilla save format. fix patch collisions with q3bsp submodels. md3 now supports framegroups too. added some more buttons to make xonotic happy. gl_polyblend 2 shows the screen flashes at the edge of the screen instead of the middle. colormod no longer applies to fullbrights (matching DP). this fixes an issue with xonotic. fix uninitialised local that was causing issues with bones used as tags. rewrote qc search_* to use a dynamic array instead of a linked list. this should make it faster to read when there's many handles open at a time. fte's saved games can now save buffers properly. fix issue with raster freetype fonts (read: coloured emoji). initial support for struct-based classes (instead of entity-based classes). still has issues. execing configs in untrusted packages will no longer run out of sync (fixing a number of afterquake issues). fix stupid bug with the te_gunshot/etc builtins. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5317 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- CMakeLists.txt | 11 + engine/client/cl_ents.c | 17 +- engine/client/cl_input.c | 93 +-- engine/client/cl_main.c | 4 +- engine/client/cl_parse.c | 12 +- engine/client/cl_plugin.inc | 8 +- engine/client/cl_screen.c | 34 +- engine/client/client.h | 1 + engine/client/console.c | 23 +- engine/client/keys.c | 18 +- engine/client/m_download.c | 315 ++++++--- engine/client/m_master.c | 4 +- engine/client/m_options.c | 33 +- engine/client/m_single.c | 16 +- engine/client/menu.c | 5 +- engine/client/merged.h | 2 +- engine/client/pr_csqc.c | 26 +- engine/client/pr_menu.c | 4 +- engine/client/r_2d.c | 104 ++- engine/client/r_surf.c | 9 + engine/client/render.h | 1 + engine/client/renderer.c | 4 +- engine/client/snd_al.c | 16 +- engine/client/snd_linux.c | 10 +- engine/client/sys_droid.c | 14 +- engine/client/sys_linux.c | 77 ++- engine/client/sys_morphos.c | 14 +- engine/client/sys_sdl.c | 21 +- engine/client/sys_win.c | 44 +- engine/client/sys_xdk.c | 13 +- engine/client/textedit.c | 19 +- engine/client/view.c | 74 ++- engine/common/cmd.c | 69 +- engine/common/com_mesh.c | 190 +++--- engine/common/com_phys_ode.c | 6 +- engine/common/common.c | 99 +-- engine/common/common.h | 3 + engine/common/cvar.c | 23 +- engine/common/fs.c | 174 +++-- engine/common/fs_stdio.c | 2 +- engine/common/gl_q2bsp.c | 324 +++++----- engine/common/huff.c | 6 +- engine/common/mathlib.c | 10 +- engine/common/net_ssl_gnutls.c | 16 +- engine/common/net_wins.c | 24 +- engine/common/plugin.c | 70 +- engine/common/pmove.c | 7 +- engine/common/pmovetst.c | 4 +- engine/common/pr_bgcmd.c | 308 +++++---- engine/common/pr_common.h | 3 +- engine/common/sys.h | 10 +- engine/common/zone.c | 8 +- engine/gl/gl_alias.c | 5 +- engine/gl/gl_font.c | 80 ++- engine/gl/gl_heightmap.c | 169 ++--- engine/gl/gl_model.c | 8 +- engine/gl/gl_model.h | 3 + engine/gl/gl_shader.c | 73 +-- engine/gl/gl_shadow.c | 2 + engine/gl/gl_videgl.c | 10 +- engine/gl/gl_vidlinuxglx.c | 147 +++-- engine/gl/gl_vidmacos.c | 19 +- engine/gl/gl_vidwayland.c | 2 +- engine/gl/r_bishaders.h | 3 +- engine/nacl/sys_ppapi.c | 14 +- engine/qclib/cmdlib.h | 3 +- engine/qclib/comprout.c | 3 +- engine/qclib/execloop.h | 26 +- engine/qclib/hash.c | 2 +- engine/qclib/initlib.c | 89 +-- engine/qclib/pr_edict.c | 144 ++--- engine/qclib/pr_exec.c | 194 +++--- engine/qclib/pr_multi.c | 26 +- engine/qclib/progsint.h | 62 +- engine/qclib/progslib.h | 24 +- engine/qclib/qcc.h | 11 +- engine/qclib/qcc_cmdlib.c | 22 +- engine/qclib/qcc_pr_comp.c | 696 +++++++++++++------- engine/qclib/qcc_pr_lex.c | 913 ++++++++++++++++----------- engine/qclib/qccmain.c | 574 ++++++++--------- engine/server/pr_cmds.c | 97 ++- engine/server/pr_q1qvm.c | 4 +- engine/server/progdefs.h | 7 - engine/server/progs.h | 1 + engine/server/savegame.c | 8 +- engine/server/sv_ccmds.c | 9 +- engine/server/sv_main.c | 2 +- engine/server/sv_mvd.c | 2 +- engine/server/sv_send.c | 2 +- engine/server/sv_sys_unix.c | 70 +- engine/server/sv_user.c | 39 +- engine/server/world.c | 135 +++- engine/shaders/glsl/defaultskin.glsl | 3 +- engine/web/sys_web.c | 12 +- plugins/ezhud/ezquakeisms.c | 2 +- plugins/ezhud/ezquakeisms.h | 247 ++++---- plugins/ezhud/hud_common.c | 2 +- plugins/irc/ircclient.c | 62 +- plugins/plugin.c | 15 +- plugins/plugin.h | 10 +- plugins/qi/qi.c | 18 +- 101 files changed, 3783 insertions(+), 2690 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e3c6ffad7..876a014a5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -113,8 +113,19 @@ ENDIF() IF(CMAKE_C_COMPILER_ID MATCHES "Clang") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-pointer-sign") endif() +IF(CMAKE_C_COMPILER_ID MATCHES "GNU") + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wstrict-prototypes") # + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wold-style-definition") #k&r c is weird and can't cope with 64bit types. + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wold-style-declaration") # + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wvla") #msvc doesn't support vla + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wdeclaration-after-statement") #msvc doesn't allow defs after statements, and they're so very tempting... + #SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wc++-compat") #lul + #TODO SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wmissing-prototypes") #for finding missing statics. + #SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-function") # +ENDIF() IF(CMAKE_BUILD_TYPE MATCHES "Debug") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fstack-protector-strong") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu89") endif() IF(${ANDROID}) diff --git a/engine/client/cl_ents.c b/engine/client/cl_ents.c index b70719455..862c5c4c6 100644 --- a/engine/client/cl_ents.c +++ b/engine/client/cl_ents.c @@ -1909,16 +1909,15 @@ entity_state_t *CL_FindPacketEntity(int num) { int pnum; entity_state_t *s1; - packet_entities_t *pack; - pack = &cl.inframes[cl.validsequence&UPDATE_MASK].packet_entities; + packet_entities_t *pack = cl.currentpackentities; + if (pack) + for (pnum=0 ; pnumnum_entities ; pnum++) + { + s1 = &pack->entities[pnum]; - for (pnum=0 ; pnumnum_entities ; pnum++) - { - s1 = &pack->entities[pnum]; - - if (num == s1->number) - return s1; - } + if (num == s1->number) + return s1; + } return NULL; } #endif diff --git a/engine/client/cl_input.c b/engine/client/cl_input.c index e45870630..7bab09b69 100644 --- a/engine/client/cl_input.c +++ b/engine/client/cl_input.c @@ -150,7 +150,7 @@ static kbutton_t in_lookup, in_lookdown, in_moveleft, in_moveright; static kbutton_t in_use, in_jump, in_attack; static kbutton_t in_rollleft, in_rollright, in_up, in_down; -static kbutton_t in_button3, in_button4, in_button5, in_button6, in_button7, in_button8; +static kbutton_t in_button[16+1-3]; #define IN_IMPULSECACHE 32 static int in_impulse[MAX_SPLITS][IN_IMPULSECACHE]; @@ -322,18 +322,8 @@ static void IN_JumpUp (void) KeyUp(&in_jump); } -static void IN_Button3Down(void) {KeyDown(&in_button3, NULL);} -static void IN_Button3Up(void) {KeyUp(&in_button3);} -static void IN_Button4Down(void) {KeyDown(&in_button4, NULL);} -static void IN_Button4Up(void) {KeyUp(&in_button4);} -static void IN_Button5Down(void) {KeyDown(&in_button5, NULL);} -static void IN_Button5Up(void) {KeyUp(&in_button5);} -static void IN_Button6Down(void) {KeyDown(&in_button6, NULL);} -static void IN_Button6Up(void) {KeyUp(&in_button6);} -static void IN_Button7Down(void) {KeyDown(&in_button7, NULL);} -static void IN_Button7Up(void) {KeyUp(&in_button7);} -static void IN_Button8Down(void) {KeyDown(&in_button8, NULL);} -static void IN_Button8Up(void) {KeyUp(&in_button8);} +static void IN_ButtonNDown(void) {KeyDown(&in_button[atoi(Cmd_Argv(0)+7)-3], NULL);} +static void IN_ButtonNUp(void) {KeyUp(&in_button[atoi(Cmd_Argv(0)+7)-3]);} float in_rotate; static void IN_Rotate_f (void) {in_rotate += atoi(Cmd_Argv(1));} @@ -367,12 +357,6 @@ void IN_WriteButtons(vfsfile_t *f, qboolean all) {&in_rollright, "rollright"}, {&in_up, "up"}, {&in_down, "down"}, - {&in_button3, "button3"}, - {&in_button4, "button4"}, - {&in_button5, "button5"}, - {&in_button6, "button6"}, - {&in_button7, "button7"}, - {&in_button8, "button8"} }; s = 0; @@ -384,6 +368,13 @@ void IN_WriteButtons(vfsfile_t *f, qboolean all) else if (b || all) VFS_PRINTF(f, "-%s\n", buttons[b].name); } + for (b = 0; b < countof(in_button); b++) + { + if ((in_button[b].state[s]&1) && (in_button[b].down[s][0]==-1 || in_button[b].down[s][1]==-1)) + VFS_PRINTF(f, "+button%i\n", b+3); + else + VFS_PRINTF(f, "-button%i\n", b+3); + } for (s = 1; s < MAX_SPLITS; s++) { VFS_PRINTF(f, "\n//Player %i buttons\n", s); @@ -394,6 +385,13 @@ void IN_WriteButtons(vfsfile_t *f, qboolean all) else if (b || all) VFS_PRINTF(f, "-p%i %s\n", s, buttons[b].name); } + for (b = 0; b < countof(in_button); b++) + { + if ((in_button[b].state[s]&1) && (in_button[b].down[s][0]==-1 || in_button[b].down[s][1]==-1)) + VFS_PRINTF(f, "+p%i button%i\n", s, b+3); + else + VFS_PRINTF(f, "-p%i button%i\n", s, b+3); + } } //FIXME: save device remappings to config. @@ -589,19 +587,34 @@ cvar_t cl_pitchspeed = CVAR("cl_pitchspeed","150"); cvar_t cl_anglespeedkey = CVAR("cl_anglespeedkey","1.5"); -#define GATHERBIT(bname,bit) if (bname.state[pnum] & 3) {bits |= bit;} bname.state[pnum] &= ~2; +#define GATHERBIT(bname,bit) if (bname.state[pnum] & 3) {bits |= (1u<buttons = bits; } @@ -2280,7 +2293,7 @@ CL_InitInput void CL_InitInput (void) { static char pcmd[MAX_SPLITS][3][5]; - int sp; + unsigned int sp, i; #define inputnetworkcvargroup "client networking options" cl.splitclients = 1; @@ -2372,16 +2385,12 @@ void CL_InitInput (void) Cmd_AddCommand ("+mlook", IN_MLookDown); Cmd_AddCommand ("-mlook", IN_MLookUp); - Cmd_AddCommand ("+button3", IN_Button3Down); - Cmd_AddCommand ("-button3", IN_Button3Up); - Cmd_AddCommand ("+button4", IN_Button4Down); - Cmd_AddCommand ("-button4", IN_Button4Up); - Cmd_AddCommand ("+button5", IN_Button5Down); - Cmd_AddCommand ("-button5", IN_Button5Up); - Cmd_AddCommand ("+button6", IN_Button6Down); - Cmd_AddCommand ("-button6", IN_Button6Up); - Cmd_AddCommand ("+button7", IN_Button7Down); - Cmd_AddCommand ("-button7", IN_Button7Up); - Cmd_AddCommand ("+button8", IN_Button8Down); - Cmd_AddCommand ("-button8", IN_Button8Up); + for (i = 0; i < countof(in_button); i++) + { + static char bcmd[countof(in_button)][2][10]; + Q_snprintfz(bcmd[i][0], sizeof(bcmd[sp][0]), "+button%i", i+3); + Q_snprintfz(bcmd[i][1], sizeof(bcmd[sp][1]), "-button%i", i+3); + Cmd_AddCommand (bcmd[i][0], IN_ButtonNDown); + Cmd_AddCommand (bcmd[i][1], IN_ButtonNUp); + } } diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index 175103ee6..7aa1e6d27 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -46,7 +46,7 @@ int startuppending; void Host_FinishLoading(void); -cvar_t cl_crypt_rcon = CVARFD("cl_crypt_rcon", "1", CVAR_ARCHIVE, "Controls whether to send a hash instead of sending rcon passwords as plain-text. Set to 1 for security, or 0 for backwards compatibility.\nYour command and any responses will still be sent as plain text.\nInstead, it is recommended to use rcon ONLY via dtls/tls/wss connections."); +cvar_t cl_crypt_rcon = CVARFD("cl_crypt_rcon", "1", CVAR_ARCHIVE|CVAR_NOTFROMSERVER, "Controls whether to send a hash instead of sending rcon passwords as plain-text. Set to 1 for security, or 0 for backwards compatibility.\nYour command and any responses will still be sent as plain text.\nInstead, it is recommended to use rcon ONLY via dtls/tls/wss connections."); //CVAR_NOTFROMSERVER prevents evil servers from degrading it to send plain-text passwords. cvar_t rcon_password = CVARF("rcon_password", "", CVAR_NOUNSAFEEXPAND); cvar_t rcon_address = CVARF("rcon_address", "", CVAR_NOUNSAFEEXPAND); @@ -6169,7 +6169,7 @@ void CL_ExecInitialConfigs(char *resetcommand) Cbuf_AddText("bind volup \"inc volume 0.1\"\n", RESTRICT_LOCAL); Cbuf_AddText("bind voldown \"inc volume -0.1\"\n", RESTRICT_LOCAL); Cbuf_AddText("alias restart_ents \"changelevel . .\"\n",RESTRICT_LOCAL); - Cbuf_AddText("alias restart \"changelevel .\"\n",RESTRICT_LOCAL); + Cbuf_AddText("alias restart map_restart\n",RESTRICT_LOCAL); Cbuf_AddText("alias startmap_sp \"map start\"\n", RESTRICT_LOCAL); Cbuf_AddText("cl_warncmd 0\n", RESTRICT_LOCAL); Cbuf_AddText("cvar_purgedefaults\n", RESTRICT_LOCAL); //reset cvar defaults to their engine-specified values. the tail end of 'exec default.cfg' will update non-cheat defaults to mod-specified values. diff --git a/engine/client/cl_parse.c b/engine/client/cl_parse.c index 98328be1a..9bf0897c7 100644 --- a/engine/client/cl_parse.c +++ b/engine/client/cl_parse.c @@ -1204,7 +1204,8 @@ static int CL_LoadModels(int stage, qboolean dontactuallyload) float giveuptime = Sys_DoubleTime()+1; //small things get padded into a single frame #define atstage() ((cl.contentstage == stage++ && !dontactuallyload)?true:false) -#define endstage() ++cl.contentstage;if (!cls.timedemo && giveuptime scr_con_current) - scr_con_current = scr_conlines; + } + if (scr_conlines < scr_con_current) + { + scr_con_current -= scr_conspeed.value*host_frametime * (vid.height/320.0f); + if (scr_conlines > scr_con_current) + scr_con_current = scr_conlines; - } - else if (scr_conlines > scr_con_current) - { - scr_con_current += scr_conspeed.value*host_frametime * (vid.height/320.0f); - if (scr_conlines < scr_con_current) - scr_con_current = scr_conlines; - } + } + else if (scr_conlines > scr_con_current) + { + scr_con_current += scr_conspeed.value*host_frametime * (vid.height/320.0f); + if (scr_conlines < scr_con_current) + scr_con_current = scr_conlines; } if (scr_con_current>vid.height) diff --git a/engine/client/client.h b/engine/client/client.h index 3c8eb48d6..8d010d8e1 100644 --- a/engine/client/client.h +++ b/engine/client/client.h @@ -710,6 +710,7 @@ struct playerview_s cshift_t cshifts[NUM_CSHIFTS]; // color shifts for damage, powerups and content types vec4_t screentint; + vec4_t bordertint; //won't contain v_cshift values, only powerup+contents+damage+bf flashes vec3_t vw_axis[3]; //weapons should be positioned relative to this vec3_t vw_origin; //weapons should be positioned relative to this diff --git a/engine/client/console.c b/engine/client/console.c index ffdfe6e31..16d66ee07 100644 --- a/engine/client/console.c +++ b/engine/client/console.c @@ -1351,8 +1351,6 @@ int Con_DrawInput (console_t *con, qboolean focused, int left, int right, int y, for (p = 0; (textstart[p]&CON_CHARMASK)>' '; p++) textstart[p] = (textstart[p]&CON_CHARMASK) | (COLOR_YELLOW<linewidth); if (cursor == endmtext) //cursor is at end { @@ -1371,8 +1369,6 @@ int Con_DrawInput (console_t *con, qboolean focused, int left, int right, int y, } } } -// else -// Plug_SpellCheckMaskedText(maskedtext+1, i-1, x, y, 8, si, con_current->linewidth); if (!vid.activeapp) cursorframe = 0; @@ -2306,15 +2302,18 @@ static int Con_DrawConsoleLines(console_t *con, conline_t *l, int sx, int ex, in send += center; if (selactive == 1) - R2D_ImageColours(SRGBA(0.1,0.1,0.3, alphaval)); //selected - else - R2D_ImageColours(SRGBA(0.3,0.3,0.3, alphaval)); //mouseover. + { + if (selactive == 1) + R2D_ImageColours(SRGBA(0.1,0.1,0.3, alphaval)); //selected + else + R2D_ImageColours(SRGBA(0.3,0.3,0.3, alphaval)); //mouseover. - if (send < sstart) - R2D_FillBlock((send*vid.width)/(float)vid.rotpixelwidth, (y*vid.height)/(float)vid.rotpixelheight, ((sstart - send)*vid.width)/(float)vid.rotpixelwidth, (Font_CharHeight()*vid.height)/(float)vid.rotpixelheight); - else - R2D_FillBlock((sstart*vid.width)/(float)vid.rotpixelwidth, (y*vid.height)/(float)vid.rotpixelheight, ((send - sstart)*vid.width)/(float)vid.rotpixelwidth, (Font_CharHeight()*vid.height)/(float)vid.rotpixelheight); - R2D_Flush(); + if (send < sstart) + R2D_FillBlock((send*vid.width)/(float)vid.rotpixelwidth, (y*vid.height)/(float)vid.rotpixelheight, ((sstart - send)*vid.width)/(float)vid.rotpixelwidth, (Font_CharHeight()*vid.height)/(float)vid.rotpixelheight); + else + R2D_FillBlock((sstart*vid.width)/(float)vid.rotpixelwidth, (y*vid.height)/(float)vid.rotpixelheight, ((send - sstart)*vid.width)/(float)vid.rotpixelwidth, (Font_CharHeight()*vid.height)/(float)vid.rotpixelheight); + R2D_Flush(); + } } } } diff --git a/engine/client/keys.c b/engine/client/keys.c index 7498c9b37..f9d95365f 100644 --- a/engine/client/keys.c +++ b/engine/client/keys.c @@ -1172,7 +1172,7 @@ void Key_ConsoleRelease(console_t *con, int key, unsigned int unicode) buffer = Con_CopyConsole(con, true, false); //don't keep markup if we're copying to the clipboard if (!buffer) return; - Sys_SaveClipboard(buffer); + Sys_SaveClipboard(CBT_SELECTION, buffer); Z_Free(buffer); } if (con->buttonsdown == CB_CLOSE) @@ -1320,6 +1320,13 @@ void Key_EntryInsert(unsigned char **line, int *linepos, char *instext) *linepos += len; } +static void Key_ConsolePaste(void *ctx, char *utf8) +{ + unsigned char **line = ctx; + int *linepos = ((line == &chat_buffer)?&chat_bufferpos:&key_linepos); + if (utf8) + Key_EntryInsert(line, linepos, utf8); +} qboolean Key_EntryLine(unsigned char **line, int lineoffset, int *linepos, int key, unsigned int unicode) { qboolean alt = keydown[K_LALT] || keydown[K_RALT]; @@ -1408,18 +1415,21 @@ qboolean Key_EntryLine(unsigned char **line, int lineoffset, int *linepos, int k //beware that windows translates ctrl+c and ctrl+v to a control char if (((unicode=='C' || unicode=='c' || unicode==3) && ctrl) || (ctrl && key == K_INS)) { - Sys_SaveClipboard(*line); + Sys_SaveClipboard(CBT_CLIPBOARD, *line); return true; } if (((unicode=='V' || unicode=='v' || unicode==22) && ctrl) || (shift && key == K_INS)) { + Sys_Clipboard_PasteText(CBT_CLIPBOARD, Key_ConsolePaste, line); + /* char *clipText = Sys_GetClipboard(); if (clipText) { Key_EntryInsert(line, linepos, clipText); Sys_CloseClipboard(clipText); } + */ return true; } @@ -1813,7 +1823,9 @@ qboolean Key_Console (console_t *con, int key, unsigned int unicode) char *txt = key_lines[edit_line]; char *guess = Cmd_CompleteCommand(*txt=='/'?txt+1:txt, true, true, con_commandmatch, NULL); Key_EntryLine(&key_lines[edit_line], 0, &key_linepos, key, unicode); - if (guess) + if (!key_linepos) + con_commandmatch = 0; + else if (guess) { guess = Z_StrDup(guess); txt = key_lines[edit_line]; diff --git a/engine/client/m_download.c b/engine/client/m_download.c index abaa2607f..49ee3d85e 100644 --- a/engine/client/m_download.c +++ b/engine/client/m_download.c @@ -70,24 +70,26 @@ extern cvar_t pm_downloads_url; //!installed * missing [simply not installed] -#define DPF_ENABLED 0x01 -#define DPF_NATIVE 0x02 //appears to be installed properly -#define DPF_CACHED 0x04 //appears to be installed in their dlcache dir (and has a qhash) -#define DPF_CORRUPT 0x08 //will be deleted before it can be changed +#define DPF_ENABLED (1u<<0) +#define DPF_NATIVE (1u<<1) //appears to be installed properly +#define DPF_CACHED (1u<<2) //appears to be installed in their dlcache dir (and has a qhash) +#define DPF_CORRUPT (1u<<3) //will be deleted before it can be changed -#define DPF_MARKED 0x10 //user selected it -#define DPF_DISPLAYVERSION 0x20 //some sort of conflict, the package is listed twice, so show versions so the user knows what's old. -#define DPF_FORGETONUNINSTALL 0x40 //for previously installed packages, remove them from the list if there's no current version any more (should really be automatic if there's no known mirrors) -#define DPF_HIDDEN 0x80 //wrong arch, file conflicts, etc. still listed if actually installed. -#define DPF_PURGE 0x200 //package should be completely removed (ie: the dlcache dir too). if its still marked then it should be reinstalled anew. available on cached or corrupt packages, implied by native. -#define DPF_MANIFEST 0x400 //package was named by the manifest, and should only be uninstalled after a warning. -#define DPF_TESTING 0x800 //package is provided on a testing/trial basis, and will only be selected/listed if autoupdates are configured to allow it. +#define DPF_USERMARKED (1u<<4) //user selected it +#define DPF_AUTOMARKED (1u<<5) //selected only to satisfy a dependancy +#define DPF_DISPLAYVERSION (1u<<6) //some sort of conflict, the package is listed twice, so show versions so the user knows what's old. +#define DPF_FORGETONUNINSTALL (1u<<7) //for previously installed packages, remove them from the list if there's no current version any more (should really be automatic if there's no known mirrors) +#define DPF_HIDDEN (1u<<8) //wrong arch, file conflicts, etc. still listed if actually installed. +#define DPF_PURGE (1u<<9) //package should be completely removed (ie: the dlcache dir too). if its still marked then it should be reinstalled anew. available on cached or corrupt packages, implied by native. +#define DPF_MANIFEST (1u<<10) //package was named by the manifest, and should only be uninstalled after a warning. +#define DPF_TESTING (1u<<11) //package is provided on a testing/trial basis, and will only be selected/listed if autoupdates are configured to allow it. -#define DPF_ENGINE 0x1000 //engine update. replaces old autoupdate mechanism -#define DPF_PLUGIN 0x2000 //this is a plugin package, with a dll +#define DPF_ENGINE (1u<<12) //engine update. replaces old autoupdate mechanism +#define DPF_PLUGIN (1u<<13) //this is a plugin package, with a dll -#define DPF_TRUSTED 0x4000 //flag used when parsing package lists. if not set then packages will be ignored if they are anything but paks/pk3s +#define DPF_TRUSTED (1u<<14) //flag used when parsing package lists. if not set then packages will be ignored if they are anything but paks/pk3s +#define DPF_MARKED (DPF_USERMARKED|DPF_AUTOMARKED) #define DPF_PRESENT (DPF_NATIVE|DPF_CACHED) #define DPF_DISABLEDINSTALLED (DPF_ENGINE|DPF_PLUGIN) //engines+plugins can be installed without being enabled. //pak.lst @@ -972,7 +974,7 @@ static void PM_ParsePackageList(vfsfile_t *f, int parseflags, const char *url, c } } if (p->flags & DPF_ENABLED) - p->flags |= DPF_MARKED; + p->flags |= DPF_USERMARKED; //FIXME: we don't know if this was manual or auto PM_InsertPackage(p); } @@ -1219,15 +1221,31 @@ static void PM_RevertChanges(void) for (p = availablepackages; p; p = p->next) { if (p->flags & DPF_ENABLED) - p->flags |= DPF_MARKED; + p->flags |= DPF_USERMARKED; else p->flags &= ~DPF_MARKED; p->flags &= ~DPF_PURGE; } } -//just flags, doesn't delete -static void PM_UnmarkPackage(package_t *package) +static qboolean PM_HasDependant(package_t *package, unsigned int markflag) +{ + package_t *o; + struct packagedep_s *dep; + for (o = availablepackages; o; o = o->next) + { + if (o->flags & markflag) + for (dep = o->deps; dep; dep = dep->next) + if (dep->dtype == DEP_REQUIRE || dep->dtype == DEP_RECOMMEND) + if (!strcmp(package->name, dep->name)) + return true; + } + return false; +} + +//just flags, doesn't delete (yet) +//markflag should be DPF_AUTOMARKED or DPF_USERMARKED +static void PM_UnmarkPackage(package_t *package, unsigned int markflag) { package_t *o; struct packagedep_s *dep; @@ -1235,32 +1253,51 @@ static void PM_UnmarkPackage(package_t *package) if (pkg_updating) return; - if (!(package->flags & DPF_MARKED)) + if (!(package->flags & markflag)) return; //looks like its already deselected. - package->flags &= ~(DPF_MARKED); + package->flags &= ~(markflag); + if (!(package->flags & DPF_MARKED)) + { #ifdef WEBCLIENT - //Is this safe? - package->trymirrors = 0; //if its enqueued, cancel that quickly... - if (package->download) - { //if its currently downloading, cancel it. - DL_Close(package->download); - package->download = NULL; - } + //Is this safe? + package->trymirrors = 0; //if its enqueued, cancel that quickly... + if (package->download) + { //if its currently downloading, cancel it. + DL_Close(package->download); + package->download = NULL; + } #endif - //remove stuff that depends on us - for (o = availablepackages; o; o = o->next) + //remove stuff that depends on us + for (o = availablepackages; o; o = o->next) + { + for (dep = o->deps; dep; dep = dep->next) + if (dep->dtype == DEP_REQUIRE) + if (!strcmp(dep->name, package->name)) + PM_UnmarkPackage(o, DPF_MARKED); + } + } + if (!(package->flags & DPF_USERMARKED)) { - for (dep = o->deps; dep; dep = dep->next) - if (dep->dtype == DEP_REQUIRE) - if (!strcmp(dep->name, package->name)) - PM_UnmarkPackage(o); + //go through dependancies and unmark any automarked packages if nothing else depends upon them + for (dep = package->deps; dep; dep = dep->next) + { + if (dep->dtype == DEP_REQUIRE || dep->dtype == DEP_RECOMMEND) + { + package_t *d = PM_MarkedPackage(dep->name); + if (d && !(d->flags & DPF_USERMARKED)) + { + if (!PM_HasDependant(d, DPF_MARKED)) + PM_UnmarkPackage(d, DPF_AUTOMARKED); + } + } + } } } //just flags, doesn't install -static void PM_MarkPackage(package_t *package) +static void PM_MarkPackage(package_t *package, unsigned int markflag) { package_t *o; struct packagedep_s *dep, *dep2; @@ -1270,7 +1307,10 @@ static void PM_MarkPackage(package_t *package) return; if (package->flags & DPF_MARKED) + { + package->flags |= markflag; return; //looks like its already picked. + } //any file-conflicts prevent the package from being installable. //this is mostly for pak1.pak @@ -1288,7 +1328,7 @@ static void PM_MarkPackage(package_t *package) } } - package->flags |= DPF_MARKED; + package->flags |= markflag; //first check to see if we're replacing a different version of the same package for (o = availablepackages; o; o = o->next) @@ -1314,7 +1354,7 @@ static void PM_MarkPackage(package_t *package) if (dep2->dtype == DEP_FILE) if (!strcmp(dep->name, dep2->name)) { - PM_UnmarkPackage(o); + PM_UnmarkPackage(o, DPF_MARKED); remove = true; break; } @@ -1341,7 +1381,7 @@ static void PM_MarkPackage(package_t *package) { d = PM_FindPackage(dep->name); if (d) - PM_MarkPackage(d); + PM_MarkPackage(d, DPF_AUTOMARKED); else Con_DPrintf("Couldn't find dependancy \"%s\"\n", dep->name); } @@ -1353,7 +1393,7 @@ static void PM_MarkPackage(package_t *package) package_t *d = PM_MarkedPackage(dep->name); if (!d) break; - PM_UnmarkPackage(d); + PM_UnmarkPackage(d, DPF_MARKED); } } } @@ -1364,7 +1404,7 @@ static void PM_MarkPackage(package_t *package) for (dep = o->deps; dep; dep = dep->next) if (dep->dtype == DEP_CONFLICT) if (!strcmp(dep->name, package->name)) - PM_UnmarkPackage(o); + PM_UnmarkPackage(o, DPF_MARKED); } } @@ -1402,7 +1442,7 @@ static unsigned int PM_MarkUpdates (void) p = PM_FindPackage(tok); if (p) { - PM_MarkPackage(p); + PM_MarkPackage(p, DPF_AUTOMARKED); changecount++; } } @@ -1438,8 +1478,8 @@ static unsigned int PM_MarkUpdates (void) if (b) { changecount++; - PM_MarkPackage(b); - PM_UnmarkPackage(p); + PM_MarkPackage(b, p->flags&DPF_MARKED); + PM_UnmarkPackage(p, DPF_MARKED); } } } @@ -1448,7 +1488,7 @@ static unsigned int PM_MarkUpdates (void) if (pm_autoupdate.ival >= UPD_STABLE) { changecount++; - PM_MarkPackage(e); + PM_MarkPackage(e, DPF_AUTOMARKED); } } @@ -2786,7 +2826,7 @@ void PM_Command_f(void) const char *key = Cmd_Argv(arg); p = PM_FindPackage(key); if (p) - PM_MarkPackage(p); + PM_MarkPackage(p, DPF_USERMARKED); else Con_Printf("%s: package %s not known\n", Cmd_Argv(0), key); } @@ -2801,7 +2841,7 @@ void PM_Command_f(void) p = PM_FindPackage(key); if (p) { - PM_MarkPackage(p); + PM_MarkPackage(p, DPF_USERMARKED); p->flags |= DPF_PURGE; } else @@ -2819,7 +2859,7 @@ void PM_Command_f(void) if (!p) p = PM_FindPackage(key); if (p) - PM_UnmarkPackage(p); + PM_UnmarkPackage(p, DPF_MARKED); else Con_Printf("%s: package %s not known\n", Cmd_Argv(0), key); } @@ -2836,7 +2876,7 @@ void PM_Command_f(void) p = PM_FindPackage(key); if (p) { - PM_UnmarkPackage(p); + PM_UnmarkPackage(p, DPF_MARKED); p->flags |= DPF_PURGE; } else @@ -2926,6 +2966,7 @@ typedef struct { char intermediatefilename[MAX_QPATH]; char pathprefix[MAX_QPATH]; int downloadablessequence; + char titletext[128]; qboolean populated; } dlmenu_t; @@ -2949,48 +2990,55 @@ static void MD_Draw (int x, int y, struct menucustom_s *c, struct menu_s *m) else #endif { - switch((p->flags & (DPF_ENABLED | DPF_MARKED))) + if (!(p->flags & DPF_MARKED)) { - case 0: - if (p->flags & DPF_PURGE) - Draw_FunString (x, y, "DEL"); //purge - else if (p->flags & DPF_HIDDEN) - Draw_FunString (x+4, y, "---"); - else if (p->flags & DPF_CORRUPT) - Draw_FunString (x, y, "!!!"); - else - { - Draw_FunString (x+4, y, "^Ue080^Ue082"); - Draw_FunString (x+8, y, "^Ue081"); - if (p->flags & DPF_PRESENT) - Draw_FunString (x+8, y, "C"); + if (!(p->flags & DPF_ENABLED)) + { //!DPF_MARKED|!DPF_ENABLED: + if (p->flags & DPF_PURGE) + Draw_FunString (x, y, "DEL"); //purge + else if (p->flags & DPF_HIDDEN) + Draw_FunString (x+4, y, "---"); + else if (p->flags & DPF_CORRUPT) + Draw_FunString (x, y, "!!!"); + else + { + Draw_FunString (x+4, y, "^Ue080^Ue082"); + Draw_FunString (x+8, y, "^Ue081"); + if (p->flags & DPF_PRESENT) + Draw_FunString (x+8, y, "-"); + } } - break; - case DPF_ENABLED: - if ((p->flags & DPF_PURGE) || PM_PurgeOnDisable(p)) - Draw_FunString (x, y, "DEL"); else - Draw_FunString (x, y, "REM"); - break; - case DPF_MARKED: - if (p->flags & DPF_PURGE) - Draw_FunString (x, y, "GET"); - else if (p->flags & (DPF_PRESENT)) - Draw_FunString (x, y, "USE"); - else - Draw_FunString (x, y, "GET"); - break; - case DPF_ENABLED | DPF_MARKED: - if (p->flags & DPF_PURGE) - Draw_FunString (x, y, "GET"); //purge and reinstall. - else if (p->flags & DPF_CORRUPT) - Draw_FunString (x, y, "?""?""?"); - else - { - Draw_FunString (x+4, y, "^Ue080^Ue082"); - Draw_FunString (x+8, y, "^Ue083"); + { //!DPF_MARKED|DPF_ENABLED: + if ((p->flags & DPF_PURGE) || PM_PurgeOnDisable(p)) + Draw_FunString (x, y, "DEL"); + else + Draw_FunString (x, y, "REM"); + } + } + else + { + if (!(p->flags & DPF_ENABLED)) + { //DPF_MARKED|!DPF_ENABLED: + if (p->flags & DPF_PURGE) + Draw_FunString (x, y, "GET"); + else if (p->flags & (DPF_PRESENT)) + Draw_FunString (x, y, "USE"); + else + Draw_FunString (x, y, "GET"); + } + else + { //DPF_MARKED|DPF_ENABLED: + if (p->flags & DPF_PURGE) + Draw_FunString (x, y, "GET"); //purge and reinstall. + else if (p->flags & DPF_CORRUPT) + Draw_FunString (x, y, "?""?""?"); + else + { + Draw_FunString (x+4, y, "^Ue080^Ue082"); + Draw_FunString (x+8, y, "^Ue083"); + } } - break; } } @@ -3026,8 +3074,10 @@ static qboolean MD_Key (struct menucustom_s *c, struct menu_s *m, int key, unsig { switch (p->flags & (DPF_PURGE|DPF_MARKED)) { + case DPF_USERMARKED: + case DPF_AUTOMARKED: case DPF_MARKED: - PM_UnmarkPackage(p); //deactivate it + PM_UnmarkPackage(p, DPF_MARKED); //deactivate it break; case 0: p->flags |= DPF_PURGE; //purge @@ -3035,10 +3085,12 @@ static qboolean MD_Key (struct menucustom_s *c, struct menu_s *m, int key, unsig break; //fall through case DPF_PURGE: - PM_MarkPackage(p); //reinstall + PM_MarkPackage(p, DPF_USERMARKED); //reinstall // if (!(p->flags & DPF_HIDDEN) && !(p->flags & DPF_CACHED)) // break; //fall through + case DPF_USERMARKED|DPF_PURGE: + case DPF_AUTOMARKED|DPF_PURGE: case DPF_MARKED|DPF_PURGE: p->flags &= ~DPF_PURGE; //back to no-change break; @@ -3049,17 +3101,21 @@ static qboolean MD_Key (struct menucustom_s *c, struct menu_s *m, int key, unsig switch (p->flags & (DPF_PURGE|DPF_MARKED)) { case 0: - PM_MarkPackage(p); + PM_MarkPackage(p, DPF_USERMARKED); //now: try to install break; + case DPF_USERMARKED: + case DPF_AUTOMARKED: case DPF_MARKED: p->flags |= DPF_PURGE; //now: re-get despite already having it. if ((p->flags & DPF_CORRUPT) || ((p->flags & DPF_PRESENT) && !PM_PurgeOnDisable(p))) break; //only makes sense if we already have a cached copy that we're not going to use. //fallthrough + case DPF_USERMARKED|DPF_PURGE: + case DPF_AUTOMARKED|DPF_PURGE: case DPF_MARKED|DPF_PURGE: - PM_UnmarkPackage(p); + PM_UnmarkPackage(p, DPF_MARKED); //now: delete if ((p->flags & DPF_CORRUPT) || ((p->flags & DPF_PRESENT) && !PM_PurgeOnDisable(p))) break; //only makes sense if we have a cached/corrupt copy of it already @@ -3088,7 +3144,7 @@ static qboolean MD_Key (struct menucustom_s *c, struct menu_s *m, int key, unsig continue; if (!strcmp(dep->name, dep2->name)) { - PM_UnmarkPackage(p2); + PM_UnmarkPackage(p2, DPF_MARKED); break; } } @@ -3193,18 +3249,18 @@ static void MD_AddItemsToDownloadMenu(menu_t *m) prefixlen = strlen(info->pathprefix); y = 48; - MC_AddCommand(m, 0, 170, y, "Apply", MD_ApplyDownloads); + MC_AddCommand(m, 0, 170, y, "Apply", MD_ApplyDownloads)->common.tooltip = "Enable/Disable/Download/Delete packages to match any changes made (you will be prompted with a list of the changes that will be made)."; y+=8; MC_AddCommand(m, 0, 170, y, "Back", MD_PopMenu); y+=8; if (!prefixlen) { #ifdef WEBCLIENT - MC_AddCommand(m, 0, 170, y, "Mark Updates", MD_MarkUpdatesButton); + MC_AddCommand(m, 0, 170, y, "Mark Updates", MD_MarkUpdatesButton)->common.tooltip = "Select any updated versions of packages that are already installed."; y+=8; #endif - MC_AddCommand(m, 0, 170, y, "Revert Updates", MD_RevertUpdates); + MC_AddCommand(m, 0, 170, y, "Revert Updates", MD_RevertUpdates)->common.tooltip = "Reset selection to only those packages that are currently installed."; y+=8; #ifdef WEBCLIENT @@ -3280,8 +3336,11 @@ static void MD_Download_UpdateStatus(struct menu_s *m) { dlmenu_t *info = m->data; int i; + package_t *p; + unsigned int totalpackages=0, selectedpackages=0, addpackages=0, rempackages=0, downloads=0; + menuoption_t *si; - if (info->downloadablessequence != downloadablessequence) + if (info->downloadablessequence != downloadablessequence || !info->populated) { while(m->options) { @@ -3294,12 +3353,66 @@ static void MD_Download_UpdateStatus(struct menu_s *m) info->downloadablessequence = downloadablessequence; info->populated = false; - MC_AddWhiteText(m, 24, 170, 8, "Downloads", false); - MC_AddWhiteText(m, 16, 170, 24, "^Ue01d^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01f", false); + MC_AddWhiteText(m, 24, 320, 8, "Downloads", false)->text = info->titletext; + MC_AddWhiteText(m, 16, 320, 24, "^Ue01d^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01f", false); //FIXME: should probably reselect the previous selected item. lets just assume everyone uses a mouse... } + for (p = availablepackages; p; p = p->next) + { + if (p->alternative && (p->flags & DPF_HIDDEN)) + p = p->alternative; + + totalpackages++; +#ifdef WEBCLIENT + if (p->download || p->trymirrors) + downloads++; //downloading or pending +#endif + if (p->flags & DPF_MARKED) + { + if (p->flags & DPF_ENABLED) + { + selectedpackages++; + if (p->flags & DPF_PURGE) + { + rempackages++; + addpackages++; + } + } + else + { + selectedpackages++; + if (p->flags & DPF_PURGE) + rempackages++; //adding, but also deleting. how weird is that! + addpackages++; + } + } + else + { + if (p->flags & DPF_ENABLED) + rempackages++; + else + { + if (p->flags & DPF_PURGE) + rempackages++; + } + } + } + + //show status. + if (cls.download) + { //we can actually download more than one thing at a time, but that makes the UI messy, so only show one active download here. + if (cls.download->sizeunknown && cls.download->size == 0) + Q_snprintfz(info->titletext, sizeof(info->titletext), "Downloads (%ukbps - %s)", CL_DownloadRate()/1000, cls.download->localname); + else + Q_snprintfz(info->titletext, sizeof(info->titletext), "Downloads (%u%% %ukbps - %s)", (int)cls.download->percent, CL_DownloadRate()/1000, cls.download->localname); + } + else if (!addpackages && !rempackages) + Q_snprintfz(info->titletext, sizeof(info->titletext), "Downloads (%i of %i)", selectedpackages, totalpackages); + else + Q_snprintfz(info->titletext, sizeof(info->titletext), "Downloads (+%u -%u)", addpackages, rempackages); + if (!info->populated) { for (i = 0; i < numdownloadablelists; i++) @@ -3315,9 +3428,12 @@ static void MD_Download_UpdateStatus(struct menu_s *m) MD_AddItemsToDownloadMenu(m); } - if (m->selecteditem && m->selecteditem->common.type == mt_custom && m->selecteditem->custom.dptr) + si = m->mouseitem; + if (!si) + si = m->selecteditem; + if (si && si->common.type == mt_custom && si->custom.dptr) { - package_t *p = m->selecteditem->custom.dptr; + package_t *p = si->custom.dptr; if (p->previewimage) { shader_t *sh = R_RegisterPic(p->previewimage, NULL); @@ -3346,8 +3462,7 @@ void Menu_DownloadStuff_f (void) if (!*info->pathprefix || !loadedinstalled) PM_UpdatePackageList(false, true); - MC_AddWhiteText(menu, 24, 170, 8, "Downloads", false); - MC_AddWhiteText(menu, 16, 170, 24, "^Ue01d^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01f", false); + info->populated = false; //will add any headers as needed } //should only be called AFTER the filesystem etc is inited. diff --git a/engine/client/m_master.c b/engine/client/m_master.c index eb407f134..51dc1ea83 100644 --- a/engine/client/m_master.c +++ b/engine/client/m_master.c @@ -826,7 +826,7 @@ dojoin: } else if (server && key == 'c' && ctrldown) //copy to clip { - Sys_SaveClipboard(NET_AdrToString(buf, sizeof(buf), &server->adr)); + Sys_SaveClipboard(CBT_CLIPBOARD, NET_AdrToString(buf, sizeof(buf), &server->adr)); return true; } else if (server && (key == 'v' || key == 'c')) //say to current server @@ -840,7 +840,7 @@ dojoin: while((s = strchr(safename, '\n'))) *s = ' '; if (key == 'c') - Sys_SaveClipboard(va("%s - %s\n", server->name, NET_AdrToString(buf, sizeof(buf), &server->adr))); + Sys_SaveClipboard(CBT_CLIPBOARD, va("%s - %s\n", server->name, NET_AdrToString(buf, sizeof(buf), &server->adr))); else if (ctrldown) Cbuf_AddText(va("say_team %s - %s\n", server->name, NET_AdrToString(buf, sizeof(buf), &server->adr)), RESTRICT_LOCAL); else diff --git a/engine/client/m_options.c b/engine/client/m_options.c index ef2f0beef..a743acfb4 100644 --- a/engine/client/m_options.c +++ b/engine/client/m_options.c @@ -834,7 +834,7 @@ const char *presetexec[] = "seta cl_rollangle 0;" "seta cl_bob 0;" "seta cl_sbar 0;" - "seta sv_nqplayerphysics 0;" //server settings in a preset might be bad. + "cvarreset sv_nqplayerphysics;" //server settings in a preset might be bad. "seta cl_demoreel 0;" "seta cl_gibfilter 1;" "if cl_deadbodyfilter == 0 then seta cl_deadbodyfilter 1;" //as useful as 2 is, some mods use death frames for crouching etc. @@ -922,7 +922,7 @@ const char *presetexec[] = "gl_texturemode2d l;" "cl_sbar 0;" "v_viewmodel_quake 0;" //don't move the gun around weirdly. - "sv_nqplayerphysics 0;" + "cvarreset sv_nqplayerphysics;" "cl_demoreel 0;" "r_loadlit 1;" "r_nolerp 0;" @@ -1225,6 +1225,9 @@ void M_Menu_Render_f (void) static const char *logcenteropts[] = {"Off", "Singleplayer", "Always", NULL}; static const char *logcentervalues[] = {"0", "1", "2", NULL}; + static const char *cshiftopts[] = {"Off", "Fullscreen", "Edges", NULL}; + static const char *cshiftvalues[] = {"0", "1", "2", NULL}; + menu_t *menu; extern cvar_t r_novis, cl_item_bobbing, r_waterwarp, r_nolerp, r_noframegrouplerp, r_fastsky, gl_nocolors, gl_lerpimages, r_wateralpha, r_drawviewmodel, gl_cshiftenabled, r_hdr_irisadaptation, scr_logcenterprint, r_fxaa, r_graphics; #ifdef GLQUAKE @@ -1246,7 +1249,7 @@ void M_Menu_Render_f (void) MB_COMBOCVAR("Water Warp", r_waterwarp, warpopts, warpvalues, NULL), MB_SLIDER("Water Alpha", r_wateralpha, 0, 1, 0.1, NULL), MB_SLIDER("Viewmodel Alpha", r_drawviewmodel, 0, 1, 0.1, NULL), - MB_CHECKBOXCVAR("Poly Blending", gl_cshiftenabled, 0), + MB_COMBOCVAR("Screen Tints", gl_cshiftenabled, cshiftopts, cshiftvalues, "Changes how screen flashes should be displayed (otherwise known as polyblends)."), #ifdef QWSKINS MB_CHECKBOXCVAR("Disable Colormap", gl_nocolors, 0), #endif @@ -3738,6 +3741,30 @@ void M_Menu_ModelViewer_f(void) World_RBE_Start(&mv->ragworld); #endif } +static int QDECL CompleteModelViewerList (const char *name, qofs_t flags, time_t mtime, void *parm, searchpathfuncs_t *spath) +{ + struct xcommandargcompletioncb_s *ctx = parm; + const char *ext = COM_GetFileExtension(name, NULL); + if (!strcmp(ext, ".mdl") || !strcmp(ext, ".md2") || !strcmp(ext, ".md3") + || !strcmp(ext, ".iqm") || !strcmp(ext, ".dpm") || !strcmp(ext, ".zym") + || !strcmp(ext, ".psk") || !strcmp(ext, ".md5mesh") || !strcmp(ext, ".md5anim") + || !strcmp(ext, ".bsp") || !strcmp(ext, ".map") || !strcmp(ext, ".hmp") + || !strcmp(ext, ".spr") || !strcmp(ext, ".sp2") || !strcmp(ext, ".spr32")) + { + ctx->cb(name, NULL, NULL, ctx); + } + return true; +} +void M_Menu_ModelViewer_c(int argn, const char *partial, struct xcommandargcompletioncb_s *ctx) +{ + if (argn == 1) + { + COM_EnumerateFiles(va("%s*", partial), CompleteModelViewerList, ctx); + COM_EnumerateFiles(va("%s*/*", partial), CompleteModelViewerList, ctx); + COM_EnumerateFiles(va("%s*/*", partial), CompleteModelViewerList, ctx); + COM_EnumerateFiles(va("%s*/*/*", partial), CompleteModelViewerList, ctx); + } +} #else void M_Menu_ModelViewer_f(void) { diff --git a/engine/client/m_single.c b/engine/client/m_single.c index 64ac420c1..50c1cde5c 100644 --- a/engine/client/m_single.c +++ b/engine/client/m_single.c @@ -38,6 +38,8 @@ static void M_ScanSave(unsigned int slot, const char *name, qboolean savable) char *in, *out, *end; int j; char line[MAX_OSPATH]; + flocation_t loc; + time_t mtime; vfsfile_t *f; int version; @@ -49,12 +51,13 @@ static void M_ScanSave(unsigned int slot, const char *name, qboolean savable) Q_strncpyz (m_saves[slot].time, "", sizeof(m_saves[slot].time)); snprintf (line, sizeof(line), "saves/%s/info.fsv", m_saves[slot].sname); - f = FS_OpenVFS (line, "rb", FS_GAME); - if (!f) + if (!FS_FLocateFile(line, FSLF_DONTREFERENCE|FSLF_IGNOREPURE, &loc)) { //legacy saved games from some other engine snprintf (line, sizeof(line), "%s.sav", m_saves[slot].sname); - f = FS_OpenVFS (line, "rb", FS_GAME); + if (!FS_FLocateFile(line, FSLF_DONTREFERENCE|FSLF_IGNOREPURE, &loc)) + return; //not found } + f = FS_OpenReadLocation(&loc); if (f) { VFS_GETS(f, line, sizeof(line)); @@ -84,8 +87,11 @@ static void M_ScanSave(unsigned int slot, const char *name, qboolean savable) out--; *out = 0; - Q_strncpyz(m_saves[slot].time, line+39, sizeof(m_saves[slot].time)); - + if (strlen(line) > 39) + Q_strncpyz(m_saves[slot].time, line+39, sizeof(m_saves[slot].time)); + else if (FS_GetLocMTime(&loc, &mtime)) + strftime(m_saves[slot].time, sizeof(m_saves[slot].time), "%Y-%m-%d %H:%M:%S", localtime( &mtime )); + // else time unknown, just leave it blank if (version == 5 || version == 6) { diff --git a/engine/client/menu.c b/engine/client/menu.c index 5c70b433f..98012e963 100644 --- a/engine/client/menu.c +++ b/engine/client/menu.c @@ -270,6 +270,7 @@ void M_Menu_Audio_f (void); void M_Menu_Demos_f (void); void M_Menu_Mods_f (void); void M_Menu_ModelViewer_f(void); +void M_Menu_ModelViewer_c(int argn, const char *partial, struct xcommandargcompletioncb_s *ctx); extern menu_t *menu_script; @@ -1234,7 +1235,9 @@ void M_Init_Internal (void) Cmd_AddCommand ("help", M_Menu_Help_f); Cmd_AddCommand ("menu_quit", M_Menu_Quit_f); Cmd_AddCommand ("menu_mods", M_Menu_Mods_f); - Cmd_AddCommand ("modelviewer", M_Menu_ModelViewer_f); +#ifndef MINIMAL + Cmd_AddCommandAD ("modelviewer", M_Menu_ModelViewer_f, M_Menu_ModelViewer_c, "View a model..."); +#endif #ifdef CL_MASTER Cmd_AddCommand ("menu_slist", M_Menu_ServerList2_f); diff --git a/engine/client/merged.h b/engine/client/merged.h index dc63cc4f0..fa119ed2f 100644 --- a/engine/client/merged.h +++ b/engine/client/merged.h @@ -111,7 +111,7 @@ void R2D_ConsoleBackground (int firstline, int lastline, qboolean forceopaque); void R2D_EditorBackground (void); void R2D_Image(float x, float y, float w, float h, float s1, float t1, float s2, float t2, mpic_t *pic); -void R2D_Image2dQuad(vec2_t const*points, vec2_t const*texcoords, mpic_t *pic); +void R2D_Image2dQuad(vec2_t const*points, vec2_t const*texcoords, vec4_t const*rgba, mpic_t *pic); void R2D_ImageColours(float r, float g, float b, float a); void R2D_ImagePaletteColour(unsigned int i, float a); diff --git a/engine/client/pr_csqc.c b/engine/client/pr_csqc.c index c7aaddf4a..09cac603c 100644 --- a/engine/client/pr_csqc.c +++ b/engine/client/pr_csqc.c @@ -734,12 +734,14 @@ static void QCBUILTIN PF_cvar (pubprogfuncs_t *prinst, struct globalvars_s *pr_g if (!strcmp(str, "vid_conwidth")) { - csqc_deprecated("vid_conwidth cvar used"); + if (!csqc_isdarkplaces) //don't warn when its unfixable... + csqc_deprecated("vid_conwidth cvar has aspect issues"); G_FLOAT(OFS_RETURN) = vid.width; } else if (!strcmp(str, "vid_conheight")) { - csqc_deprecated("vid_conheight cvar used"); + if (!csqc_isdarkplaces) + csqc_deprecated("vid_conheight cvar has aspect issues"); G_FLOAT(OFS_RETURN) = vid.height; } else @@ -1806,6 +1808,7 @@ void buildmatricies(void) float modelview[16]; float proj[16]; float ofovx = r_refdef.fov_x,ofovy=r_refdef.fov_y; + float ofovvx = r_refdef.fovv_x,ofovvy=r_refdef.fovv_y; V_ApplyAFov(csqc_playerview); @@ -1826,6 +1829,8 @@ void buildmatricies(void) r_refdef.fov_x = ofovx, r_refdef.fov_y = ofovy; + r_refdef.fovv_x = ofovvx, + r_refdef.fovv_y = ofovvy; } static void QCBUILTIN PF_cs_project (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { @@ -2145,25 +2150,28 @@ void QCBUILTIN PF_R_SetViewFlag(pubprogfuncs_t *prinst, struct globalvars_s *pr_ r_refdef.afov = 0; r_refdef.fov_x = p[0]; r_refdef.fov_y = p[1]; + r_refdef.fovv_x = r_refdef.fovv_y = 0; r_refdef.dirty |= RDFD_FOV; break; case VF_FOVX: r_refdef.afov = 0; r_refdef.fov_x = *p; + r_refdef.fovv_x = r_refdef.fovv_y = 0; r_refdef.dirty |= RDFD_FOV; break; case VF_FOVY: r_refdef.afov = 0; r_refdef.fov_y = *p; + r_refdef.fovv_x = r_refdef.fovv_y = 0; r_refdef.dirty |= RDFD_FOV; break; case VF_AFOV: r_refdef.afov = *p; - r_refdef.fov_x = 0; - r_refdef.fov_y = 0; + r_refdef.fov_x = r_refdef.fov_y = 0; + r_refdef.fovv_x = r_refdef.fovv_y = 0; r_refdef.dirty |= RDFD_FOV; break; @@ -2385,9 +2393,9 @@ static void QCBUILTIN PF_R_RenderScene(pubprogfuncs_t *prinst, struct globalvars r_refdef.playerview = csqc_playerview; + V_ApplyRefdef(); V_CalcGunPositionAngle(csqc_playerview, V_CalcBob(csqc_playerview, true)); - V_ApplyRefdef(); R_RenderView(); R2D_PolyBlend (); @@ -5751,10 +5759,16 @@ static void QCBUILTIN PF_V_CalcRefdef(pubprogfuncs_t *prinst, struct globalvars_ DEAD, INTERMISSION } flags = G_FLOAT(OFS_PARM1);*/ - csqc_deprecated("V_CalcRefdef has too much undefined behaviour.\n"); +// csqc_deprecated("V_CalcRefdef has too much undefined behaviour.\n"); // if (ent->xv->entnum >= 1 && ent->xv->entnum <= MAX_CLIENTS) // CSQC_ChangeLocalPlayer(ent->xv->entnum-1); + /* xonotic requires: + cl_followmodel + cl_smoothviewheight + cl_bobfall + */ + csqc_rebuildmatricies = true; CL_DecayLights (); diff --git a/engine/client/pr_menu.c b/engine/client/pr_menu.c index af76fd06e..211260256 100644 --- a/engine/client/pr_menu.c +++ b/engine/client/pr_menu.c @@ -587,7 +587,7 @@ void QCBUILTIN PF_CL_drawrotpic (pubprogfuncs_t *prinst, struct globalvars_s *pr r2d_be_flags = PF_SelectDPDrawFlag(flag); R2D_ImageColours(rgb[0], rgb[1], rgb[2], alpha); - R2D_Image2dQuad((const vec2_t*)points, (const vec2_t*)tcoords, p); + R2D_Image2dQuad((const vec2_t*)points, (const vec2_t*)tcoords, NULL, p); r2d_be_flags = 0; G_FLOAT(OFS_RETURN) = 1; @@ -659,7 +659,7 @@ void QCBUILTIN PF_CL_drawrotsubpic (pubprogfuncs_t *prinst, struct globalvars_s r2d_be_flags = PF_SelectDPDrawFlag(flag); R2D_ImageColours(rgb[0], rgb[1], rgb[2], alpha); - R2D_Image2dQuad((const vec2_t*)points, (const vec2_t*)tcoords, p); + R2D_Image2dQuad((const vec2_t*)points, (const vec2_t*)tcoords, NULL, p); r2d_be_flags = 0; G_FLOAT(OFS_RETURN) = 1; diff --git a/engine/client/r_2d.c b/engine/client/r_2d.c index ce5a88eda..c730c733c 100644 --- a/engine/client/r_2d.c +++ b/engine/client/r_2d.c @@ -630,7 +630,7 @@ void R2D_Image(float x, float y, float w, float h, float s1, float t1, float s2, return; } - if (draw_active_shader != pic || draw_active_flags != r2d_be_flags || draw_mesh.numvertexes+4 > DRAW_QUADS) + if (draw_active_shader != pic || draw_active_flags != r2d_be_flags || R2D_Flush != R2D_ImageFlush || draw_mesh.numvertexes+4 > DRAW_QUADS) { if (R2D_Flush) R2D_Flush(); @@ -662,7 +662,7 @@ void R2D_Image(float x, float y, float w, float h, float s1, float t1, float s2, draw_mesh.numvertexes += 4; draw_mesh.numindexes += 6; } -void R2D_Image2dQuad(vec2_t const*points, vec2_t const*texcoords, mpic_t *pic) +void R2D_Image2dQuad(vec2_t const*points, vec2_t const*texcoords, vec4_t const*rgba, mpic_t *pic) { int i; if (!pic) @@ -677,7 +677,7 @@ void R2D_Image2dQuad(vec2_t const*points, vec2_t const*texcoords, mpic_t *pic) return; } - if (draw_active_shader != pic || draw_active_flags != r2d_be_flags || draw_mesh.numvertexes+4 > DRAW_QUADS) + if (draw_active_shader != pic || draw_active_flags != r2d_be_flags || R2D_Flush != R2D_ImageFlush || draw_mesh.numvertexes+4 > DRAW_QUADS) { if (R2D_Flush) R2D_Flush(); @@ -694,7 +694,10 @@ void R2D_Image2dQuad(vec2_t const*points, vec2_t const*texcoords, mpic_t *pic) { Vector2Copy(points[i], draw_mesh_xyz[draw_mesh.numvertexes+i]); Vector2Copy(texcoords[i], draw_mesh_st[draw_mesh.numvertexes+i]); - Vector4Copy(draw_active_colour, draw_mesh_colors[draw_mesh.numvertexes+i]); + if (rgba) + Vector4Copy(rgba[i], draw_mesh_colors[draw_mesh.numvertexes+i]); + else + Vector4Copy(draw_active_colour, draw_mesh_colors[draw_mesh.numvertexes+i]); } draw_mesh.numvertexes += 4; @@ -709,7 +712,7 @@ void R2D_FillBlock(float x, float y, float w, float h) pic = shader_draw_fill_trans; else pic = shader_draw_fill; - if (draw_active_shader != pic || draw_active_flags != r2d_be_flags || draw_mesh.numvertexes+4 > DRAW_QUADS) + if (draw_active_shader != pic || draw_active_flags != r2d_be_flags || R2D_Flush != R2D_ImageFlush || draw_mesh.numvertexes+4 > DRAW_QUADS) { if (R2D_Flush) R2D_Flush(); @@ -1014,6 +1017,14 @@ void R2D_Font_AddFontLink(char *buffer, int buffersize, char *fontname) } } } +#else +int R2D_Font_ListSystemFonts(const char *fname, qofs_t fsize, time_t modtime, void *ctx, searchpathfuncs_t *spath) +{ + char tmp[MAX_QPATH]; + COM_StripExtension(fname, tmp, sizeof(tmp)); + Con_Printf("^[/gl_font %s^]\n", tmp); + return true; +} #endif void R2D_Font_Changed(void) { @@ -1049,9 +1060,9 @@ void R2D_Font_Changed(void) if (qrenderer == QR_NONE) return; -#if defined(_WIN32) && !defined(FTE_SDL) && !defined(WINRT) && !defined(_XBOX) if (!strcmp(gl_font.string, "?")) { +#if defined(_WIN32) && !defined(FTE_SDL) && !defined(WINRT) && !defined(_XBOX) BOOL (APIENTRY *pChooseFontW)(LPCHOOSEFONTW) = NULL; dllfunction_t funcs[] = { @@ -1073,7 +1084,7 @@ void R2D_Font_Changed(void) cf.lpLogFont = &lf; Sys_LoadLibrary("comdlg32.dll", funcs); - + if (pChooseFontW && pChooseFontW(&cf)) { char fname[MAX_OSPATH*8]; @@ -1099,8 +1110,11 @@ void R2D_Font_Changed(void) Cvar_Set(&gl_font, fname); } return; - } +#else + Sys_EnumerateFiles("/usr/share/fonts/truetype/", "*/*.ttf", R2D_Font_ListSystemFonts, NULL, NULL); + Cvar_Set(&gl_font, ""); #endif + } font_default = Font_LoadFont(gl_font.string, 8); if (!font_default && *gl_font.string) @@ -1273,15 +1287,79 @@ R_PolyBlend //bright flashes and stuff, game only, doesn't touch sbar void R2D_PolyBlend (void) { - if (!r_refdef.playerview->screentint[3]) - return; + extern cvar_t gl_cshiftborder; + float bordersize = gl_cshiftborder.value; if (r_refdef.flags & RDF_NOWORLDMODEL) return; - R2D_ImageColours (SRGBA(r_refdef.playerview->screentint[0], r_refdef.playerview->screentint[1], r_refdef.playerview->screentint[2], r_refdef.playerview->screentint[3])); - R2D_ScalePic(r_refdef.vrect.x, r_refdef.vrect.y, r_refdef.vrect.width, r_refdef.vrect.height, shader_polyblend); - R2D_ImageColours (1, 1, 1, 1); + + if (bordersize && bordersize < r_refdef.vrect.width && bordersize < r_refdef.vrect.height) + { + vec2_t points[4]; + vec2_t tcoords[4]; + vec4_t colours[4]; + int i; + if (!bordersize) + bordersize = 64; + bordersize = min(bordersize, min(r_refdef.vrect.width, r_refdef.vrect.height)/2); + + for (i = 0; i < 4; i++) + { + Vector4Copy(r_refdef.playerview->bordertint, colours[0]); + Vector4Copy(r_refdef.playerview->bordertint, colours[1]); + Vector4Copy(r_refdef.playerview->bordertint, colours[2]); + Vector4Copy(r_refdef.playerview->bordertint, colours[3]); + switch(i) + { + case 0: //top + Vector2Set(points[0], r_refdef.vrect.x, r_refdef.vrect.y); + Vector2Set(points[1], r_refdef.vrect.x+r_refdef.vrect.width, r_refdef.vrect.y); + Vector2Set(points[2], r_refdef.vrect.x+r_refdef.vrect.width-bordersize, r_refdef.vrect.y+bordersize); + Vector2Set(points[3], r_refdef.vrect.x+bordersize, r_refdef.vrect.y+bordersize); + + colours[2][3] = colours[3][3] = 0; + break; + case 1: //bottom + Vector2Set(points[0], r_refdef.vrect.x+bordersize, r_refdef.vrect.y+r_refdef.vrect.height-bordersize); + Vector2Set(points[1], r_refdef.vrect.x+r_refdef.vrect.width-bordersize, r_refdef.vrect.y+r_refdef.vrect.height-bordersize); + Vector2Set(points[2], r_refdef.vrect.x+r_refdef.vrect.width, r_refdef.vrect.y+r_refdef.vrect.height); + Vector2Set(points[3], r_refdef.vrect.x, r_refdef.vrect.y+r_refdef.vrect.height); + + colours[0][3] = colours[1][3] = 0; + break; + case 2: //left + Vector2Set(points[0], r_refdef.vrect.x, r_refdef.vrect.y); + Vector2Set(points[1], r_refdef.vrect.x+bordersize, r_refdef.vrect.y+bordersize); + Vector2Set(points[2], r_refdef.vrect.x+bordersize, r_refdef.vrect.y+r_refdef.vrect.height-bordersize); + Vector2Set(points[3], r_refdef.vrect.x, r_refdef.vrect.y+r_refdef.vrect.height); + + colours[1][3] = colours[2][3] = 0; + break; + case 3: //right + Vector2Set(points[0], r_refdef.vrect.x+r_refdef.vrect.width-bordersize, r_refdef.vrect.y+bordersize); + Vector2Set(points[1], r_refdef.vrect.x+r_refdef.vrect.width, r_refdef.vrect.y); + Vector2Set(points[2], r_refdef.vrect.x+r_refdef.vrect.width, r_refdef.vrect.y+r_refdef.vrect.height); + Vector2Set(points[3], r_refdef.vrect.x+r_refdef.vrect.width-bordersize, r_refdef.vrect.y+r_refdef.vrect.height-bordersize); + colours[0][3] = colours[3][3] = 0; + break; + } + + Vector2Set(tcoords[0], points[0][0]/64, points[0][1]/64); + Vector2Set(tcoords[1], points[1][0]/64, points[1][1]/64); + Vector2Set(tcoords[2], points[2][0]/64, points[2][1]/64); + Vector2Set(tcoords[3], points[3][0]/64, points[3][1]/64); + + R2D_Image2dQuad((const vec2_t*)points, (const vec2_t*)tcoords, colours, shader_polyblend); + } + } + + if (r_refdef.playerview->screentint[3]) + { + R2D_ImageColours (SRGBA(r_refdef.playerview->screentint[0], r_refdef.playerview->screentint[1], r_refdef.playerview->screentint[2], r_refdef.playerview->screentint[3])); + R2D_ScalePic(r_refdef.vrect.x, r_refdef.vrect.y, r_refdef.vrect.width, r_refdef.vrect.height, shader_polyblend); + R2D_ImageColours (1, 1, 1, 1); + } } //for lack of hardware gamma diff --git a/engine/client/r_surf.c b/engine/client/r_surf.c index 2c2b1d45d..3bbe82090 100644 --- a/engine/client/r_surf.c +++ b/engine/client/r_surf.c @@ -3859,6 +3859,8 @@ int Surf_NewLightmaps(int count, int width, int height, qboolean deluxe) } int Surf_NewExternalLightmaps(int count, char *filepattern, qboolean deluxe) { + unsigned int nulllight = 0xffffffff; + unsigned int nulldeluxe = 0xffff7f7f; int first = numlightmaps; int i; char nname[MAX_QPATH]; @@ -3891,6 +3893,13 @@ int Surf_NewExternalLightmaps(int count, char *filepattern, qboolean deluxe) TEXASSIGN(lightmap[i]->lightmap_texture, R_LoadHiResTexture(nname, NULL, (r_lightmap_nearest.ival?IF_NEAREST:IF_LINEAR)|IF_NOMIPMAP)); if (lightmap[i]->lightmap_texture->status == TEX_LOADING) COM_WorkerPartialSync(lightmap[i]->lightmap_texture, &lightmap[i]->lightmap_texture->status, TEX_LOADING); + if (lightmap[i]->lightmap_texture->status == TEX_FAILED) + { + if ((i&1) && deluxe) + lightmap[i]->lightmap_texture = R_LoadReplacementTexture("*nulldeluxe", NULL, IF_LOADNOW, &nulldeluxe, 1, 1, TF_RGBX32); + else + lightmap[i]->lightmap_texture = R_LoadReplacementTexture("*nulllight", NULL, IF_LOADNOW, &nulllight, 1, 1, TF_RGBX32); + } lightmap[i]->width = lightmap[i]->lightmap_texture->width; lightmap[i]->height = lightmap[i]->lightmap_texture->height; } diff --git a/engine/client/render.h b/engine/client/render.h index 59d76f0e5..7e88c3d04 100644 --- a/engine/client/render.h +++ b/engine/client/render.h @@ -584,6 +584,7 @@ qbyte *ReadJPEGFile(qbyte *infile, int length, int *width, int *height); qbyte *ReadPNGFile(qbyte *buf, int length, int *width, int *height, const char *name); qbyte *ReadPCXPalette(qbyte *buf, int len, qbyte *out); void Image_ResampleTexture (unsigned *in, int inwidth, int inheight, unsigned *out, int outwidth, int outheight); +void Image_ResampleTexture8 (unsigned char *in, int inwidth, int inheight, unsigned char *out, int outwidth, int outheight); void BoostGamma(qbyte *rgba, int width, int height, uploadfmt_t fmt); void SaturateR8G8B8(qbyte *data, int size, float sat); diff --git a/engine/client/renderer.c b/engine/client/renderer.c index 4f9567249..bd403ac72 100644 --- a/engine/client/renderer.c +++ b/engine/client/renderer.c @@ -124,7 +124,6 @@ cvar_t r_wireframe = CVARFD ("r_wireframe", "0", cvar_t r_wireframe_smooth = CVAR ("r_wireframe_smooth", "0"); cvar_t r_refract_fbo = CVARD ("r_refract_fbo", "1", "Use an fbo for refraction. If 0, just renders as a portal and uses a copy of the current framebuffer."); cvar_t r_refractreflect_scale = CVARD ("r_refractreflect_scale", "0.5", "Use a different scale for refraction and reflection texturemaps. Because $reasons."); -cvar_t gl_miptexLevel = CVAR ("gl_miptexLevel", "0"); cvar_t r_drawviewmodel = CVARF ("r_drawviewmodel", "1", CVAR_ARCHIVE); cvar_t r_drawviewmodelinvis = CVAR ("r_drawviewmodelinvis", "0"); cvar_t r_dynamic = CVARFD ("r_dynamic", IFMINIMAL("0","1"), @@ -430,7 +429,7 @@ cvar_t r_shadows = CVARFD ("r_shadows", "0", CVAR_ARCHIVE, "Draw basic blo cvar_t r_showbboxes = CVARD("r_showbboxes", "0", "Debugging. Shows bounding boxes. 1=ssqc, 2=csqc. Red=solid, Green=stepping/toss/bounce, Blue=onground."); cvar_t r_showfields = CVARD("r_showfields", "0", "Debugging. Shows entity fields boxes (entity closest to crosshair). 1=ssqc, 2=csqc."); cvar_t r_showshaders = CVARD("r_showshaders", "0", "Debugging. Shows the name of the (worldmodel) shader being pointed to."); -cvar_t r_lightprepass_cvar = CVARFD("r_lightprepass", "0", CVAR_ARCHIVE, "Experimental. Attempt to use a different lighting mechanism. Requires vid_reload to take effect."); +cvar_t r_lightprepass_cvar = CVARFD("r_lightprepass", "0", CVAR_ARCHIVE, "Experimental. Attempt to use a different lighting mechanism (aka: deferred lighting). Requires vid_reload to take effect."); int r_lightprepass; cvar_t r_shadow_bumpscale_basetexture = CVARD ("r_shadow_bumpscale_basetexture", "0", "bumpyness scaler for generation of fallback normalmap textures from models"); @@ -981,7 +980,6 @@ void Renderer_Init(void) Cvar_Register (&r_clear, GLRENDEREROPTIONS); Cvar_Register (&gl_max_size, GLRENDEREROPTIONS); Cvar_Register (&gl_maxdist, GLRENDEREROPTIONS); - Cvar_Register (&gl_miptexLevel, GRAPHICALNICETIES); Cvar_Register (&gl_texturemode, GLRENDEREROPTIONS); Cvar_Register (&gl_texturemode2d, GLRENDEREROPTIONS); Cvar_Register (&r_font_linear, GLRENDEREROPTIONS); diff --git a/engine/client/snd_al.c b/engine/client/snd_al.c index c4a730a2c..9ed64ec71 100644 --- a/engine/client/snd_al.c +++ b/engine/client/snd_al.c @@ -383,7 +383,7 @@ static void PrintALError(char *string) Con_Printf("OpenAL - %s: %x: %s\n",string,err,text); } -qboolean OpenAL_LoadCache(unsigned int *bufptr, sfxcache_t *sc, float volume) +static qboolean OpenAL_LoadCache(unsigned int *bufptr, sfxcache_t *sc, float volume) { unsigned int fmt; unsigned int size; @@ -1421,7 +1421,7 @@ sounddriver_t OPENAL_Output = #if defined(VOICECHAT) -qboolean OpenAL_InitCapture(void) +static qboolean OpenAL_InitCapture(void) { if (!OpenAL_InitLibrary()) return false; @@ -1445,7 +1445,7 @@ qboolean OpenAL_InitCapture(void) return palcGetIntegerv&&palcCaptureOpenDevice&&palcCaptureStart&&palcCaptureSamples&&palcCaptureStop&&palcCaptureCloseDevice; } -qboolean QDECL OPENAL_Capture_Enumerate (void (QDECL *callback) (const char *drivername, const char *devicecode, const char *readablename)) +static qboolean QDECL OPENAL_Capture_Enumerate (void (QDECL *callback) (const char *drivername, const char *devicecode, const char *readablename)) { const char *devnames; if (!OpenAL_InitCapture()) @@ -1460,7 +1460,7 @@ qboolean QDECL OPENAL_Capture_Enumerate (void (QDECL *callback) (const char *dri return true; } //fte's capture api specifies mono 16. -void *QDECL OPENAL_Capture_Init (int samplerate, const char *device) +static void *QDECL OPENAL_Capture_Init (int samplerate, const char *device) { #ifndef OPENAL_STATIC if (!device) //no default devices please, too buggy for that. @@ -1475,12 +1475,12 @@ void *QDECL OPENAL_Capture_Init (int samplerate, const char *device) return palcCaptureOpenDevice(device, samplerate, AL_FORMAT_MONO16, 0.5*samplerate); } -void QDECL OPENAL_Capture_Start (void *ctx) +static void QDECL OPENAL_Capture_Start (void *ctx) { ALCdevice *device = ctx; palcCaptureStart(device); } -unsigned int QDECL OPENAL_Capture_Update (void *ctx, unsigned char *buffer, unsigned int minbytes, unsigned int maxbytes) +static unsigned int QDECL OPENAL_Capture_Update (void *ctx, unsigned char *buffer, unsigned int minbytes, unsigned int maxbytes) { #define samplesize sizeof(short) ALCdevice *device = ctx; @@ -1491,12 +1491,12 @@ unsigned int QDECL OPENAL_Capture_Update (void *ctx, unsigned char *buffer, unsi palcCaptureSamples(device, (ALCvoid *)buffer, avail); return avail * samplesize; } -void QDECL OPENAL_Capture_Stop (void *ctx) +static void QDECL OPENAL_Capture_Stop (void *ctx) { ALCdevice *device = ctx; palcCaptureStop(device); } -void QDECL OPENAL_Capture_Shutdown (void *ctx) +static void QDECL OPENAL_Capture_Shutdown (void *ctx) { ALCdevice *device = ctx; palcCaptureCloseDevice(device); diff --git a/engine/client/snd_linux.c b/engine/client/snd_linux.c index 6625d6330..6aeb601a6 100644 --- a/engine/client/snd_linux.c +++ b/engine/client/snd_linux.c @@ -514,7 +514,7 @@ static qboolean QDECL OSS_Capture_Enumerate (void (QDECL *callback) (const char //SNDCTL_CARDINFO return false; } -void *OSS_Capture_Init(int rate, const char *snddev) +static void *OSS_Capture_Init(int rate, const char *snddev) { int tmp; intptr_t fd; @@ -555,26 +555,26 @@ void *OSS_Capture_Init(int rate, const char *snddev) fd++; return (void*)fd; } -void OSS_Capture_Start(void *ctx) +static void OSS_Capture_Start(void *ctx) { /*oss will automagically restart it when we next read*/ } -void OSS_Capture_Stop(void *ctx) +static void OSS_Capture_Stop(void *ctx) { intptr_t fd = ((intptr_t)ctx)-1; ioctl(fd, SNDCTL_DSP_RESET, NULL); } -void OSS_Capture_Shutdown(void *ctx) +static void OSS_Capture_Shutdown(void *ctx) { intptr_t fd = ((intptr_t)ctx)-1; close(fd); } -unsigned int OSS_Capture_Update(void *ctx, unsigned char *buffer, unsigned int minbytes, unsigned int maxbytes) +static unsigned int OSS_Capture_Update(void *ctx, unsigned char *buffer, unsigned int minbytes, unsigned int maxbytes) { intptr_t fd = ((intptr_t)ctx)-1; ssize_t res; diff --git a/engine/client/sys_droid.c b/engine/client/sys_droid.c index b36155a37..36bb880c7 100644 --- a/engine/client/sys_droid.c +++ b/engine/client/sys_droid.c @@ -511,20 +511,16 @@ void Sys_CloseTerminal(void) { } -#define SYS_CLIPBOARD_SIZE 256 +#define SYS_CLIPBOARD_SIZE 256 static char clipboard_buffer[SYS_CLIPBOARD_SIZE] = {0}; -char *Sys_GetClipboard(void) +void Sys_Clipboard_PasteText(clipboardtype_t cbt, void (*callback)(void *cb, char *utf8), void *ctx) { - return clipboard_buffer; + callback(ctx, clipboard_buffer); } -void Sys_CloseClipboard(char *bf) +void Sys_SaveClipboard(clipboardtype_t cbt, char *text) { + Q_strncpyz(clipboard_buffer, text, SYS_CLIPBOARD_SIZE); } -void Sys_SaveClipboard(char *text) -{ - Q_strncpyz(clipboard_buffer, text, SYS_CLIPBOARD_SIZE); -} - int Sys_EnumerateFiles (const char *gpath, const char *match, int (*func)(const char *, qofs_t, time_t mtime, void *, searchpathfuncs_t *), void *parm, searchpathfuncs_t *spath) { diff --git a/engine/client/sys_linux.c b/engine/client/sys_linux.c index 811ba09b2..5fe5aa4fd 100644 --- a/engine/client/sys_linux.c +++ b/engine/client/sys_linux.c @@ -312,24 +312,30 @@ static void Sys_Register_File_Associations_f(void) { char *exe = realpath(host_parms.argv[0], NULL); char *basedir = realpath(com_gamepath, NULL); + char *iconname = fs_manifest->installation; const char *desktopfile = "[Desktop Entry]\n" "Type=Application\n" "Encoding=UTF-8\n" - "Name=FTE QuakeWorld\n" //FIXME: needs to come from the manifest + "Name=%s\n" "Comment=Awesome First Person Shooter\n" //again should be a manicfest item "Exec=\"%s\" %%u\n" //FIXME: FS_GetManifestArgs! etc! "Path=%s\n" - "Icon=quake\n" //FIXME: fix me! + "Icon=%s\n" "Terminal=false\n" "Categories=Game;\n" - "MimeType=application/x-quakeworlddemo;x-scheme-handler/qw;\n" + "MimeType=" "application/x-quakeworlddemo;" "x-scheme-handler/qw;\n" ; + if (!strcmp(iconname, "afterquake") || !strcmp(iconname, "nq")) //hacks so that we don't need to create icons. + iconname = "quake"; desktopfile = va(desktopfile, - exe, basedir); + fs_manifest->formalname?fs_manifest->formalname:fs_manifest->installation, + exe, basedir, iconname); free(exe); free(basedir); - FS_WriteFile(va("%s/applications/fteqw.desktop", xdgbase), desktopfile, strlen(desktopfile), FS_SYSTEM); + FS_WriteFile(va("%s/applications/fte-%s.desktop", xdgbase, fs_manifest->installation), desktopfile, strlen(desktopfile), FS_SYSTEM); + + //FIXME: read icon.png and write it to ~/.local/share/icons/hicolor/WxH/apps/foo.png } //we need to set some default applications. @@ -374,7 +380,7 @@ static void Sys_Register_File_Associations_f(void) if (foundassoc) { //if we found it, or somewhere to insert it, then insert it. VFS_WRITE(out, in, foundassoc-in); - VFS_PRINTF(out, "x-scheme-handler/qw=fteqw.desktop\n"); + VFS_PRINTF(out, "x-scheme-handler/qw=fte-%s.desktop\n", fs_manifest->installation); VFS_WRITE(out, foundassoc, insize - (foundassoc-in)); } else @@ -384,7 +390,7 @@ static void Sys_Register_File_Associations_f(void) if (!foundassoc) { //if file not found, or no appropriate section, just concat it on the end. VFS_PRINTF(out, "[Added Associations]\n"); - VFS_PRINTF(out, "x-scheme-handler/qw=fteqw.desktop\n"); + VFS_PRINTF(out, "x-scheme-handler/qw=fte-%s.desktop\n", fs_manifest->installation); } VFS_FLUSH(out); VFS_CLOSE(out); @@ -418,9 +424,20 @@ void Sys_Error (const char *error, ...) fprintf(stderr, "Error: %s\n", string); Host_Shutdown (); + #ifdef USE_LIBTOOL lt_dlexit(); #endif + + fflush(stdout); + fflush(stderr); + + if (!isatty(STDERR_FILENO)) + { //if we're a graphical x11 program then its quite likely that we have no stdout with the user never knowing why the game just disappeared + //the crash could have come from malloc failures, this means we can't really depend upon xlib + //but we can start some other program to display the message. + execl("/usr/bin/xmessage", "xmessage", string, NULL); + } exit (1); } @@ -436,24 +453,6 @@ void Sys_Warn (char *warning, ...) fprintf(stderr, "Warning: %s", string); } -/* -============ -Sys_FileTime - -returns -1 if not present -============ -*/ -int Sys_FileTime (char *path) -{ - struct stat buf; - - if (stat (path,&buf) == -1) - return -1; - - return buf.st_mtime; -} - - void Sys_mkdir (const char *path) { mkdir (path, 0760); @@ -507,7 +506,7 @@ int Sys_DebugLog(char *file, char *fmt, ...) return 1; } -int Sys_EnumerateFiles2 (const char *truepath, int apathofs, const char *match, int (*func)(const char *, qofs_t, time_t modtime, void *, searchpathfuncs_t *), void *parm, searchpathfuncs_t *spath) +static int Sys_EnumerateFiles2 (const char *truepath, int apathofs, const char *match, int (*func)(const char *, qofs_t, time_t modtime, void *, searchpathfuncs_t *), void *parm, searchpathfuncs_t *spath) { DIR *dir; char file[MAX_OSPATH]; @@ -593,7 +592,7 @@ int Sys_EnumerateFiles2 (const char *truepath, int apathofs, const char *match, if (!func(file, st.st_size, st.st_mtime, parm, spath)) { - Con_DPrintf("giving up on search after finding %s\n", file); +// Con_DPrintf("giving up on search after finding %s\n", file); closedir(dir); return false; } @@ -861,7 +860,7 @@ char *Sys_ConsoleInput(void) // if (!qrenderer) { - len = read (0, text, sizeof(text)); + len = read (STDIN_FILENO, text, sizeof(text)); if (len < 1) return NULL; @@ -911,10 +910,12 @@ int main (int c, const char **v) #endif #ifdef __linux__ - uid_t ruid, euid, suid; - getresuid(&ruid, &euid, &suid); - if (!ruid || !euid || !suid) - printf("WARNING: you should NOT be running this as root!\n"); + { + uid_t ruid, euid, suid; + getresuid(&ruid, &euid, &suid); + if (!ruid || !euid || !suid) + printf("WARNING: you should NOT be running this as root!\n"); + } #endif #ifdef __linux__ @@ -1059,7 +1060,7 @@ qboolean Sys_GetDesktopParameters(int *width, int *height, int *bpp, int *refres return false; #else return X11_GetDesktopParameters(width, height, bpp, refreshrate); - +/* Display *xtemp; int scr; @@ -1078,6 +1079,7 @@ qboolean Sys_GetDesktopParameters(int *width, int *height, int *bpp, int *refres XCloseDisplay(xtemp); return true; +*/ #endif } @@ -1085,15 +1087,12 @@ qboolean Sys_GetDesktopParameters(int *width, int *height, int *bpp, int *refres #define SYS_CLIPBOARD_SIZE 256 static char clipboard_buffer[SYS_CLIPBOARD_SIZE] = {0}; -char *Sys_GetClipboard(void) { - return clipboard_buffer; -} - -void Sys_CloseClipboard(char *bf) +void Sys_Clipboard_PasteText(clipboardtype_t cbt, void (*callback)(void *cb, char *utf8), void *ctx) { + callback(ctx, clipboard_buffer); } -void Sys_SaveClipboard(char *text) { +void Sys_SaveClipboard(clipboardtype_t cbt, char *text) { Q_strncpyz(clipboard_buffer, text, SYS_CLIPBOARD_SIZE); } #endif diff --git a/engine/client/sys_morphos.c b/engine/client/sys_morphos.c index f694e9dad..936c8f25c 100755 --- a/engine/client/sys_morphos.c +++ b/engine/client/sys_morphos.c @@ -375,17 +375,15 @@ void Sys_Init() { } -char *Sys_GetClipboard(void) +#define SYS_CLIPBOARD_SIZE 256 +static char clipboard_buffer[SYS_CLIPBOARD_SIZE] = {0}; +void Sys_Clipboard_PasteText(clipboardtype_t cbt, void (*callback)(void *cb, char *utf8), void *ctx) { - return 0; + callback(ctx, clipboard_buffer); } - -void Sys_CloseClipboard(char *buf) -{ -} - -void Sys_SaveClipboard(char *text) +void Sys_SaveClipboard(clipboardtype_t cbt, char *text) { + Q_strncpyz(clipboard_buffer, text, SYS_CLIPBOARD_SIZE); } qboolean Sys_InitTerminal() diff --git a/engine/client/sys_sdl.c b/engine/client/sys_sdl.c index ea169206b..b27ceeda9 100644 --- a/engine/client/sys_sdl.c +++ b/engine/client/sys_sdl.c @@ -582,30 +582,21 @@ qboolean Sys_GetDesktopParameters(int *width, int *height, int *bpp, int *refres #if SDL_MAJOR_VERSION >= 2 //probably could include 1.3 #include -char *Sys_GetClipboard(void) +void Sys_Clipboard_PasteText(clipboardtype_t cbt, void (*callback)(void *cb, char *utf8), void *ctx) { - return SDL_GetClipboardText(); + callback(ctx, SDL_GetClipboardText()); } -void Sys_CloseClipboard(char *bf) -{ - SDL_free(bf); -} -void Sys_SaveClipboard(char *text) +void Sys_SaveClipboard(clipboardtype_t cbt, char *text) { SDL_SetClipboardText(text); } #else static char *clipboard_buffer; -char *Sys_GetClipboard(void) +void Sys_Clipboard_PasteText(clipboardtype_t cbt, void (*callback)(void *cb, char *utf8), void *ctx) { - return clipboard_buffer; + callback(ctx, clipboard_buffer); } - -void Sys_CloseClipboard(char *bf) -{ -} - -void Sys_SaveClipboard(char *text) +void Sys_SaveClipboard(clipboardtype_t cbt, char *text) { free(clipboard_buffer); clipboard_buffer = strdup(text); diff --git a/engine/client/sys_win.c b/engine/client/sys_win.c index f2964a87b..fc630dbf6 100644 --- a/engine/client/sys_win.c +++ b/engine/client/sys_win.c @@ -74,15 +74,11 @@ void *RT_GetCoreWindow(int *width, int *height){return NULL;} //I already wrote void D3D11_DoResize(int newwidth, int newheight); //already written, call if resized since getcorewindow static char *clippy; -char *Sys_GetClipboard(void) +void Sys_Clipboard_PasteText(clipboardtype_t cbt, void (*callback)(void *cb, char *utf8), void *ctx) { - return Z_StrDup(clippy); + callback(ctx, clippy); } -void Sys_CloseClipboard(char *bf) -{ - Z_Free(bf); -} -void Sys_SaveClipboard(char *text) +void Sys_SaveClipboard(clipboardtype_t cbt, char *text) { Z_Free(clippy); clippy = Z_StrDup(text); @@ -852,7 +848,7 @@ DWORD CrashExceptionHandler (qboolean iswatchdog, DWORD exceptionCode, LPEXCEPTI if (logpos+1 >= sizeof(stacklog)) break; } - Sys_SaveClipboard(stacklog+logstart); + Sys_SaveClipboard(CBT_CLIPBOARD, stacklog+logstart); #ifdef _MSC_VER if (MessageBoxA(0, stacklog, "KABOOM!", MB_ICONSTOP|MB_YESNO) != IDYES) { @@ -1414,6 +1410,8 @@ int Sys_EnumerateFiles (const char *gpath, const char *match, int (QDECL *func)( { char fullmatch[MAX_OSPATH]; int start; + if (!gpath) + gpath = ""; if (strlen(gpath) + strlen(match) + 2 > MAX_OSPATH) return 1; @@ -1838,10 +1836,10 @@ double Sys_DoubleTime (void) ///////////////////////////////////////////////////////////// //clipboard -HANDLE clipboardhandle; -char *cliputf8; -char *Sys_GetClipboard(void) +void Sys_Clipboard_PasteText(clipboardtype_t cbt, void (*callback)(void *cb, char *utf8), void *ctx) { + HANDLE clipboardhandle; + char *cliputf8; if (OpenClipboard(NULL)) { //windows programs interpret CF_TEXT as ansi (aka: gibberish) @@ -1882,6 +1880,10 @@ char *Sys_GetClipboard(void) utf8 += c; } *utf8 = 0; + callback(ctx, cliputf8); + free(cliputf8); + GlobalUnlock(clipboardhandle); + CloseClipboard(); return cliputf8; } @@ -1913,7 +1915,8 @@ char *Sys_GetClipboard(void) utf8 += c; } *utf8 = 0; - return cliputf8; + callback(ctx, cliputf8); + free(cliputf8); } //failed at the last hurdle @@ -1922,23 +1925,8 @@ char *Sys_GetClipboard(void) } CloseClipboard(); } - - clipboardhandle = NULL; - - return NULL; } -void Sys_CloseClipboard(char *bf) -{ - if (clipboardhandle) - { - free(cliputf8); - cliputf8 = NULL; - GlobalUnlock(clipboardhandle); - CloseClipboard(); - clipboardhandle = NULL; - } -} -void Sys_SaveClipboard(char *text) +void Sys_SaveClipboard(clipboardtype_t cbt, char *text) { HANDLE glob; char *temp; diff --git a/engine/client/sys_xdk.c b/engine/client/sys_xdk.c index 1d9aa802f..ae4ff0c46 100644 --- a/engine/client/sys_xdk.c +++ b/engine/client/sys_xdk.c @@ -148,18 +148,15 @@ int Sys_EnumerateFiles (const char *gpath, const char *match, int (QDECL *func)( } /*consoles don't tend to need system clipboards, so this is fully internal to our engine*/ -#define SYS_CLIPBOARD_SIZE 256 +#define SYS_CLIPBOARD_SIZE 256 static char clipboard_buffer[SYS_CLIPBOARD_SIZE] = {0}; -char *Sys_GetClipboard(void) +void Sys_Clipboard_PasteText(clipboardtype_t cbt, void (*callback)(void *cb, char *utf8), void *ctx) { - return clipboard_buffer; + callback(ctx, clipboard_buffer); } -void Sys_CloseClipboard(char *bf) +void Sys_SaveClipboard(clipboardtype_t cbt, char *text) { -} -void Sys_SaveClipboard(char *text) -{ - Q_strncpyz(clipboard_buffer, text, SYS_CLIPBOARD_SIZE); + Q_strncpyz(clipboard_buffer, text, SYS_CLIPBOARD_SIZE); } /*dynamic library stubs*/ diff --git a/engine/client/textedit.c b/engine/client/textedit.c index 0869a04b3..cc1c99892 100644 --- a/engine/client/textedit.c +++ b/engine/client/textedit.c @@ -236,16 +236,16 @@ static void Con_Editor_DeleteSelection(console_t *con) con->userline = con->selstartline; con->useroffset = con->selstartoffset; } -static void Con_Editor_Paste(console_t *con) +static void Con_Editor_DoPaste(void *ctx, char *utf8) { - char *clipText = Sys_GetClipboard(); - if (clipText) + console_t *con = ctx; + if (utf8) { conchar_t buffer[8192], *end; char *s, *nl; - if (*clipText && (con->flags & CONF_KEEPSELECTION)) + if (*utf8 && (con->flags & CONF_KEEPSELECTION)) Con_Editor_DeleteSelection(con); - for(s = clipText; ; ) + for(s = utf8; ; ) { nl = strchr(s, '\n'); if (nl) @@ -263,9 +263,12 @@ static void Con_Editor_Paste(console_t *con) else break; } - Sys_CloseClipboard(clipText); } } +static void Con_Editor_Paste(console_t *con) +{ + Sys_Clipboard_PasteText(CBT_CLIPBOARD, Con_Editor_DoPaste, con); +} static void Con_Editor_Save(console_t *con) { vfsfile_t *file; @@ -606,7 +609,7 @@ qboolean Con_Editor_Key(console_t *con, unsigned int unicode, int key) char *buffer = Con_CopyConsole(con, true, false); //don't keep markup if we're copying to the clipboard if (buffer) { - Sys_SaveClipboard(buffer); + Sys_SaveClipboard(CBT_CLIPBOARD, buffer); Z_Free(buffer); } break; @@ -791,7 +794,7 @@ qboolean Con_Editor_Key(console_t *con, unsigned int unicode, int key) char *buffer = Con_CopyConsole(con, true, false); //don't keep markup if we're copying to the clipboard if (buffer) { - Sys_SaveClipboard(buffer); + Sys_SaveClipboard(CBT_CLIPBOARD, buffer); Z_Free(buffer); } break; diff --git a/engine/client/view.c b/engine/client/view.c index ba02cf81b..062bee343 100644 --- a/engine/client/view.c +++ b/engine/client/view.c @@ -53,21 +53,21 @@ cvar_t vsec_yaw[SIDEVIEWS] = {CVAR("v2_yaw", "180"), CVAR("v3_yaw", "90"), CV #endif cvar_t cl_rollspeed = CVAR("cl_rollspeed", "200"); -cvar_t cl_rollangle = CVAR("cl_rollangle", "2.0"); +cvar_t cl_rollangle = CVARD("cl_rollangle", "2.0", "Controls how much the view should tilt while strafing."); cvar_t v_deathtilt = CVAR("v_deathtilt", "1"); -cvar_t cl_bob = CVAR("cl_bob","0.02"); +cvar_t cl_bob = CVARD("cl_bob","0.02", "Controls how much the camera position should bob up down as the player runs around."); cvar_t cl_bobcycle = CVAR("cl_bobcycle","0.6"); cvar_t cl_bobup = CVAR("cl_bobup","0.5"); -cvar_t cl_bobmodel = CVAR("cl_bobmodel", "0"); +cvar_t cl_bobmodel = CVARD("cl_bobmodel", "0", "Controls whether the viewmodel should bob up and down as the player runs around."); cvar_t cl_bobmodel_side = CVAR("cl_bobmodel_side", "0.15"); cvar_t cl_bobmodel_up = CVAR("cl_bobmodel_up", "0.06"); cvar_t cl_bobmodel_speed = CVAR("cl_bobmodel_speed", "7"); -cvar_t v_kicktime = CVAR("v_kicktime", "0.5"); -cvar_t v_kickroll = CVAR("v_kickroll", "0.6"); -cvar_t v_kickpitch = CVAR("v_kickpitch", "0.6"); +cvar_t v_kicktime = CVARD("v_kicktime", "0.5", "This controls how long viewangle changes from taking damage will last."); +cvar_t v_kickroll = CVARD("v_kickroll", "0.6", "This controls part of the strength of viewangle changes from taking damage."); +cvar_t v_kickpitch = CVARD("v_kickpitch", "0.6", "This controls part of the strength of viewangle changes from taking damage."); cvar_t v_iyaw_cycle = CVAR("v_iyaw_cycle", "2"); cvar_t v_iroll_cycle = CVAR("v_iroll_cycle", "0.5"); @@ -88,18 +88,19 @@ cvar_t crosshairimage = CVAR("crosshairimage", ""); cvar_t crosshairalpha = CVAR("crosshairalpha", "1"); cvar_t gl_cshiftpercent = CVAR("gl_cshiftpercent", "100"); -cvar_t gl_cshiftenabled = CVARF("gl_polyblend", "1", CVAR_ARCHIVE); +cvar_t gl_cshiftenabled = CVARFD("gl_polyblend", "1", CVAR_ARCHIVE, "Controls whether temporary whole-screen colour changes should be honoured or not. Change gl_cshiftpercent if you want to adjust the intensity.\nThis does not affect v_cshift commands sent from the server."); +cvar_t gl_cshiftborder = CVARD("gl_polyblend_edgesize", "128", "This constrains colour shifts to the edge of the screen, with the value specifying the size of those borders."); -cvar_t v_bonusflash = CVAR("v_bonusflash", "1"); +cvar_t v_bonusflash = CVARD("v_bonusflash", "1", "Controls the strength of temporary screen flashes when picking up items (gl_polyblend must be enabled)."); -cvar_t v_contentblend = CVARF("v_contentblend", "1", CVAR_ARCHIVE); -cvar_t v_damagecshift = CVAR("v_damagecshift", "1"); -cvar_t v_quadcshift = CVAR("v_quadcshift", "1"); -cvar_t v_suitcshift = CVAR("v_suitcshift", "1"); -cvar_t v_ringcshift = CVAR("v_ringcshift", "1"); -cvar_t v_pentcshift = CVAR("v_pentcshift", "1"); -cvar_t v_gunkick = CVAR("v_gunkick", "0"); -cvar_t v_gunkick_q2 = CVAR("v_gunkick_q2", "1"); +cvar_t v_contentblend = CVARFD("v_contentblend", "1", CVAR_ARCHIVE, "Controls the strength of underwater colour tints (gl_polyblend must be enabled)."); +cvar_t v_damagecshift = CVARD("v_damagecshift", "1", "Controls the strength of damage-taken colour tints (gl_polyblend must be enabled)."); +cvar_t v_quadcshift = CVARD("v_quadcshift", "1", "Controls the strength of quad-damage colour tints (gl_polyblend must be enabled)."); +cvar_t v_suitcshift = CVARD("v_suitcshift", "1", "Controls the strength of envirosuit colour tints (gl_polyblend must be enabled)."); +cvar_t v_ringcshift = CVARD("v_ringcshift", "1", "Controls the strength of ring-of-invisibility colour tints (gl_polyblend must be enabled)."); +cvar_t v_pentcshift = CVARD("v_pentcshift", "1", "Controls the strength of pentagram-of-protection colour tints (gl_polyblend must be enabled)."); +cvar_t v_gunkick = CVARD("v_gunkick", "0", "Controls the strength of view angle changes when firing weapons."); +cvar_t v_gunkick_q2 = CVARD("v_gunkick_q2", "1", "Controls the strength of view angle changes when firing weapons (in Quake2)."); cvar_t v_viewmodel_quake = CVARD("r_viewmodel_quake", "0", "Controls whether to use weird viewmodel movements from vanilla quake."); //name comes from MarkV. cvar_t v_viewheight = CVAR("v_viewheight", "0"); @@ -469,9 +470,9 @@ void V_ParseDamage (playerview_t *pv) #endif if (v_damagecshift.value >= 0) - count *= v_damagecshift.value; - - pv->cshifts[CSHIFT_DAMAGE].percent += 3*count; + pv->cshifts[CSHIFT_DAMAGE].percent += 3*count*v_damagecshift.value; + else + pv->cshifts[CSHIFT_DAMAGE].percent += 3*count; if (pv->cshifts[CSHIFT_DAMAGE].percent < 0) pv->cshifts[CSHIFT_DAMAGE].percent = 0; if (pv->cshifts[CSHIFT_DAMAGE].percent > 150) @@ -761,6 +762,7 @@ void V_CalcBlend (float *hw_blend) { pv = &cl.playerview[seat]; memset(pv->screentint, 0, sizeof(pv->screentint)); + memset(pv->bordertint, 0, sizeof(pv->bordertint)); //don't apply it to the server, we'll blend the two later if the user has no hardware gamma (if they do have it, we use just the server specified value) This way we avoid winnt users having a cheat with flashbangs and stuff. for (j=0 ; j 1) + if (gl_cshiftenabled.value) + blend = pv->bordertint; //show the colours only on the borders so we don't blind ourselves + else if (j == CSHIFT_BONUS || j == CSHIFT_DAMAGE || gl_nohwblend.ival || !r2d_canhwgamma || cl.splitclients > 1) blend = pv->screentint; else //powerup or contents? blend = hw_blend; @@ -812,6 +816,7 @@ void V_CalcBlend (float *hw_blend) { pv = &cl.playerview[seat]; memset(pv->screentint, 0, sizeof(pv->screentint)); + memset(pv->bordertint, 0, sizeof(pv->bordertint)); } if (hw_blend[3] > 1) hw_blend[3] = 1; @@ -888,6 +893,15 @@ void V_UpdatePalette (qboolean force) ramps[0][i] = gammatable[ir]<<8; ramps[1][i] = gammatable[ig]<<8; ramps[2][i] = gammatable[ib]<<8; + +#ifdef _WIN32 + //'In fact, any entry in the ramp must be within 32768 of the identity value' + //so lets try to bound it so that it doesn't randomly fail. + ir = (i<<8)|i; + ramps[0][i] = bound(ir-32767, ramps[0][i], ir+32767); + ramps[1][i] = bound(ir-32767, ramps[1][i], ir+32767); + ramps[2][i] = bound(ir-32767, ramps[2][i], ir+32767); +#endif } if (qrenderer) @@ -1010,6 +1024,9 @@ void V_CalcGunPositionAngle (playerview_t *pv, float bob) xyspeed = VectorLength(xyvel); //FIXME: clamp + //FIXME: cl_followmodel should lag the viewmodel's position relative to the view + //FIXME: cl_leanmodel should lag the viewmodel's angles relative to the view + if (cl_bobmodel.value) { //bobmodel causes the viewmodel to bob relative to the view. float s = pv->bobtime * cl_bobmodel_speed.value, v; @@ -1018,8 +1035,6 @@ void V_CalcGunPositionAngle (playerview_t *pv, float bob) v = xyspeed * 0.01 * cl_bobmodel_up.value * /*cl_viewmodel_scale.value * */cos(2*s); VectorMA(pv->vw_origin, v, pv->vw_axis[2], pv->vw_origin); } - //FIXME: cl_followmodel should lag the viewmodel's position relative to the view - //FIXME: cl_leanmodel should lag the viewmodel's angles relative to the view // fudge position around to keep amount of weapon visible @@ -1902,14 +1917,22 @@ void R_DrawNameTags(void) if (cls.protocol == CP_QUAKE2) return; //FIXME: q2 has its own ent logic, which messes stuff up here. - if (r_showfields.ival && cls.allow_cheats) + if (r_showfields.ival) { world_t *w = NULL; wedict_t *e; vec3_t org; vec3_t screenspace; vec3_t diff; - if ((r_showfields.ival & 3) == 1) + if (!cls.allow_cheats) + { + vec2_t scale = {8,8}; + float x = 0.5*r_refdef.vrect.width+r_refdef.vrect.x; + float y = (1-0.5)*r_refdef.vrect.height+r_refdef.vrect.y; + R_DrawTextField(x, y, vid.width - x, vid.height - y, "r_showfields requires sv_cheats 1", CON_WHITEMASK, CPRINT_TALIGN|CPRINT_LALIGN, font_console, scale); + w = NULL; + } + else if ((r_showfields.ival & 3) == 1) { #ifndef CLIENTONLY w = &sv.world; @@ -1955,7 +1978,6 @@ void R_DrawNameTags(void) y = (1-screenspace[1])*r_refdef.vrect.height+r_refdef.vrect.y; R_DrawTextField(x, y, vid.width - x, vid.height - y, entstr, CON_WHITEMASK, CPRINT_TALIGN|CPRINT_LALIGN, font_default, scale); } - } } } @@ -2008,7 +2030,6 @@ void R_DrawNameTags(void) y = (1-screenspace[1])*r_refdef.vrect.height+r_refdef.vrect.y; R_DrawTextField(x, y, vid.width - x, vid.height - y, entstr, CON_WHITEMASK, CPRINT_TALIGN|CPRINT_LALIGN, font_console, scale); } - } } } @@ -2447,6 +2468,7 @@ void V_Init (void) Cvar_Register (&cl_crossy, VIEWVARS); Cvar_Register (&gl_cshiftpercent, VIEWVARS); Cvar_Register (&gl_cshiftenabled, VIEWVARS); + Cvar_Register (&gl_cshiftborder, VIEWVARS); Cvar_Register (&cl_rollspeed, VIEWVARS); Cvar_Register (&cl_rollangle, VIEWVARS); diff --git a/engine/common/cmd.c b/engine/common/cmd.c index 4f7d82939..566fe9901 100644 --- a/engine/common/cmd.c +++ b/engine/common/cmd.c @@ -110,7 +110,7 @@ void Cmd_AddMacro(char *s, char *(*f)(void), int disputableintentions) macro_count++; } -char *TP_MacroString (char *s, int *newaccesslevel, int *len) +static char *TP_MacroString (char *s, int *newaccesslevel, int *len) { int i; macro_command_t *macro; @@ -131,7 +131,7 @@ char *TP_MacroString (char *s, int *newaccesslevel, int *len) return NULL; } -void Cmd_MacroList_f (void) +static void Cmd_MacroList_f (void) { int i; @@ -182,7 +182,7 @@ next frame. This allows commands like: bind g "impulse 5 ; +attack ; wait ; -attack ; impulse 2" ============ */ -void Cmd_Wait_f (void) +static void Cmd_Wait_f (void) { if (cmd_blockwait) return; @@ -416,7 +416,7 @@ start: return text; } -char *Cbuf_StripText(int level) //remove all text in the command buffer and return it (so it can be readded later) +static char *Cbuf_StripText(int level) //remove all text in the command buffer and return it (so it can be readded later) { char *buf; buf = (char*)Z_Malloc(cmd_text[level].buf.cursize+1); @@ -626,7 +626,7 @@ void Cmd_StuffCmds (void) Cmd_Exec_f =============== */ -void Cmd_Exec_f (void) +static void Cmd_Exec_f (void) { char *f, *s; char name[256]; @@ -818,6 +818,9 @@ void Cmd_Exec_f (void) if (cvar_watched) Cbuf_InsertText (va("echo BEGIN %s", buf), level, true); BZ_Free(f); + + if (level != Cmd_ExecLevel) + Cbuf_ExecuteLevel(level); } static int QDECL CompleteExecList (const char *name, qofs_t flags, time_t mtime, void *parm, searchpathfuncs_t *spath) @@ -826,7 +829,7 @@ static int QDECL CompleteExecList (const char *name, qofs_t flags, time_t mtime, ctx->cb(name, NULL, NULL, ctx); return true; } -void Cmd_Exec_c(int argn, const char *partial, struct xcommandargcompletioncb_s *ctx) +static void Cmd_Exec_c(int argn, const char *partial, struct xcommandargcompletioncb_s *ctx) { if (argn == 1) { @@ -844,7 +847,7 @@ Just prints the rest of the line to the console =============== */ char *TP_ParseFunChars (char *s); -void Cmd_Echo_f (void) +static void Cmd_Echo_f (void) { char text[4096]; char extext[4096], *t; @@ -962,7 +965,7 @@ Creates a new command that executes a command string (possibly ; seperated) =============== */ -void Cmd_Alias_f (void) +static void Cmd_Alias_f (void) { cmdalias_t *a, *b; char cmd[65536]; @@ -1165,7 +1168,7 @@ static void Cmd_AliasEdit_f (void) } #endif -void Cmd_DeleteAlias(const char *name) +/*static void Cmd_DeleteAlias(const char *name) { cmdalias_t *a, **link; for (link = &cmd_alias; (a = *link); link = &(*link)->next) @@ -1178,7 +1181,7 @@ void Cmd_DeleteAlias(const char *name) return; } } -} +}*/ char *Cmd_AliasExist(const char *name, int restrictionlevel) { @@ -1198,7 +1201,7 @@ char *Cmd_AliasExist(const char *name, int restrictionlevel) return NULL; } -void Cmd_AliasLevel_f (void) +static void Cmd_AliasLevel_f (void) { cmdalias_t *a; char *s = Cmd_Argv(1); @@ -1248,7 +1251,7 @@ void Cmd_AliasLevel_f (void) } //lists commands, also prints restriction level -void Cmd_AliasList_f (void) +static void Cmd_AliasList_f (void) { cmdalias_t *cmd; int num=0; @@ -1277,7 +1280,7 @@ void Cmd_AliasList_f (void) Con_Printf("\n"); } -void Alias_WriteAliases (vfsfile_t *f) +static void Alias_WriteAliases (vfsfile_t *f) { const char *s; cmdalias_t *cmd; @@ -1455,7 +1458,7 @@ void Cmd_ShiftArgs (int ammount, qboolean expandstring) } } -const char *Cmd_ExpandCvar(char *cvarterm, int maxaccesslevel, int *newaccesslevel, qboolean enclosed, int *len) +static const char *Cmd_ExpandCvar(char *cvarterm, int maxaccesslevel, int *newaccesslevel, qboolean enclosed, int *len) { const char *ret = NULL; char *fixup = NULL, fixval=0, *t; @@ -1724,7 +1727,7 @@ char *Cmd_ExpandString (const char *data, char *dest, int destlen, int *accessle return dest; } -char *Cmd_ExpandStringArguments (char *data, char *dest, int destlen) +static char *Cmd_ExpandStringArguments (char *data, char *dest, int destlen) { char c; int quotes = 0; @@ -2004,7 +2007,7 @@ void Cmd_RemoveCommands (xcommand_t function) } } -void Cmd_RestrictCommand_f (void) +static void Cmd_RestrictCommand_f (void) { cmdalias_t *a; cvar_t *v; @@ -2208,7 +2211,7 @@ fte_inlinestatic int Q_tolower(char c) c -= ('a' - 'A'); return c; } -void Cmd_Complete_CheckArg(const char *value, const char *desc, const char *repl, struct xcommandargcompletioncb_s *vctx) //compare cumulative strings and join the result +static void Cmd_Complete_CheckArg(const char *value, const char *desc, const char *repl, struct xcommandargcompletioncb_s *vctx) //compare cumulative strings and join the result { struct cmdargcompletion_ctx_s *ctx = (struct cmdargcompletion_ctx_s*)vctx; cmd_completion_t *res = ctx->res; @@ -2292,7 +2295,7 @@ void Cmd_Complete_CheckArg(const char *value, const char *desc, const char *repl res->num++; } -void Cmd_Complete_Check(const char *check, cmd_completion_t *res, const char *desc) //compare cumulative strings and join the result +static void Cmd_Complete_Check(const char *check, cmd_completion_t *res, const char *desc) //compare cumulative strings and join the result { const char *c; char *p; @@ -2323,7 +2326,7 @@ void Cmd_Complete_Check(const char *check, cmd_completion_t *res, const char *de res->completions[res->num].repl = NULL; res->num++; } -void Cmd_Complete_End(cmd_completion_t *c) +static void Cmd_Complete_End(cmd_completion_t *c) { size_t u; for (u = 0; u < c->num; u++) @@ -2347,7 +2350,7 @@ void Cmd_Complete_End(cmd_completion_t *c) Z_Free(c->partial); c->partial = NULL; } -int QDECL Cmd_Complete_Sort(const void *a, const void *b) +static int QDECL Cmd_Complete_Sort(const void *a, const void *b) { //FIXME: its possible that they're equal (eg: filesystem searches). we should strip one in that case, but gah. const struct cmd_completion_opt_s *c1 = a, *c2 = b; return Q_strcasecmp(c1->text, c2->text); @@ -2501,7 +2504,7 @@ char *Cmd_CompleteCommand (const char *partial, qboolean fullonly, qboolean case //lists commands, also prints restriction level -void Cmd_List_f (void) +static void Cmd_List_f (void) { cmd_function_t *cmd; int num=0; @@ -2519,7 +2522,7 @@ void Cmd_List_f (void) } //I'm not personally keen on this name, but its somewhat standard in both DP and suse (which lh uses, hence why DP uses that name). oh well. -void Cmd_Apropos_f (void) +static void Cmd_Apropos_f (void) { extern cvar_group_t *cvar_groups; cmd_function_t *cmd; @@ -2615,7 +2618,7 @@ void Cmd_ForwardToServer (void) } // don't forward the first argument -void Cmd_ForwardToServer_f (void) +static void Cmd_ForwardToServer_f (void) { if (cls.state == ca_disconnected) { @@ -3383,7 +3386,7 @@ qboolean If_EvaluateBoolean(const char *text, int restriction) return ret; } -void Cbuf_ExecBlock(int level) +static void Cbuf_ExecBlock(int level) { char *remainingcbuf; char *exectext = NULL; @@ -3450,7 +3453,7 @@ void Cbuf_ExecBlock(int level) Z_Free(remainingcbuf); } -void Cbuf_SkipBlock(int level) +static void Cbuf_SkipBlock(int level) { char *line, *end; line = Cbuf_GetNext(level, false); @@ -3602,7 +3605,7 @@ skipblock: If_Token_Clear(ts); } -void Cmd_Vstr_f( void ) +static void Cmd_Vstr_f( void ) { char *v; @@ -3616,7 +3619,7 @@ void Cmd_Vstr_f( void ) Cbuf_InsertText(v, Cmd_ExecLevel, true); } -void Cmd_toggle_f(void) +static void Cmd_toggle_f(void) { cvar_t *v; if (Cmd_Argc()<2) @@ -3652,7 +3655,7 @@ static void Cmd_Set_c(int argn, const char *partial, struct xcommandargcompletio } } -void Cmd_set_f(void) +static void Cmd_set_f(void) { void *mark; cvar_t *var; @@ -3832,7 +3835,7 @@ void Cmd_set_f(void) If_Token_Clear(mark); } -void Cvar_Inc_f (void) +static void Cvar_Inc_f (void) { int c; cvar_t *var; @@ -3895,7 +3898,7 @@ void Cvar_ParseWatches(void) } } -void Cvar_Watch_f(void) +static void Cvar_Watch_f(void) { char *cvarname = Cmd_Argv(1); cvar_t *var; @@ -3940,7 +3943,7 @@ void Cvar_Watch_f(void) } } -void Cmd_WriteConfig_f(void) +static void Cmd_WriteConfig_f(void) { vfsfile_t *f; char *filename; @@ -4023,13 +4026,13 @@ void Cmd_WriteConfig_f(void) Con_Printf ("Wrote %s\n",sysname); } -void Cmd_Reset_f(void) +static void Cmd_Reset_f(void) { } #ifndef SERVERONLY // dumps current console contents to a text file -void Cmd_Condump_f(void) +static void Cmd_Condump_f(void) { vfsfile_t *f; char *filename; diff --git a/engine/common/com_mesh.c b/engine/common/com_mesh.c index 4fd4334f0..342c4981b 100644 --- a/engine/common/com_mesh.c +++ b/engine/common/com_mesh.c @@ -34,7 +34,7 @@ cvar_t r_meshpitch = CVARCD ("r_meshpitch", "-1", r_meshpitch_callback, "S #endif #ifndef SERVERONLY -void Mod_UpdateCRC(void *ctx, void *data, size_t a, size_t b) +static void Mod_UpdateCRC(void *ctx, void *data, size_t a, size_t b) { char st[40]; Q_snprintfz(st, sizeof(st), "%d", (int) a); @@ -530,7 +530,7 @@ static void Alias_TransformVerticies_VNST(const float *bonepose, int vertcount, //converts one entire frame to another skeleton type //only writes to destbuffer if absolutely needed -const float *Alias_ConvertBoneData(skeltype_t sourcetype, const float *sourcedata, size_t bonecount, galiasbone_t *bones, skeltype_t desttype, float *destbuffer, float *destbufferalt, size_t destbonecount) +static const float *Alias_ConvertBoneData(skeltype_t sourcetype, const float *sourcedata, size_t bonecount, galiasbone_t *bones, skeltype_t desttype, float *destbuffer, float *destbufferalt, size_t destbonecount) { int i; if (sourcetype == desttype) @@ -1171,7 +1171,7 @@ static int Alias_FindRawSkelData(galiasinfo_t *inf, framestate_t *fstate, skelle return value is the lastbone argument, or less if the model simply doesn't have that many bones. _always_ writes into result */ -int Alias_BlendBoneData(galiasinfo_t *inf, framestate_t *fstate, float *result, skeltype_t skeltype, int firstbone, int lastbone) +static int Alias_BlendBoneData(galiasinfo_t *inf, framestate_t *fstate, float *result, skeltype_t skeltype, int firstbone, int lastbone) { skellerps_t lerps[FS_COUNT], *lerp; size_t bone, endbone = 0; @@ -1216,7 +1216,7 @@ int Alias_BlendBoneData(galiasinfo_t *inf, framestate_t *fstate, float *result, only writes targetbuffer if needed. the return value is the only real buffer result. assumes that all blended types are the same. probably buggy, but meh. */ -const float *Alias_GetBoneInformation(galiasinfo_t *inf, framestate_t *framestate, skeltype_t targettype, float *targetbuffer, float *targetbufferalt, size_t maxbufferbones) +static const float *Alias_GetBoneInformation(galiasinfo_t *inf, framestate_t *framestate, skeltype_t targettype, float *targetbuffer, float *targetbufferalt, size_t maxbufferbones) { skellerps_t lerps[FS_COUNT], *lerp; size_t numgroups; @@ -1661,7 +1661,7 @@ qboolean Alias_GAliasBuildMesh(mesh_t *mesh, vbo_t **vbop, galiasinfo_t *inf, in #endif usebones = false; - if (meshcache.ent == e) + if (0)//meshcache.ent == e) { if (meshcache.vertgroup == inf->shares_verts && meshcache.ent == e && usebones == meshcache.usebones) { @@ -1898,25 +1898,24 @@ qboolean Alias_GAliasBuildMesh(mesh_t *mesh, vbo_t **vbop, galiasinfo_t *inf, in if (g1 == g2) //lerping within group is only done if not changing group { lerp = fg1time*g1->rate; - if (lerp < 0) lerp = 0; //hrm - frame1=lerp; + frame1=floor(lerp); frame2=frame1+1; lerp-=frame1; if (r_noframegrouplerp.ival) lerp = 0; if (g1->loop) { - frame1=frame1%g1->numposes; - frame2=frame2%g1->numposes; + frame1=frame1%g1->numposes;if (frame1 < 0)frame1 += g1->numposes; + frame2=frame2%g1->numposes;if (frame2 < 0)frame2 += g1->numposes; } else { - frame1=(frame1>g1->numposes-1)?g1->numposes-1:frame1; - frame2=(frame2>g1->numposes-1)?g1->numposes-1:frame2; + frame1=bound(0, frame1, g1->numposes-1); + frame2=bound(0, frame2, g1->numposes-1); } } else //don't bother with a four way lerp. Yeah, this will produce jerkyness with models with just framegroups. - { + { //FIXME: find the two poses with the strongest influence. frame1=0; frame2=0; } @@ -2162,7 +2161,7 @@ static float PlaneNearest(vec3_t normal, vec3_t mins, vec3_t maxs) } void CLQ1_DrawLine(shader_t *shader, vec3_t v1, vec3_t v2, float r, float g, float b, float a); -qboolean Mod_Trace_Trisoup(vecV_t *posedata, index_t *indexes, int numindexes, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, trace_t *trace) +static qboolean Mod_Trace_Trisoup(vecV_t *posedata, index_t *indexes, int numindexes, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, trace_t *trace) { qboolean impacted = false; int i, j; @@ -2339,7 +2338,7 @@ qboolean Mod_Trace_Trisoup(vecV_t *posedata, index_t *indexes, int numindexes, v } //The whole reason why model loading is supported in the server. -qboolean Mod_Trace(model_t *model, int forcehullnum, framestate_t *framestate, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, qboolean capsule, unsigned int contentsmask, trace_t *trace) +static qboolean Mod_Trace(model_t *model, int forcehullnum, framestate_t *framestate, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, qboolean capsule, unsigned int contentsmask, trace_t *trace) { galiasinfo_t *mod = Mod_Extradata(model); @@ -2560,7 +2559,7 @@ static int R_FindTriangleWithEdge (index_t *indexes, int numtris, int start, int } #endif -void Mod_CompileTriangleNeighbours(model_t *loadmodel, galiasinfo_t *galias) +static void Mod_CompileTriangleNeighbours(model_t *loadmodel, galiasinfo_t *galias) { #ifndef SERVERONLY if (Sh_StencilShadowsActive()) @@ -2709,7 +2708,7 @@ static qboolean Mod_ParseModelEvents(model_t *mod, galiasanimation_t *anims, uns return true; } -void Mod_DefaultMesh(galiasinfo_t *galias, const char *name, unsigned int index) +static void Mod_DefaultMesh(galiasinfo_t *galias, const char *name, unsigned int index) { Q_strncpyz(galias->surfacename, name, sizeof(galias->surfacename)); Q_strncpyz(galias->csurface.name, COM_SkipPath(name), sizeof(galias->csurface.name)); @@ -2735,10 +2734,10 @@ void Mod_DestroyMesh(galiasinfo_t *galias) #endif } -void Mod_GenerateMeshVBO(galiasinfo_t *galias) +#ifndef SERVERONLY +static void Mod_GenerateMeshVBO(galiasinfo_t *galias) //vec3_t *vc, vec2_t *tc, vec3_t *nv, vec3_t *sv, vec3_t *tv, index_t *idx, int numidx, int numverts) { -#ifndef SERVERONLY #ifdef NONSKELETALMODELS int i, p; galiasanimation_t *group = galias->ofsanimations; @@ -2817,13 +2816,13 @@ void Mod_GenerateMeshVBO(galiasinfo_t *galias) } #endif BE_VBO_Finish(&vboctx, galias->ofs_indexes, sizeof(*galias->ofs_indexes) * galias->numindexes, &galias->vboindicies, &galias->vbomem, &galias->ebomem); -#endif } +#endif #ifdef NONSKELETALMODELS //called for non-skeletal model formats. -void Mod_BuildTextureVectors(galiasinfo_t *galias) +static void Mod_BuildTextureVectors(galiasinfo_t *galias) //vec3_t *vc, vec2_t *tc, vec3_t *nv, vec3_t *sv, vec3_t *tv, index_t *idx, int numidx, int numverts) { #ifndef SERVERONLY @@ -2867,7 +2866,7 @@ void Mod_BuildTextureVectors(galiasinfo_t *galias) #ifndef SERVERONLY //looks for foo.md3_0.skin files, for dp compat //also try foo_0.skin, because people appear to use that too. *sigh*. -int Mod_CountSkinFiles(model_t *mod) +static int Mod_CountSkinFiles(model_t *mod) { int i; char skinfilename[MAX_QPATH]; @@ -3930,7 +3929,7 @@ static qboolean QDECL Mod_LoadQ1Model (model_t *mod, void *buffer, size_t fsize) return true; } -int Mod_ReadFlagsFromMD1(char *name, int md3version) +static int Mod_ReadFlagsFromMD1(char *name, int md3version) { int result = 0; size_t fsize; @@ -4022,7 +4021,7 @@ static void Q2MD2_LoadSkins(galiasinfo_t *galias, model_t *mod, md2_t *pq2inmode } #define MD2_MAX_TRIANGLES 4096 -qboolean QDECL Mod_LoadQ2Model (model_t *mod, void *buffer, size_t fsize) +static qboolean QDECL Mod_LoadQ2Model (model_t *mod, void *buffer, size_t fsize) { #ifndef SERVERONLY dmd2stvert_t *pinstverts; @@ -4472,6 +4471,7 @@ qboolean Mod_GetTag(model_t *model, int tagnum, framestate_t *fstate, float *res lerps[0].lerpcount = 1; lerps[0].firstbone = 0; lerps[0].endbone = fstate->bonecount; + lerps[0].skeltype = fstate->skeltype; numbonegroups = 1; } @@ -4487,6 +4487,7 @@ qboolean Mod_GetTag(model_t *model, int tagnum, framestate_t *fstate, float *res lerps[0].lerpcount = 1; lerps[0].firstbone = 0; lerps[0].endbone = inf->numbones; + lerps[0].skeltype = SKEL_ABSOLUTE; numbonegroups = 1; } @@ -5029,7 +5030,7 @@ typedef struct { } md3Shader_t; //End of Tenebrae 'assistance' -qboolean QDECL Mod_LoadQ3Model(model_t *mod, void *buffer, size_t fsize) +static qboolean QDECL Mod_LoadQ3Model(model_t *mod, void *buffer, size_t fsize) { #ifndef SERVERONLY galiasskin_t *skin; @@ -5066,6 +5067,10 @@ qboolean QDECL Mod_LoadQ3Model(model_t *mod, void *buffer, size_t fsize) md3Header_t *header; md3Surface_t *surf; galiasinfo_t *galias; + unsigned int numposes, numverts; + + frameinfo_t *framegroups; + unsigned int numgroups; header = buffer; @@ -5082,25 +5087,34 @@ qboolean QDECL Mod_LoadQ3Model(model_t *mod, void *buffer, size_t fsize) min[0] = min[1] = min[2] = 0; max[0] = max[1] = max[2] = 0; + framegroups = ParseFrameInfo(mod->name, &numgroups); + surf = (md3Surface_t *)((qbyte *)header + LittleLong(header->ofsSurfaces)); for (s = 0; s < LittleLong(header->numSurfaces); s++) { if (LittleLong(surf->ident) != MD3_IDENT) Con_Printf(CON_WARNING "Warning: md3 sub-surface doesn't match ident\n"); - size = sizeof(galiasinfo_t) + sizeof(galiasanimation_t)*LittleLong(header->numFrames); + + if (!framegroups) + numgroups = LittleLong(header->numFrames); + numposes = LittleLong(surf->numFrames); + numverts = LittleLong(surf->numVerts); + + size = sizeof(galiasinfo_t) + sizeof(galiasanimation_t)*numgroups; galias = ZG_Malloc(&mod->memgroup, size); Mod_DefaultMesh(galias, surf->name, s); - galias->ofsanimations = (galiasanimation_t*)(galias+1); //frame groups - galias->numanimations = LittleLong(header->numFrames); - galias->numverts = LittleLong(surf->numVerts); + galias->ofsanimations = group = (galiasanimation_t*)(galias+1); //frame groups + galias->numanimations = numgroups; + galias->numverts = numverts; galias->numindexes = LittleLong(surf->numTriangles)*3; - galias->shares_verts = s; + galias->shares_verts = s; //with itself, so no sharing. if (parent) parent->nextsurf = galias; else root = galias; parent = galias; + //load the texcoords #ifndef SERVERONLY st_array = ZG_Malloc(&mod->memgroup, sizeof(vec2_t)*galias->numindexes); galias->ofs_st_array = st_array; @@ -5112,6 +5126,7 @@ qboolean QDECL Mod_LoadQ3Model(model_t *mod, void *buffer, size_t fsize) } #endif + //load the index data indexes = ZG_Malloc(&mod->memgroup, sizeof(*indexes)*galias->numindexes); galias->ofs_indexes = indexes; intris = (md3Triangle_t *)((qbyte*)surf + LittleLong(surf->ofsTriangles)); @@ -5122,28 +5137,61 @@ qboolean QDECL Mod_LoadQ3Model(model_t *mod, void *buffer, size_t fsize) indexes[i*3+2] = LittleLong(intris[i].indexes[2]); } - group = (galiasanimation_t *)(galias+1); + //figure out where we're putting the pose data + size = sizeof(galiaspose_t) + sizeof(vecV_t)*numverts; +#ifndef SERVERONLY + size += 3*sizeof(vec3_t)*numverts; +#endif + size *= numposes; + pose = (galiaspose_t *)ZG_Malloc(&mod->memgroup, size); + verts = (vecV_t*)(pose+numposes); +#ifndef SERVERONLY + normals = (vec3_t*)(verts + numverts*numposes); + svector = (vec3_t*)(normals + numverts*numposes); + tvector = (vec3_t*)(svector + numverts*numposes); +#endif + + if (framegroups) + { //group the poses into animations. + for (i = 0; i < numgroups; i++) + { + int first = framegroups[i].firstpose, count = framegroups[i].posecount; + if (first >= numposes) //bound the numbers. + first = numposes-1; + if (first < 0) + first = 0; + if (count > numposes-first) + count = numposes-first; + if (count < 0) + count = 0; + Q_snprintfz(group->name, sizeof(group->name), "%s", framegroups[i].name); + group->numposes = count; + group->rate = framegroups[i].fps; + group->poseofs = pose + first; + group->loop = framegroups[i].loop; + group->events = NULL; + group++; + } + } + else + { //raw poses, no animations. + for (i = 0; i < numgroups; i++) + { + Q_snprintfz(group->name, sizeof(group->name), "frame%i", i); + group->numposes = 1; + group->rate = 1; + group->poseofs = pose + i; + group->loop = false; + group->events = NULL; + group++; + } + } + + //load in that per-pose data invert = (md3XyzNormal_t *)((qbyte*)surf + LittleLong(surf->ofsXyzNormals)); - for (i = 0; i < LittleLong(surf->numFrames); i++) + for (i = 0; i < numposes; i++) { - int size = sizeof(galiaspose_t) + sizeof(vecV_t)*LittleLong(surf->numVerts); -#ifndef SERVERONLY - size += 3*sizeof(vec3_t)*LittleLong(surf->numVerts); -#endif - pose = (galiaspose_t *)ZG_Malloc(&mod->memgroup, size); - - verts = (vecV_t*)(pose+1); - pose->ofsverts = verts; -#ifndef SERVERONLY - normals = (vec3_t*)(verts + LittleLong(surf->numVerts)); - pose->ofsnormals = normals; - svector = normals + LittleLong(surf->numVerts); - pose->ofssvector = svector; - tvector = svector + LittleLong(surf->numVerts); - pose->ofstvector = tvector; -#endif - - for (j = 0; j < LittleLong(surf->numVerts); j++) + for (j = 0; j < numverts; j++) { #ifndef SERVERONLY lat = (float)invert[j].latlong[0] * (2 * M_PI)*(1.0 / 255.0); @@ -5170,14 +5218,19 @@ qboolean QDECL Mod_LoadQ3Model(model_t *mod, void *buffer, size_t fsize) pose->scale_origin[1] = 0; pose->scale_origin[2] = 0; - snprintf(group->name, sizeof(group->name)-1, "frame%i", i); - - group->numposes = 1; - group->rate = 1; - group->poseofs = pose; - - group++; invert += LittleLong(surf->numVerts); + + pose->ofsverts = verts; + verts += numverts; +#ifndef SERVERONLY + pose->ofsnormals = normals; + normals += numverts; + pose->ofssvector = svector; + svector += numverts; + pose->ofstvector = tvector; + tvector += numverts; +#endif + pose++; } #ifndef SERVERONLY @@ -5339,7 +5392,7 @@ typedef struct zymvertex_s //this can generate multiple meshes (one for each shader). //but only one set of transforms are ever generated. -qboolean QDECL Mod_LoadZymoticModel(model_t *mod, void *buffer, size_t fsize) +static qboolean QDECL Mod_LoadZymoticModel(model_t *mod, void *buffer, size_t fsize) { #ifndef SERVERONLY galiasskin_t *skin; @@ -5703,7 +5756,7 @@ typedef struct pskanimkeys_s } pskanimkeys_t; -qboolean QDECL Mod_LoadPSKModel(model_t *mod, void *buffer, size_t fsize) +static qboolean QDECL Mod_LoadPSKModel(model_t *mod, void *buffer, size_t fsize) { pskchunk_t *chunk; unsigned int pos = 0; @@ -6360,7 +6413,7 @@ typedef struct dpmvertex_s // immediately followed by 1 or more dpmbonevert_t structures } dpmvertex_t; -qboolean QDECL Mod_LoadDarkPlacesModel(model_t *mod, void *buffer, size_t fsize) +static qboolean QDECL Mod_LoadDarkPlacesModel(model_t *mod, void *buffer, size_t fsize) { #ifndef SERVERONLY galiasskin_t *skin; @@ -7128,7 +7181,7 @@ static void Mod_CleanWeights(const char *modelname, size_t numverts, vec4_t *owe Con_DPrintf(CON_ERROR"%s has invalid vertex weights. Verticies will probably be attached to the wrong bones\n", modelname); } -galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, const char *buffer, size_t fsize) +static galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, const char *buffer, size_t fsize) { const struct iqmheader *h = (struct iqmheader *)buffer; const struct iqmmesh *mesh; @@ -7669,14 +7722,7 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, const char *buffer, size_t fsi return gai; } -qboolean Mod_ParseIQMAnim(char *buffer, galiasinfo_t *prototype, void**poseofs, galiasanimation_t *gat) -{ - return false; -} - - - -qboolean QDECL Mod_LoadInterQuakeModel(model_t *mod, void *buffer, size_t fsize) +static qboolean QDECL Mod_LoadInterQuakeModel(model_t *mod, void *buffer, size_t fsize) { galiasinfo_t *root; struct iqmheader *h = (struct iqmheader *)buffer; @@ -7711,7 +7757,7 @@ qboolean QDECL Mod_LoadInterQuakeModel(model_t *mod, void *buffer, size_t fsize) #ifdef MD5MODELS -qboolean Mod_ParseMD5Anim(model_t *mod, char *buffer, galiasinfo_t *prototype, void**poseofs, galiasanimation_t *gat) +static qboolean Mod_ParseMD5Anim(model_t *mod, char *buffer, galiasinfo_t *prototype, void**poseofs, galiasanimation_t *gat) { #define MD5ERROR0PARAM(x) { Con_Printf(CON_ERROR x "\n"); return false; } #define MD5ERROR1PARAM(x, y) { Con_Printf(CON_ERROR x "\n", y); return false; } @@ -7921,7 +7967,7 @@ qboolean Mod_ParseMD5Anim(model_t *mod, char *buffer, galiasinfo_t *prototype, v #undef EXPECT } -galiasinfo_t *Mod_ParseMD5MeshModel(model_t *mod, char *buffer, char *modname) +static galiasinfo_t *Mod_ParseMD5MeshModel(model_t *mod, char *buffer, char *modname) { #define MD5ERROR0PARAM(x) { Con_Printf(CON_ERROR x "\n"); return NULL; } #define MD5ERROR1PARAM(x, y) { Con_Printf(CON_ERROR x "\n", y); return NULL; } @@ -8282,7 +8328,7 @@ galiasinfo_t *Mod_ParseMD5MeshModel(model_t *mod, char *buffer, char *modname) #undef EXPECT } -qboolean QDECL Mod_LoadMD5MeshModel(model_t *mod, void *buffer, size_t fsize) +static qboolean QDECL Mod_LoadMD5MeshModel(model_t *mod, void *buffer, size_t fsize) { galiasinfo_t *root; @@ -8318,7 +8364,7 @@ clampgroup test/idle1.md5anim frames test/idle1.md5anim */ -qboolean QDECL Mod_LoadCompositeAnim(model_t *mod, void *buffer, size_t fsize) +static qboolean QDECL Mod_LoadCompositeAnim(model_t *mod, void *buffer, size_t fsize) { int i; diff --git a/engine/common/com_phys_ode.c b/engine/common/com_phys_ode.c index a1f52067f..503054d8c 100644 --- a/engine/common/com_phys_ode.c +++ b/engine/common/com_phys_ode.c @@ -2546,12 +2546,12 @@ static void VARGS nearCallback (void *data, dGeomID o1, dGeomID o2) if (numcontacts) { if(ed1 && ed1->v->touch) - { - world->Event_Touch(world, ed1, ed2); + { //no trace info here. you'll have to figure it out yourself or something. + world->Event_Touch(world, ed1, ed2, NULL); } if(ed2 && ed2->v->touch) { - world->Event_Touch(world, ed2, ed1); + world->Event_Touch(world, ed2, ed1, NULL); } /* if either ent killed itself, don't collide */ diff --git a/engine/common/common.c b/engine/common/common.c index 7c98409d7..6b13b9dd9 100644 --- a/engine/common/common.c +++ b/engine/common/common.c @@ -128,10 +128,6 @@ qboolean msg_suppress_1 = false; int isPlugin; //if 2, we qcdebug to external program qboolean wantquit; -void COM_Path_f (void); -void COM_Dir_f (void); -void COM_Locate_f (void); - // if a packfile directory differs from this, it is assumed to be hacked #define PAK0_COUNT 339 @@ -450,11 +446,6 @@ char *Q_strcasestr(const char *haystack, const char *needle) return NULL; //didn't find it } -int QDECL Q_vsnprintf(char *buffer, int size, const char *format, va_list argptr) -{ - return vsnprintf(buffer, size, format, argptr); -} - int VARGS Com_sprintf(char *buffer, int size, const char *format, ...) { int ret; @@ -799,7 +790,7 @@ short ShortSwap (short l) return (b1<<8) + b2; } -short ShortNoSwap (short l) +static short ShortNoSwap (short l) { return l; } @@ -816,12 +807,12 @@ int LongSwap (int l) return ((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4; } -int LongNoSwap (int l) +static int LongNoSwap (int l) { return l; } -float FloatSwap (float f) +static float FloatSwap (float f) { union { @@ -838,7 +829,7 @@ float FloatSwap (float f) return dat2.f; } -float FloatNoSwap (float f) +static float FloatNoSwap (float f) { return f; } @@ -1032,11 +1023,11 @@ void MSG_WriteCoord (sizebuf_t *sb, float f) coorddata i = MSG_ToCoord(f, sb->prim.coordsize); SZ_Write (sb, (void*)&i, sb->prim.coordsize); } -void MSG_WriteCoord24 (sizebuf_t *sb, float f) +/*static void MSG_WriteCoord24 (sizebuf_t *sb, float f) { coorddata i = MSG_ToCoord(f, 3); SZ_Write (sb, (void*)&i, 3); -} +}*/ void MSG_WriteAngle16 (sizebuf_t *sb, float f) { @@ -1167,25 +1158,6 @@ unsigned int MSGCL_ReadEntity(void) num = (unsigned short)(short)MSG_ReadShort(); return num; } -//compat for ktx/ezquake's railgun -unsigned int MSGCLF_ReadEntity(qboolean *flagged) -{ - int s; - *flagged = false; - if (cls.fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS) - return MSG_ReadEntity(); - else - { - s = MSG_ReadShort(); - if (s < 0) - { - *flagged = true; - return -1 -s; - } - else - return s; - } -} #endif void MSG_WriteEntity(sizebuf_t *sb, unsigned int entnum) { @@ -1716,12 +1688,12 @@ float MSG_ReadCoord (void) MSG_ReadData(&c, net_message.prim.coordsize); return MSG_FromCoord(c, net_message.prim.coordsize); } -float MSG_ReadCoord24 (void) +/*static float MSG_ReadCoord24 (void) { coorddata c = {{0}}; MSG_ReadData(&c, 3); return MSG_FromCoord(c, 3); -} +}*/ float MSG_ReadCoordFloat (void) { coorddata c = {{0}}; @@ -4354,6 +4326,8 @@ skipwhite: return (char*)data; } +//escape a string so that COM_Parse will give the same string. +//maximum expansion is strlen(string)*2+4 (includes null terminator) const char *COM_QuotedString(const char *string, char *buf, int buflen, qboolean omitquotes) { #ifndef NOLEGACY @@ -4363,7 +4337,8 @@ const char *COM_QuotedString(const char *string, char *buf, int buflen, qboolean #endif const char *result = buf; if (strchr(string, '\r') || strchr(string, '\n') || (!dpcompat_console.ival && strchr(string, '\"'))) - { + { //strings of the form \"foo" can contain c-style escapes, including for newlines etc. + //it might be fancy to ALWAYS escape non-ascii chars too, but mneh if (!omitquotes) { *buf++ = '\\'; //prefix so the reader knows its a quoted string. @@ -4427,8 +4402,9 @@ const char *COM_QuotedString(const char *string, char *buf, int buflen, qboolean else buflen -= 1; if (dpcompat_console.ival) - { - while(*string && buflen >= 1) + { //dp escapes \\ and \", but nothing else. + //so no new-lines etc + while(*string && buflen >= 2) { if (*string == '\\' || *string == '\"') { @@ -4440,7 +4416,7 @@ const char *COM_QuotedString(const char *string, char *buf, int buflen, qboolean } } else - { + { //vanilla quake's console doesn't support any escapes. while(*string && buflen >= 1) { *buf++ = *string++; @@ -4810,7 +4786,7 @@ void COM_AddParm (const char *parm) COM_Version_f ====================== */ -void COM_Version_f (void) +static void COM_Version_f (void) { Con_Printf("%s\n", version_string()); @@ -5139,19 +5115,19 @@ void COM_Version_f (void) } #ifdef _DEBUG -void COM_LoopMe_f(void) +static void COM_LoopMe_f(void) { while(1) ; } -void COM_CrashMe_f(void) +static void COM_CrashMe_f(void) { int *crashaddr = (int*)0x05; *crashaddr = 0; } -void COM_ErrorMe_f(void) +static void COM_ErrorMe_f(void) { Sys_Error("\"errorme\" command used"); } @@ -5240,7 +5216,7 @@ void COM_AddWork(wgroup_t tg, void(*func)(void *ctx, void *data, size_t a, size_ Sys_UnlockConditional(com_workercondition[tg]); } -void COM_PrintWork(void) +/*static void COM_PrintWork(void) { struct com_work_s *work; int tg; @@ -5256,7 +5232,7 @@ void COM_PrintWork(void) } Sys_UnlockConditional(com_workercondition[tg]); } -} +}*/ //leavelocked = false == poll mode. //leavelocked = true == safe sleeping @@ -5733,9 +5709,6 @@ void COM_Init (void) #endif Cmd_AddCommandD("pkg", PM_Command_f, "Provides a way to install / list / disable / purge packages via the console."); - Cmd_AddCommandD("path", COM_Path_f, "prints a list of current search paths."); - Cmd_AddCommandD("dir", COM_Dir_f, "Displays filesystem listings. Accepts wildcards."); //q3 like - Cmd_AddCommandD("flocate", COM_Locate_f, "Searches for a named file, and displays where it can be found in the OS's filesystem"); //prints the pak or whatever where this file can be found. Cmd_AddCommandD("version", COM_Version_f, "Reports engine revision and optional compile-time settings."); //prints the pak or whatever where this file can be found. #ifdef _DEBUG @@ -5815,18 +5788,6 @@ char *VARGS va(const char *format, ...) return string[bufnum]; } - -/// just for debugging -int memsearch (qbyte *start, int count, int search) -{ - int i; - - for (i=0 ; iflags & CVAR_SERVEROVERRIDE && !force) + if (force) + ; + else if (0)//var->flags & CVAR_SERVEROVERRIDE && !force) latch = "variable %s is under server control - latched\n"; else if (var->flags & CVAR_LATCH && (sv_state || cls_state)) latch = "variable %s is latched and will be applied for the start of the next map\n"; @@ -757,7 +759,7 @@ cvar_t *Cvar_SetCore (cvar_t *var, const char *value, qboolean force) latch = "variable %s is a cheat variable - latched\n"; #endif - if (latch && !force) + if (latch) { if (cl_warncmd.value) { //FIXME: flag that there's a latched cvar instead of spamming prints. @@ -1053,7 +1055,7 @@ void Cvar_ForceSetValue (cvar_t *var, float value) Cvar_ForceSet (var, val); } -void Cvar_Free(cvar_t *tbf) +static void Cvar_Free(cvar_t *tbf) { cvar_t *var; cvar_group_t *grp; @@ -1161,6 +1163,11 @@ qboolean Cvar_Register (cvar_t *variable, const char *groupname) Con_Printf ("Cvar_RegisterVariable: %s is a command\n", variable->name); return false; } + if (variable->name2 && (Cmd_Exists (variable->name2) || Cvar_FindVar (variable->name2))) + { + Con_Printf ("Cvar_RegisterVariable: %s is a command/exists\n", variable->name2); + variable->name2 = NULL; + } group = Cvar_GetGroup(groupname); diff --git a/engine/common/fs.c b/engine/common/fs.c index 2868fa601..5cc22b430 100644 --- a/engine/common/fs.c +++ b/engine/common/fs.c @@ -214,6 +214,7 @@ void FS_Manifest_Free(ftemanifest_t *man) Z_Free(man->defaultexec); Z_Free(man->defaultoverrides); Z_Free(man->rtcbroker); + Z_Free(man->basedir); for (i = 0; i < sizeof(man->gamepath) / sizeof(man->gamepath[0]); i++) { Z_Free(man->gamepath[i].path); @@ -255,6 +256,8 @@ static ftemanifest_t *FS_Manifest_Clone(ftemanifest_t *oldm) newm->defaultoverrides = Z_StrDup(oldm->defaultoverrides); if (oldm->rtcbroker) newm->rtcbroker = Z_StrDup(oldm->rtcbroker); + if (oldm->basedir) + newm->basedir = Z_StrDup(oldm->basedir); newm->disablehomedir = oldm->disablehomedir; for (i = 0; i < sizeof(newm->gamepath) / sizeof(newm->gamepath[0]); i++) @@ -279,7 +282,7 @@ static ftemanifest_t *FS_Manifest_Clone(ftemanifest_t *oldm) return newm; } -void FS_Manifest_Print(ftemanifest_t *man) +static void FS_Manifest_Print(ftemanifest_t *man) { char buffer[1024]; int i, j; @@ -303,6 +306,8 @@ void FS_Manifest_Print(ftemanifest_t *man) Con_Printf("%s", man->defaultoverrides); if (man->rtcbroker) Con_Printf("rtcbroker %s\n", COM_QuotedString(man->rtcbroker, buffer, sizeof(buffer), false)); + if (man->basedir) + Con_Printf("basedir %s\n", COM_QuotedString(man->basedir, buffer, sizeof(buffer), false)); for (i = 0; i < sizeof(man->gamepath) / sizeof(man->gamepath[0]); i++) { @@ -370,7 +375,7 @@ static ftemanifest_t *FS_Manifest_Create(const char *syspath) return man; } -static qboolean FS_Manifest_ParsePackage(ftemanifest_t *man, int type) +static qboolean FS_Manifest_ParsePackage(ftemanifest_t *man, int packagetype) { char *path = ""; unsigned int crc = 0; @@ -453,7 +458,7 @@ mirror: { if (!man->package[i].path) { - if (type == mdt_singlepackage && (!strchr(path, '/') || strchr(path, ':') || strchr(path, '\\'))) + if (packagetype == mdt_singlepackage && (!strchr(path, '/') || strchr(path, ':') || strchr(path, '\\'))) { Con_Printf("invalid package path specified in manifest (%s)\n", path); break; @@ -465,7 +470,7 @@ mirror: #endif break; } - man->package[i].type = type; + man->package[i].type = packagetype; man->package[i].path = Z_StrDup(path); man->package[i].prefix = prefix?Z_StrDup(prefix):NULL; man->package[i].condition = condition?Z_StrDup(condition):NULL; @@ -682,7 +687,7 @@ int QDECL COM_FileSize(const char *path) } //appends a / on the end of the directory if it does not already have one. -void FS_CleanDir(char *out, int outlen) +static void FS_CleanDir(char *out, int outlen) { int olen = strlen(out); if (!olen || olen >= outlen-1) @@ -714,7 +719,7 @@ static void COM_PathLine(searchpath_t *s) (s->flags & SPF_WRITABLE)?"^[(w)\\tip\\Writable\\desc\\We can probably write here^]":"", (s->handle->GeneratePureCRC)?va("^[(h)\\tip\\Hash: %x^]", s->handle->GeneratePureCRC(s->handle, 0, 0)):""); } -void COM_Path_f (void) +static void COM_Path_f (void) { searchpath_t *s; @@ -844,7 +849,7 @@ static int QDECL COM_Dir_List(const char *name, qofs_t size, time_t mtime, void return 1; } -void COM_Dir_f (void) +static void COM_Dir_f (void) { char match[MAX_QPATH]; @@ -872,7 +877,7 @@ COM_Locate_f ============ */ -void COM_Locate_f (void) +static void COM_Locate_f (void) { flocation_t loc; char *f = Cmd_Argv(1); @@ -1657,7 +1662,7 @@ const char *FS_GetCleanPath(const char *pattern, char *outbuf, int outlen) return outbuf; } -vfsfile_t *VFS_Filter(const char *filename, vfsfile_t *handle) +static vfsfile_t *VFS_Filter(const char *filename, vfsfile_t *handle) { // char *ext; @@ -1855,7 +1860,7 @@ vfsfile_t *FS_OpenWithFriends(const char *fname, char *sysname, size_t sysnamesi } //returns false if the string didn't fit. we're not trying to be clever and reallocate the buffer -qboolean try_snprintf(char *buffer, size_t size, const char *format, ...) +static qboolean try_snprintf(char *buffer, size_t size, const char *format, ...) { size_t ret; va_list argptr; @@ -2306,7 +2311,7 @@ qboolean COM_LoadMapPackFile (const char *filename, qofs_t ofs) } static searchpath_t *FS_AddPathHandle(searchpath_t **oldpaths, const char *purepath, const char *probablepath, searchpathfuncs_t *handle, const char *prefix, unsigned int flags, unsigned int loadstuff); -searchpathfuncs_t *FS_GetOldPath(searchpath_t **oldpaths, const char *dir, unsigned int *keepflags) +static searchpathfuncs_t *FS_GetOldPath(searchpath_t **oldpaths, const char *dir, unsigned int *keepflags) { searchpath_t *p; searchpathfuncs_t *r = NULL; @@ -2390,7 +2395,7 @@ static int QDECL FS_AddWildDataFiles (const char *descriptor, qofs_t size, time_ return true; } -searchpathfuncs_t *FS_OpenPackByExtension(vfsfile_t *f, searchpathfuncs_t *parent, const char *filename, const char *pakname) +static searchpathfuncs_t *FS_OpenPackByExtension(vfsfile_t *f, searchpathfuncs_t *parent, const char *filename, const char *pakname) { searchpathfuncs_t *pak; int j; @@ -2770,7 +2775,7 @@ Sets com_gamedir, adds the directory to the head of the path, then loads and adds pak1.pak pak2.pak ... ================ */ -void FS_AddGameDirectory (searchpath_t **oldpaths, const char *puredir, const char *dir, unsigned int loadstuff, unsigned int flags) +static void FS_AddGameDirectory (searchpath_t **oldpaths, const char *puredir, const char *dir, unsigned int loadstuff, unsigned int flags) { unsigned int keptflags; searchpath_t *search; @@ -2890,8 +2895,9 @@ int FS_GetManifestArgv(char **argv, int maxargs) return c; } +/* //given a 'c:/foo/bar/' path, will extract 'bar'. -void FS_ExtractDir(char *in, char *out, int outlen) +static void FS_ExtractDir(char *in, char *out, int outlen) { char *end; if (!outlen) @@ -2923,7 +2929,7 @@ void FS_ExtractDir(char *in, char *out, int outlen) *out++ = *end++; } *out = 0; -} +}*/ qboolean FS_PathURLCache(const char *url, char *path, size_t pathsize) { @@ -3059,13 +3065,15 @@ void COM_Gamedir (const char *dir, const struct gamepacks *packagespaths) #define EZQUAKECOMPETITIVE "set ruleset_allow_fbmodels 1\nset sv_demoExtensions \"\"\n" #define QRPCOMPAT "set cl_cursor_scale 0.2\nset cl_cursor_bias_x 7.5\nset cl_cursor_bias_y 0.8" #define QCFG "set com_parseutf8 0\nset allow_download_refpackages 0\nset sv_bigcoords \"\"\nmap_autoopenportals 1\n" "sv_port "STRINGIFY(PORT_QWSERVER)" "STRINGIFY(PORT_NQSERVER)"\n" ZFIXHACK EZQUAKECOMPETITIVE QRPCOMPAT -//nehahra has to be weird with extra cvars, and buggy fullbrights. +/*NetQuake reconfiguration, to make certain people feel more at home...*/ +#define NQCFG "//-nohome\ncfg_save_auto 1\n" QCFG "sv_nqplayerphysics 1\ncl_loopbackprotocol auto\ncl_sbar 1\nplug_sbar 0\nsv_port "STRINGIFY(PORT_NQSERVER)"\ncl_defaultport "STRINGIFY(PORT_NQSERVER)"\n" +//nehahra has to be weird with its extra cvars, and buggy fullbrights. #define NEHCFG QCFG "set nospr32 0\nset cutscene 1\nalias startmap_sp \"map nehstart\"\nr_fb_bmodels 0\nr_fb_models 0\n" /*stuff that makes dp-only mods work a bit better*/ -#define DPCOMPAT QCFG "gl_specular 1\nset _cl_playermodel \"\"\n set dpcompat_set 1\ndpcompat_console 1\nset dpcompat_corruptglobals 1\nset vid_pixelheight 1\n" +#define DPCOMPAT QCFG "gl_specular 1\nset _cl_playermodel \"\"\n set dpcompat_set 1\ndpcompat_console 1\nset dpcompat_corruptglobals 1\nset vid_pixelheight 1\nset dpcompat_set 1\nset dpcompat_console 1\nset r_particlesdesc effectinfo\n" /*nexuiz/xonotic has a few quirks/annoyances...*/ -#define NEXCFG DPCOMPAT "cl_nopred 1\ncl_loopbackprotocol dpp7\nset sv_listen_dp 1\nset sv_listen_qw 0\nset sv_listen_nq 0\nset dpcompat_nopreparse 1\nset r_particlesdesc effectinfo\nset sv_bigcoords 1\nset sv_maxairspeed \"30\"\nset sv_jumpvelocity 270\nset sv_mintic \"0.01\"\ncl_nolerp 0\npr_enable_uriget 0\n" -#define XONCFG NEXCFG "set qport $qport_\ncom_parseutf8 1\npr_fixbrokenqccarrays 2\n" +#define NEXCFG DPCOMPAT "cl_loopbackprotocol dpp7\nset sv_listen_dp 1\nset sv_listen_qw 0\nset sv_listen_nq 0\nset dpcompat_nopreparse 1\nset sv_bigcoords 1\nset sv_maxairspeed \"30\"\nset sv_jumpvelocity 270\nset sv_mintic \"0.01\"\ncl_nolerp 0\n" +#define XONCFG NEXCFG "set qport $qport_\ncom_parseutf8 1\npr_fixbrokenqccarrays 2\nset pr_csqc_memsize 64m\nset pr_ssqc_memsize 96m\n" /*some modern non-compat settings*/ #define DMFCFG "set com_parseutf8 1\npm_airstep 1\nsv_demoExtensions 1\n" /*set some stuff so our regular qw client appears more like hexen2. sv_mintic is required to 'fix' the ravenstaff so that its projectiles don't impact upon each other*/ @@ -3120,30 +3128,37 @@ const gamemode_info_t gamemode_info[] = { //for quake, we also allow extracting all files from paks. some people think it loads faster that way or something. #ifndef NOLEGACY //cmdline switch exename protocol name(dpmaster) identifying file exec dir1 dir2 dir3 dir(fte) full name - //two quakes - one without extra game dirs which should avoid fuckups from nquake's configs (which screw over cvars that every nq progs.dat depends upon but which the ezquake id1-only less-compatible gamecode ignores). - {"-quake", "q1", "FTE-Quake DarkPlaces-Quake", {"id1/pak0.pak", "id1/quake.rc"},QCFG, {"id1", "qw", "*fte"}, "Quake", "https://triptohell.info/downloadables.php" /*,"id1/pak0.pak|http://quakeservers.nquake.com/qsw106.zip|http://nquake.localghost.net/qsw106.zip|http://qw.quakephil.com/nquake/qsw106.zip|http://fnu.nquake.com/qsw106.zip"*/}, - {"-netquake", "nq", "FTE-Quake DarkPlaces-Quake", {"id1/pak0.pak", "id1/quake.rc"},QCFG, {"id1"}, "Quake", "https://triptohell.info/downloadables.php" /*,"id1/pak0.pak|http://quakeservers.nquake.com/qsw106.zip|http://nquake.localghost.net/qsw106.zip|http://qw.quakephil.com/nquake/qsw106.zip|http://fnu.nquake.com/qsw106.zip"*/}, + //standard quake + {"-quake", "q1", "FTE-Quake DarkPlaces-Quake",{"id1/pak0.pak", "id1/quake.rc"},QCFG,{"id1", "qw", "*fte"}, "Quake", "https://triptohell.info/downloadables.php" /*,"id1/pak0.pak|http://quakeservers.nquake.com/qsw106.zip|http://nquake.localghost.net/qsw106.zip|http://qw.quakephil.com/nquake/qsw106.zip|http://fnu.nquake.com/qsw106.zip"*/}, + //alternative name, because fmf file install names are messy when a single name is used for registry install path. + {"-afterquake", NULL, "FTE-Quake",{"id1/pak0.pak", "id1/quake.rc"},QCFG,{"id1", "qw", "*fte"}, "Quake", "https://triptohell.info/downloadables.php" /*,"id1/pak0.pak|http://quakeservers.nquake.com/qsw106.zip|http://nquake.localghost.net/qsw106.zip|http://qw.quakephil.com/nquake/qsw106.zip|http://fnu.nquake.com/qsw106.zip"*/}, + //netquake-specific quake that avoids qw/ with its nquake fuckups, and disables nqisms + {"-netquake", "nq", "FTE-Quake DarkPlaces-Quake",{"id1/pak0.pak", "id1/quake.rc"},NQCFG,{"id1"}, "NetQuake", "https://triptohell.info/downloadables.php" /*,"id1/pak0.pak|http://quakeservers.nquake.com/qsw106.zip|http://nquake.localghost.net/qsw106.zip|http://qw.quakephil.com/nquake/qsw106.zip|http://fnu.nquake.com/qsw106.zip"*/}, + //because we can + {"-tenebrae", NULL, "FTE-Quake DarkPlaces-Quake",{"id1/pak0.pak", "id1/quake.rc"},QCFG"fps_preset tenebrae\n",{"id1","qw","*fte"},"Tenebrae", "https://triptohell.info/downloadables.php" /*,"id1/pak0.pak|http://quakeservers.nquake.com/qsw106.zip|http://nquake.localghost.net/qsw106.zip|http://qw.quakephil.com/nquake/qsw106.zip|http://fnu.nquake.com/qsw106.zip"*/}, + //quake's mission packs should not be favoured over the base game nor autodetected //third part mods also tend to depend upon the mission packs for their huds, even if they don't use any other content. //and q2 also has a rogue/pak0.pak file that we don't want to find and cause quake2 to look like dissolution of eternity //so just make these require the same files as good ol' quake. - {"-hipnotic", "hipnotic", "FTE-Hipnotic",{"id1/pak0.pak","id1/quake.rc"},QCFG, {"id1", "qw", "hipnotic", "*fte"}, "Quake: Scourge of Armagon"}, - {"-rogue", "rogue", "FTE-Rogue", {"id1/pak0.pak","id1/quake.rc"},QCFG, {"id1", "qw", "rogue", "*fte"}, "Quake: Dissolution of Eternity"}, + {"-hipnotic", "hipnotic", "FTE-Hipnotic", {"id1/pak0.pak","id1/quake.rc"},QCFG, {"id1", "qw", "hipnotic", "*fte"}, "Quake: Scourge of Armagon"}, + {"-rogue", "rogue", "FTE-Rogue", {"id1/pak0.pak","id1/quake.rc"},QCFG, {"id1", "qw", "rogue", "*fte"}, "Quake: Dissolution of Eternity"}, //various quake-dependant non-standalone mods that require hacks //quoth needed an extra arg just to enable hipnotic hud drawing, it doesn't actually do anything weird, but most engines have a -quoth arg, so lets have one too. - {"-quoth", "quoth", "FTE-Quake", {"id1/pak0.pak","id1/quake.rc"},QCFG, {"id1", "qw", "quoth", "*fte"}, "Quake: Quoth"}, - {"-nehahra", "nehahra", "FTE-Quake", {"id1/pak0.pak","id1/quake.rc"},NEHCFG, {"id1", "qw", "nehahra", "*fte"}, "Quake: Seal Of Nehahra"}, + {"-quoth", "quoth", "FTE-Quake", {"id1/pak0.pak","id1/quake.rc"},QCFG, {"id1", "qw", "quoth", "*fte"}, "Quake: Quoth"}, + {"-nehahra", "nehahra", "FTE-Quake", {"id1/pak0.pak","id1/quake.rc"},NEHCFG, {"id1", "qw", "nehahra", "*fte"}, "Quake: Seal Of Nehahra"}, //various quake-based standalone mods. - {"-nexuiz", "nexuiz", "Nexuiz", {"nexuiz.exe"}, NEXCFG, {"data", "*ftedata"}, "Nexuiz"}, - {"-xonotic", "xonotic", "Xonotic", {"xonotic.exe"}, XONCFG, {"data", "*ftedata"}, "Xonotic"}, + {"-nexuiz", "nexuiz", "Nexuiz", {"nexuiz.exe"}, NEXCFG, {"data", "*ftedata"},"Nexuiz"}, + {"-xonotic", "xonotic", "Xonotic", {"data/xonotic-data.pk3dir", + "data/xonotic-*data*.pk3"}, XONCFG, {"data", "*ftedata"},"Xonotic"}, // {"-spark", "spark", "Spark", {"base/src/progs.src", // "base/qwprogs.dat", -// "base/pak0.pak"}, DMFCFG, {"base", }, "Spark"}, +// "base/pak0.pak"}, DMFCFG, {"base", }, "Spark"}, // {"-scouts", "scouts", "FTE-SJ", {"basesj/src/progs.src", // "basesj/progs.dat", -// "basesj/pak0.pak"}, NULL, {"basesj", }, "Scouts Journey"}, -// {"-rmq", "rmq", "RMQ", {NULL}, RMQCFG, {"id1", "qw", "rmq", "*fte"}, "Remake Quake"}, +// "basesj/pak0.pak"}, NULL, {"basesj", }, "Scouts Journey"}, +// {"-rmq", "rmq", "RMQ", {NULL}, RMQCFG, {"id1", "qw", "rmq", "*fte" }, "Remake Quake"}, #ifdef HEXEN2 //hexen2's mission pack generally takes precedence if both are installed. @@ -3167,8 +3182,8 @@ const gamemode_info_t gamemode_info[] = { // {"-warsow", "warsow", "FTE-Warsow", {"basewsw/pak0.pk3"}, NULL, {"basewsw", "*ftewsw"}, "Warsow"}, #endif #if !defined(QUAKETC) && !defined(MINIMAL) -// {"-doom", "doom", "FTE-Doom", {"doom.wad"}, NULL, {"*", "*ftedoom"}, "Doom"}, -// {"-doom2", "doom2", "FTE-Doom2", {"doom2.wad"}, NULL, {"*", "*ftedoom"}, "Doom2"}, +// {"-doom", "doom", "FTE-Doom", {"doom.wad"}, NULL, {"*", "*ftedoom"},"Doom"}, +// {"-doom2", "doom2", "FTE-Doom2", {"doom2.wad"}, NULL, {"*", "*ftedoom"},"Doom2"}, // {"-doom3", "doom3", "FTE-Doom3", {"doom3.wad"}, NULL, {"based3", "*ftedoom3"},"Doom3"}, //for the luls @@ -3183,7 +3198,7 @@ const gamemode_info_t gamemode_info[] = { {NULL} }; -void QDECL Q_strnlowercatz(char *d, const char *s, int n) +static void QDECL Q_strnlowercatz(char *d, const char *s, int n) { int c = strlen(d); d += c; @@ -3654,7 +3669,7 @@ FS_ReloadPackFiles Called when the client has downloaded a new pak/pk3 file */ -void FS_ReloadPackFilesFlags(unsigned int reloadflags) +static void FS_ReloadPackFilesFlags(unsigned int reloadflags) { searchpath_t *oldpaths; searchpath_t *next; @@ -4025,7 +4040,7 @@ void FS_ReloadPackFiles(void) } -void FS_ReloadPackFiles_f(void) +static void FS_ReloadPackFiles_f(void) { if (Sys_LockMutex(fs_thread_mutex)) { @@ -4322,7 +4337,19 @@ static qboolean Sys_SteamHasFile(char *basepath, int basepathlen, char *steamdir } return false; } +#else +static qboolean Sys_SteamHasFile(char *basepath, int basepathlen, char *steamdir, char *fname) +{ //this system probably has no steam installs... + return false; +} #endif + +qboolean Sys_DoDirectoryPrompt(char *basepath, size_t basepathsize, const char *poshname, const char *savedname) +{ + return false; +} +//#define Sys_DoDirectoryPrompt(bp,bps,game,savename) false + qboolean Sys_FindGameData(const char *poshname, const char *gamename, char *basepath, int basepathlen, qboolean allowprompts) { #if defined(__linux__) || defined(__unix__) || defined(__apple__) @@ -4374,10 +4401,18 @@ qboolean Sys_FindGameData(const char *poshname, const char *gamename, char *base return true; } } + +#if !defined(NPFTE) && !defined(SERVERONLY) //this is *really* unfortunate, but doing this crashes the browser + if (allowprompts && poshname && *gamename && !COM_CheckParm("-manifest")) + { + if (Sys_DoDirectoryPrompt(basepath, basepathlen, poshname, gamename)) + return true; + } +#endif + #endif return false; } -#define Sys_DoDirectoryPrompt(bp,bps,game,savename) false #endif static void FS_FreePaths(void) @@ -4455,11 +4490,16 @@ static qboolean FS_DirHasAPackage(char *basedir, ftemanifest_t *man) return defaultret; } +//false stops the search (and returns that value to FS_DirHasGame) +int FS_DirDoesHaveGame(const char *fname, qofs_t fsize, time_t modtime, void *ctx, searchpathfuncs_t *subdir) +{ + return false; +} + //just check each possible file, see if one is there. static qboolean FS_DirHasGame(const char *basedir, int gameidx) { int j; - vfsfile_t *f; //none listed, just assume its correct. if (!gamemode_info[gameidx].auniquefile[0]) @@ -4469,12 +4509,8 @@ static qboolean FS_DirHasGame(const char *basedir, int gameidx) { if (!gamemode_info[gameidx].auniquefile[j]) continue; //no more - f = VFSOS_Open(va("%s%s", basedir, gamemode_info[gameidx].auniquefile[j]), "rb"); - if (f) - { - VFS_CLOSE(f); - return true; - } + if (!Sys_EnumerateFiles(basedir, gamemode_info[gameidx].auniquefile[j], FS_DirDoesHaveGame, NULL, NULL)) + return true; //search was cancelled by the callback, so it actually got called. } return false; } @@ -4549,6 +4585,12 @@ static ftemanifest_t *FS_GenerateLegacyManifest(char *newbasedir, int sizeof_new { man = FS_Manifest_Create(NULL); + if (gamemode_info[game].customexec && !strncmp(gamemode_info[game].customexec, "//-nohome\n", 10)) + { + Cmd_TokenizeString("disablehomedir 1", false, false); + FS_Manifest_ParseTokens(man); + } + Cmd_TokenizeString(va("game \"%s\"", gamemode_info[game].argname+1), false, false); FS_Manifest_ParseTokens(man); if (gamemode_info[game].poshname) @@ -5207,7 +5249,7 @@ void FS_BeginManifestUpdates(void) } #endif -qboolean FS_FoundManifest(void *usr, ftemanifest_t *man) +static qboolean FS_FoundManifest(void *usr, ftemanifest_t *man) { if (!*(ftemanifest_t**)usr) *(ftemanifest_t**)usr = man; @@ -5258,7 +5300,11 @@ ftemanifest_t *FS_ReadDefaultManifest(char *newbasedir, size_t newbasedirsize, q VFS_READ(f, fdata, len); fdata[len] = 0; man = FS_Manifest_Parse(NULL, fdata); - man->security = MANIFEST_SECURITY_DEFAULT; + if (man) + { + man->security = MANIFEST_SECURITY_DEFAULT; + man->basedir = Z_StrDup(newbasedir); + } BZ_Free(fdata); } VFS_CLOSE(f); @@ -5514,9 +5560,14 @@ qboolean FS_ChangeGame(ftemanifest_t *man, qboolean allowreloadconfigs, qboolean } builtingame = true; - if (!fixedbasedir && !FS_DirHasGame(newbasedir, i)) - if (Sys_FindGameData(man->formalname, man->installation, realpath, sizeof(realpath), man->security != MANIFEST_SECURITY_INSTALLER) && FS_FixPath(realpath, sizeof(realpath)) && FS_DirHasGame(realpath, i)) - Q_strncpyz (newbasedir, realpath, sizeof(newbasedir)); + if (!fixedbasedir) + { + if (man->basedir) + Q_strncpyz (newbasedir, man->basedir, sizeof(newbasedir)); + else if (!FS_DirHasGame(newbasedir, i)) + if (Sys_FindGameData(man->formalname, man->installation, realpath, sizeof(realpath), man->security != MANIFEST_SECURITY_INSTALLER) && FS_FixPath(realpath, sizeof(realpath)) && FS_DirHasGame(realpath, i)) + Q_strncpyz (newbasedir, realpath, sizeof(newbasedir)); + } break; } } @@ -5937,7 +5988,7 @@ qboolean FS_FixupGamedirForExternalFile(char *input, char *filename, size_t fnam } -void FS_ChangeGame_f(void) +static void FS_ChangeGame_f(void) { int i; char *arg = Cmd_Argv(1); @@ -5992,7 +6043,7 @@ void FS_ChangeGame_f(void) } } -void FS_ChangeMod_f(void) +static void FS_ChangeMod_f(void) { char cachename[512]; struct gamepacks packagespaths[16]; @@ -6068,13 +6119,28 @@ void FS_ChangeMod_f(void) } } -void FS_ShowManifest_f(void) +static void FS_ShowManifest_f(void) { if (fs_manifest) FS_Manifest_Print(fs_manifest); else Con_Printf("no manifest loaded...\n"); } + +static int QDECL FS_ArbitraryFile_cb (const char *name, qofs_t flags, time_t mtime, void *parm, searchpathfuncs_t *spath) +{ + struct xcommandargcompletioncb_s *ctx = parm; + ctx->cb(name, NULL, NULL, ctx); + return true; +} +void FS_ArbitraryFile_c(int argn, const char *partial, struct xcommandargcompletioncb_s *ctx) +{ + if (argn == 1) + { + COM_EnumerateFiles(va("%s*", partial), FS_ArbitraryFile_cb, ctx); + } +} + /* ================ COM_InitFilesystem @@ -6096,6 +6162,10 @@ void COM_InitFilesystem (void) Cmd_AddCommandD("fs_changemod", FS_ChangeMod_f, "Provides the backend functionality of a transient online installer. Eg, for quaddicted's map/mod database."); Cmd_AddCommand("fs_showmanifest", FS_ShowManifest_f); Cmd_AddCommand ("fs_flush", COM_RefreshFSCache_f); + Cmd_AddCommandAD("dir", COM_Dir_f, FS_ArbitraryFile_c, "Displays filesystem listings. Accepts wildcards."); //q3 like + Cmd_AddCommandD("path", COM_Path_f, "prints a list of current search paths."); + Cmd_AddCommandAD("flocate", COM_Locate_f, FS_ArbitraryFile_c, "Searches for a named file, and displays where it can be found in the OS's filesystem"); //prints the pak or whatever where this file can be found. + // // -basedir diff --git a/engine/common/fs_stdio.c b/engine/common/fs_stdio.c index 5afa5be9d..dceffe28b 100644 --- a/engine/common/fs_stdio.c +++ b/engine/common/fs_stdio.c @@ -148,7 +148,7 @@ vfsfile_t *FSSTDIO_OpenTemp(void) vfsfile_t *Sys_OpenAsset(const char *fname); #endif -vfsfile_t *VFSSTDIO_Open(const char *osname, const char *mode, qboolean *needsflush) +static vfsfile_t *VFSSTDIO_Open(const char *osname, const char *mode, qboolean *needsflush) { FILE *f; vfsstdiofile_t *file; diff --git a/engine/common/gl_q2bsp.c b/engine/common/gl_q2bsp.c index f3ec9814e..e02a9b22d 100644 --- a/engine/common/gl_q2bsp.c +++ b/engine/common/gl_q2bsp.c @@ -421,7 +421,7 @@ qboolean BoundsIntersect (vec3_t mins1, vec3_t maxs1, vec3_t mins2, vec3_t maxs2 #ifdef Q3BSPS -int PlaneTypeForNormal ( vec3_t normal ) +static int PlaneTypeForNormal ( vec3_t normal ) { vec_t ax, ay, az; @@ -460,7 +460,7 @@ void CategorizePlane ( mplane_t *plane ) plane->type = PlaneTypeForNormal(plane->normal); } -void PlaneFromPoints ( vec3_t verts[3], mplane_t *plane ) +static void PlaneFromPoints ( vec3_t verts[3], mplane_t *plane ) { vec3_t v1, v2; @@ -948,6 +948,163 @@ static void CM_CreatePatch(model_t *loadmodel, q3cpatch_t *patch, q2mapsurface_t //====================================================== +static qboolean CM_CreatePatchForFace (model_t *loadmodel, cminfo_t *prv, mleaf_t *leaf, int facenum, int *checkout) +{ + size_t u; + q3cface_t *face; + q2mapsurface_t *surf; + q3cpatch_t *patch; + q3cmesh_t *cmesh; + + face = &prv->faces[facenum]; + + if (face->numverts <= 0) + return true; + if (face->shadernum < 0 || face->shadernum >= loadmodel->numtextures) + return true; + surf = &prv->surfaces[face->shadernum]; + if (!surf->c.value) //surface has no contents value, so can't ever block anything. + return true; + + switch(face->facetype) + { + case MST_TRIANGLE_SOUP: + if (!face->soup.numindicies) + return true; + //only enable mesh collisions if its meant to be enabled. + //we haven't parsed any shaders, so we depend upon the stuff that the bsp compiler left lying around. + if (!(surf->c.flags & q3bsp_surf_meshcollision_flag.ival) && !q3bsp_surf_meshcollision_force.ival) + return true; + + if (prv->numleafcmeshes >= prv->maxleafcmeshes) + { + prv->maxleafcmeshes *= 2; + prv->maxleafcmeshes += 16; + if (prv->numleafcmeshes > prv->maxleafcmeshes) + { //detect overflow + Con_Printf (CON_ERROR "CM_CreateCMeshesForLeafs: map is insanely huge!\n"); + return false; + } + prv->leafcmeshes = realloc(prv->leafcmeshes, sizeof(*prv->leafcmeshes) * prv->maxleafcmeshes); + } + + // the patch was already built + if (checkout[facenum] != -1) + { + prv->leafcmeshes[prv->numleafcmeshes] = checkout[facenum]; + cmesh = &prv->cmeshes[checkout[facenum]]; + } + else + { + if (prv->numcmeshes >= MAX_CM_PATCHES) + { + Con_Printf (CON_ERROR "CM_CreatePatchesForLeafs: map has too many patches\n"); + return false; + } + + cmesh = &prv->cmeshes[prv->numcmeshes]; + prv->leafcmeshes[prv->numleafcmeshes] = prv->numcmeshes; + checkout[facenum] = prv->numcmeshes++; + +//gcc warns without this cast + + cmesh->surface = surf; + cmesh->numverts = face->numverts; + cmesh->numincidies = face->soup.numindicies; + cmesh->xyz_array = ZG_Malloc(&loadmodel->memgroup, cmesh->numverts * sizeof(*cmesh->xyz_array) + cmesh->numincidies * sizeof(*cmesh->indicies)); + cmesh->indicies = (index_t*)(cmesh->xyz_array + cmesh->numverts); + + VectorCopy(prv->verts[face->firstvert+0], cmesh->xyz_array[0]); + VectorCopy(cmesh->xyz_array[0], cmesh->absmaxs); + VectorCopy(cmesh->xyz_array[0], cmesh->absmins); + for (u = 1; u < cmesh->numverts; u++) + { + VectorCopy(prv->verts[face->firstvert+u], cmesh->xyz_array[u]); + AddPointToBounds(cmesh->xyz_array[u], cmesh->absmins, cmesh->absmaxs); + } + for (u = 0; u < cmesh->numincidies; u++) + cmesh->indicies[u] = prv->surfindexes[face->soup.firstindex+u]; + } + leaf->contents |= surf->c.value; + leaf->numleafcmeshes++; + + prv->numleafcmeshes++; + + break; + case MST_PATCH: + if (face->patch.cp[0] <= 0 || face->patch.cp[1] <= 0) + return true; + + if ( !surf->c.value || (surf->c.flags & Q3SURF_NONSOLID) ) + return true; + + if (prv->numleafpatches >= prv->maxleafpatches) + { + prv->maxleafpatches *= 2; + prv->maxleafpatches += 16; + if (prv->numleafpatches > prv->maxleafpatches) + { //detect overflow + Con_Printf (CON_ERROR "CM_CreatePatchesForLeafs: map is insanely huge!\n"); + return false; + } + prv->leafpatches = realloc(prv->leafpatches, sizeof(*prv->leafpatches) * prv->maxleafpatches); + } + + // the patch was already built + if (checkout[facenum] != -1) + { + prv->leafpatches[prv->numleafpatches] = checkout[facenum]; + patch = &prv->patches[checkout[facenum]]; + } + else + { + if (prv->numpatches >= MAX_CM_PATCHES) + { + Con_Printf (CON_ERROR "CM_CreatePatchesForLeafs: map has too many patches\n"); + return false; + } + + patch = &prv->patches[prv->numpatches]; + prv->leafpatches[prv->numleafpatches] = prv->numpatches; + checkout[facenum] = prv->numpatches++; + +//gcc warns without this cast + CM_CreatePatch (loadmodel, patch, surf, (const vec_t *)(prv->verts + face->firstvert), face->patch.cp ); + } + leaf->contents |= patch->surface->c.value; + leaf->numleafpatches++; + + prv->numleafpatches++; + break; + } + return true; +} +static qboolean CM_CreatePatchesForLeaf (model_t *loadmodel, cminfo_t *prv, mleaf_t *leaf, int *checkout) +{ + int j, k; + + leaf->numleafpatches = 0; + leaf->firstleafpatch = prv->numleafpatches; + leaf->numleafcmeshes = 0; + leaf->firstleafcmesh = prv->numleafcmeshes; + + if (leaf->cluster == -1) + return true; + + for (j=0 ; jnummarksurfaces ; j++) + { + k = leaf->firstmarksurface[j] - loadmodel->surfaces; + if (k >= prv->numfaces) + { + Con_Printf (CON_ERROR "CM_CreatePatchesForLeafs: corrupt map\n"); + break; + } + if (!CM_CreatePatchForFace (loadmodel, prv, leaf, k, checkout)) + return false; + } + return true; +} + /* ================= CM_CreatePatchesForLeafs @@ -955,12 +1112,8 @@ CM_CreatePatchesForLeafs */ static qboolean CM_CreatePatchesForLeafs (model_t *loadmodel, cminfo_t *prv) { - int i, j, k; + int i, k; mleaf_t *leaf; - q3cface_t *face; - q2mapsurface_t *surf; - q3cpatch_t *patch; - q3cmesh_t *cmesh; int *checkout = alloca(sizeof(int)*prv->numfaces); if (map_noCurves.ival) @@ -968,148 +1121,23 @@ static qboolean CM_CreatePatchesForLeafs (model_t *loadmodel, cminfo_t *prv) memset (checkout, -1, sizeof(int)*prv->numfaces); + //worldmodel's leafs for (i = 0, leaf = loadmodel->leafs; i < loadmodel->numleafs; i++, leaf++) + if (!CM_CreatePatchesForLeaf(loadmodel, prv, leaf, checkout)) + return false; + + //and the per-submodel uni-leaf. + for (i = 0; i < prv->numcmodels; i++) { - leaf->numleafpatches = 0; - leaf->firstleafpatch = prv->numleafpatches; - leaf->numleafcmeshes = 0; - leaf->firstleafcmesh = prv->numleafcmeshes; - - if (leaf->cluster == -1) - continue; - - for (j=0 ; jnummarksurfaces ; j++) + leaf = prv->cmodels[i].headleaf; + if (leaf) { - k = leaf->firstmarksurface[j] - loadmodel->surfaces; - if (k >= prv->numfaces) - { - Con_Printf (CON_ERROR "CM_CreatePatchesForLeafs: corrupt map\n"); - break; - } - face = &prv->faces[k]; - - if (face->numverts <= 0) - continue; - if (face->shadernum < 0 || face->shadernum >= loadmodel->numtextures) - continue; - surf = &prv->surfaces[face->shadernum]; - if (!surf->c.value) //surface has no contents value, so can't ever block anything. - continue; - - switch(face->facetype) - { - case MST_TRIANGLE_SOUP: - if (!face->soup.numindicies) - continue; - //only enable mesh collisions if its meant to be enabled. - //we haven't parsed any shaders, so we depend upon the stuff that the bsp compiler left lying around. - if (!(surf->c.flags & q3bsp_surf_meshcollision_flag.ival) && !q3bsp_surf_meshcollision_force.ival) - continue; - - if (prv->numleafcmeshes >= prv->maxleafcmeshes) - { - prv->maxleafcmeshes *= 2; - prv->maxleafcmeshes += 16; - if (prv->numleafcmeshes > prv->maxleafcmeshes) - { //detect overflow - Con_Printf (CON_ERROR "CM_CreateCMeshesForLeafs: map is insanely huge!\n"); - return false; - } - prv->leafcmeshes = realloc(prv->leafcmeshes, sizeof(*prv->leafcmeshes) * prv->maxleafcmeshes); - } - - // the patch was already built - if (checkout[k] != -1) - { - prv->leafcmeshes[prv->numleafcmeshes] = checkout[k]; - cmesh = &prv->cmeshes[checkout[k]]; - } - else - { - if (prv->numcmeshes >= MAX_CM_PATCHES) - { - Con_Printf (CON_ERROR "CM_CreatePatchesForLeafs: map has too many patches\n"); - return false; - } - - cmesh = &prv->cmeshes[prv->numcmeshes]; - prv->leafcmeshes[prv->numleafcmeshes] = prv->numcmeshes; - checkout[k] = prv->numcmeshes++; - - //gcc warns without this cast - - cmesh->surface = surf; - cmesh->numverts = face->numverts; - cmesh->numincidies = face->soup.numindicies; - cmesh->xyz_array = ZG_Malloc(&loadmodel->memgroup, cmesh->numverts * sizeof(*cmesh->xyz_array) + cmesh->numincidies * sizeof(*cmesh->indicies)); - cmesh->indicies = (index_t*)(cmesh->xyz_array + cmesh->numverts); - - VectorCopy(prv->verts[face->firstvert+0], cmesh->xyz_array[0]); - VectorCopy(cmesh->xyz_array[0], cmesh->absmaxs); - VectorCopy(cmesh->xyz_array[0], cmesh->absmins); - for (k = 1; k < cmesh->numverts; k++) - { - VectorCopy(prv->verts[face->firstvert+k], cmesh->xyz_array[k]); - AddPointToBounds(cmesh->xyz_array[k], cmesh->absmins, cmesh->absmaxs); - } - for (k = 0; k < cmesh->numincidies; k++) - cmesh->indicies[k] = prv->surfindexes[face->soup.firstindex+k]; - } - leaf->contents |= surf->c.value; - leaf->numleafcmeshes++; - - prv->numleafcmeshes++; - - break; - case MST_PATCH: - if (face->patch.cp[0] <= 0 || face->patch.cp[1] <= 0) - continue; - - if ( !surf->c.value || (surf->c.flags & Q3SURF_NONSOLID) ) - continue; - - if (prv->numleafpatches >= prv->maxleafpatches) - { - prv->maxleafpatches *= 2; - prv->maxleafpatches += 16; - if (prv->numleafpatches > prv->maxleafpatches) - { //detect overflow - Con_Printf (CON_ERROR "CM_CreatePatchesForLeafs: map is insanely huge!\n"); - return false; - } - prv->leafpatches = realloc(prv->leafpatches, sizeof(*prv->leafpatches) * prv->maxleafpatches); - } - - // the patch was already built - if (checkout[k] != -1) - { - prv->leafpatches[prv->numleafpatches] = checkout[k]; - patch = &prv->patches[checkout[k]]; - } - else - { - if (prv->numpatches >= MAX_CM_PATCHES) - { - Con_Printf (CON_ERROR "CM_CreatePatchesForLeafs: map has too many patches\n"); - return false; - } - - patch = &prv->patches[prv->numpatches]; - prv->leafpatches[prv->numleafpatches] = prv->numpatches; - checkout[k] = prv->numpatches++; - - //gcc warns without this cast - CM_CreatePatch (loadmodel, patch, surf, (const vec_t *)(prv->verts + face->firstvert), face->patch.cp ); - } - leaf->contents |= patch->surface->c.value; - leaf->numleafpatches++; - - prv->numleafpatches++; - break; - } + if (!CM_CreatePatchesForLeaf(loadmodel, prv, leaf, checkout)) + return false; + for (k = 0; k < prv->cmodels[i].numsurfaces; k++) + CM_CreatePatchForFace(loadmodel, prv, leaf, prv->cmodels[i].firstsurface+k, checkout); } } - return true; } #endif @@ -4669,7 +4697,7 @@ To keep everything totally uniform, bounding boxes are turned into small BSP trees instead of being compared directly. =================== */ -void CM_SetTempboxSize (vec3_t mins, vec3_t maxs) +static void CM_SetTempboxSize (vec3_t mins, vec3_t maxs) { box_planes[0].dist = maxs[0]; box_planes[1].dist = maxs[1]; @@ -4741,7 +4769,7 @@ int *leaf_list; float *leaf_mins, *leaf_maxs; int leaf_topnode; -void CM_BoxLeafnums_r (model_t *mod, int nodenum) +static void CM_BoxLeafnums_r (model_t *mod, int nodenum) { mplane_t *plane; mnode_t *node; @@ -4779,7 +4807,7 @@ void CM_BoxLeafnums_r (model_t *mod, int nodenum) } } -int CM_BoxLeafnums_headnode (model_t *mod, vec3_t mins, vec3_t maxs, int *list, int listsize, int headnode, int *topnode) +static int CM_BoxLeafnums_headnode (model_t *mod, vec3_t mins, vec3_t maxs, int *list, int listsize, int headnode, int *topnode) { leaf_list = list; leaf_count = 0; @@ -6355,7 +6383,7 @@ qbyte *CM_ClusterPHS (model_t *mod, int cluster, pvsbuffer_t *buffer) return buffer->buffer; } -unsigned int SV_Q2BSP_FatPVS (model_t *mod, vec3_t org, pvsbuffer_t *result, qboolean merge) +static unsigned int SV_Q2BSP_FatPVS (model_t *mod, vec3_t org, pvsbuffer_t *result, qboolean merge) { int leafs[64]; int i, j, count; diff --git a/engine/common/huff.c b/engine/common/huff.c index f4ea32c04..9dba84d98 100644 --- a/engine/common/huff.c +++ b/engine/common/huff.c @@ -84,15 +84,15 @@ static void Huff_setBloc(int _bloc) { bloc = _bloc; } -*/ -int Huff_getBit( qbyte *fin, int *offset) { + +static int Huff_getBit( qbyte *fin, int *offset) { int t; bloc = *offset; t = (fin[(bloc>>3)] >> (bloc&7)) & 0x1; bloc++; *offset = bloc; return t; -} +}*/ /* Add a bit to the output file (buffered) */ static void huff_add_bit (char bit, qbyte *fout) { diff --git a/engine/common/mathlib.c b/engine/common/mathlib.c index c05012eb1..c55e2cf65 100644 --- a/engine/common/mathlib.c +++ b/engine/common/mathlib.c @@ -28,7 +28,7 @@ vec3_t vec3_origin = {0,0,0}; #define DEG2RAD( a ) ( a * M_PI ) / 180.0F -void ProjectPointOnPlane( vec3_t dst, const vec3_t p, const vec3_t normal ) +static void ProjectPointOnPlane( vec3_t dst, const vec3_t p, const vec3_t normal ) { float d; vec3_t n; @@ -267,7 +267,7 @@ if (sides == 0) -void VVPerpendicularVector(vec3_t dst, const vec3_t src) +static void VVPerpendicularVector(vec3_t dst, const vec3_t src) { if (!src[0] && !src[1]) { @@ -858,9 +858,9 @@ void QDECL GenMatrixPosQuat4Scale(const vec3_t pos, const vec4_t quat, const vec result[1*4+3] = pos[1]; result[2*4+3] = pos[2]; } -#ifdef HALFLIFEMODELS +#if 0//def HALFLIFEMODELS -void AngleQuaternion( const vec3_t angles, vec4_t quaternion ) +static void AngleQuaternion( const vec3_t angles, vec4_t quaternion ) { float angle; float sr, sp, sy, cr, cp, cy; @@ -882,7 +882,7 @@ void AngleQuaternion( const vec3_t angles, vec4_t quaternion ) quaternion[3] = cr*cp*cy+sr*sp*sy; // W } -void QuaternionMatrix( const vec4_t quaternion, float (*matrix)[4] ) +static void QuaternionMatrix( const vec4_t quaternion, float (*matrix)[4] ) { matrix[0][0] = 1.0 - 2.0 * quaternion[1] * quaternion[1] - 2.0 * quaternion[2] * quaternion[2]; diff --git a/engine/common/net_ssl_gnutls.c b/engine/common/net_ssl_gnutls.c index 3743cba46..cc6ff17f2 100644 --- a/engine/common/net_ssl_gnutls.c +++ b/engine/common/net_ssl_gnutls.c @@ -613,7 +613,7 @@ static int QDECL SSL_CheckCert(gnutls_session_t session) //return 1 to read data. //-1 or 0 for error or not ready -int SSL_DoHandshake(gnutlsfile_t *file) +static int SSL_DoHandshake(gnutlsfile_t *file) { int err; //session was previously closed = error @@ -827,7 +827,7 @@ static gnutls_certificate_credentials_t xcred[2]; static gnutls_datum_t cookie_key; #endif -qboolean SSL_LoadPrivateCert(gnutls_certificate_credentials_t cred) +static qboolean SSL_LoadPrivateCert(gnutls_certificate_credentials_t cred) { int ret = -1; gnutls_datum_t priv, pub; @@ -1045,7 +1045,7 @@ qboolean SSL_InitGlobal(qboolean isserver) return false; return true; } -qboolean SSL_InitConnection(gnutlsfile_t *newf, qboolean isserver, qboolean datagram) +static qboolean SSL_InitConnection(gnutlsfile_t *newf, qboolean isserver, qboolean datagram) { // Initialize TLS session qgnutls_init (&newf->session, GNUTLS_NONBLOCK|(isserver?GNUTLS_SERVER:GNUTLS_CLIENT)|(datagram?GNUTLS_DATAGRAM:0)); @@ -1153,11 +1153,11 @@ int TLS_GetChannelBinding(vfsfile_t *vf, qbyte *binddata, size_t *bindsize) #ifdef HAVE_DTLS -void GNUDTLS_DestroyContext(void *ctx) +static void GNUDTLS_DestroyContext(void *ctx) { SSL_Close(ctx); } -void *GNUDTLS_CreateContext(const char *remotehost, void *cbctx, neterr_t(*push)(void *cbctx, const qbyte *data, size_t datasize), qboolean isserver) +static void *GNUDTLS_CreateContext(const char *remotehost, void *cbctx, neterr_t(*push)(void *cbctx, const qbyte *data, size_t datasize), qboolean isserver) { gnutlsfile_t *newf; @@ -1185,7 +1185,7 @@ void *GNUDTLS_CreateContext(const char *remotehost, void *cbctx, neterr_t(*push) return newf; } -neterr_t GNUDTLS_Transmit(void *ctx, const qbyte *data, size_t datasize) +static neterr_t GNUDTLS_Transmit(void *ctx, const qbyte *data, size_t datasize) { int ret; gnutlsfile_t *f = (gnutlsfile_t *)ctx; @@ -1217,7 +1217,7 @@ neterr_t GNUDTLS_Transmit(void *ctx, const qbyte *data, size_t datasize) return NETERR_SENT; } -neterr_t GNUDTLS_Received(void *ctx, qbyte *data, size_t datasize) +static neterr_t GNUDTLS_Received(void *ctx, qbyte *data, size_t datasize) { int cli_addr = 0xdeadbeef; int ret; @@ -1291,7 +1291,7 @@ neterr_t GNUDTLS_Received(void *ctx, qbyte *data, size_t datasize) return NETERR_SENT; } -neterr_t GNUDTLS_Timeouts(void *ctx) +static neterr_t GNUDTLS_Timeouts(void *ctx) { gnutlsfile_t *f = (gnutlsfile_t *)ctx; int ret; diff --git a/engine/common/net_wins.c b/engine/common/net_wins.c index a0dbddeb6..243739877 100644 --- a/engine/common/net_wins.c +++ b/engine/common/net_wins.c @@ -5215,7 +5215,7 @@ neterr_t FTENET_TCPConnect_SendPacket(ftenet_generic_connection_t *gcon, int len return NETERR_NOROUTE; } -int FTENET_TCPConnect_GetLocalAddresses(struct ftenet_generic_connection_s *gcon, unsigned int *adrflags, netadr_t *addresses, int maxaddresses) +static int FTENET_TCPConnect_GetLocalAddresses(struct ftenet_generic_connection_s *gcon, unsigned int *adrflags, netadr_t *addresses, int maxaddresses) { ftenet_tcpconnect_connection_t *con = (ftenet_tcpconnect_connection_t*)gcon; netproto_t prot = con->tls?NP_TLS:NP_STREAM; @@ -5227,7 +5227,7 @@ int FTENET_TCPConnect_GetLocalAddresses(struct ftenet_generic_connection_s *gcon return r; } -qboolean FTENET_TCPConnect_ChangeLocalAddress(struct ftenet_generic_connection_s *con, netadr_t *adr) +static qboolean FTENET_TCPConnect_ChangeLocalAddress(struct ftenet_generic_connection_s *con, netadr_t *adr) { //if we're a server, we want to try switching listening tcp port without shutting down all other connections. //yes, this might mean we leave a connection active on the old port, but oh well. @@ -5349,7 +5349,7 @@ qboolean FTENET_TCPConnect_ChangeLocalAddress(struct ftenet_generic_connection_s } return false; } -void FTENET_TCPConnect_Close(ftenet_generic_connection_t *gcon) +static void FTENET_TCPConnect_Close(ftenet_generic_connection_t *gcon) { ftenet_tcpconnect_connection_t *con = (ftenet_tcpconnect_connection_t*)gcon; ftenet_tcpconnect_stream_t *st; @@ -7801,7 +7801,7 @@ void NET_InitClient(qboolean loopbackonly) #ifndef CLIENTONLY #ifdef HAVE_IPV4 -void QDECL SV_Tcpport_Callback(struct cvar_s *var, char *oldvalue) +static void QDECL SV_Tcpport_Callback(struct cvar_s *var, char *oldvalue) { if (!strcmp(var->string, "0")) //qtv_streamport had an old default value of 0. make sure we don't end up listening on random ports. FTENET_AddToCollection(svs.sockets, var->name, "", NA_IP, NP_STREAM); @@ -7815,21 +7815,21 @@ cvar_t qtv_streamport = CVARAFCD( "qtv_streamport", "", #endif #endif #ifdef HAVE_IPV6 -void QDECL SV_Tcpport6_Callback(struct cvar_s *var, char *oldvalue) +static void QDECL SV_Tcpport6_Callback(struct cvar_s *var, char *oldvalue) { FTENET_AddToCollection(svs.sockets, var->name, var->string, NA_IPV6, NP_STREAM); } cvar_t sv_port_tcp6 = CVARC("sv_port_tcp6", "", SV_Tcpport6_Callback); #endif #ifdef HAVE_IPV4 -void QDECL SV_Port_Callback(struct cvar_s *var, char *oldvalue) +static void QDECL SV_Port_Callback(struct cvar_s *var, char *oldvalue) { FTENET_AddToCollection(svs.sockets, var->name, var->string, NA_IP, NP_DGRAM); } cvar_t sv_port_ipv4 = CVARC("sv_port", STRINGIFY(PORT_DEFAULTSERVER), SV_Port_Callback); #endif #ifdef HAVE_IPV6 -void QDECL SV_PortIPv6_Callback(struct cvar_s *var, char *oldvalue) +static void QDECL SV_PortIPv6_Callback(struct cvar_s *var, char *oldvalue) { FTENET_AddToCollection(svs.sockets, var->name, var->string, NA_IPV6, NP_DGRAM); } @@ -7850,7 +7850,7 @@ void QDECL SV_PortUNIX_Callback(struct cvar_s *var, char *oldvalue) cvar_t sv_port_unix = CVARC("sv_port_unix", "/tmp/fte.sock", SV_PortUNIX_Callback); #endif #ifdef HAVE_NATPMP -void QDECL SV_Port_NatPMP_Callback(struct cvar_s *var, char *oldvalue) +static void QDECL SV_Port_NatPMP_Callback(struct cvar_s *var, char *oldvalue) { FTENET_AddToCollection(svs.sockets, var->name, va("natpmp://%s", var->string), NA_IP, NP_NATPMP); } @@ -8034,7 +8034,7 @@ typedef struct { int readbuffered; char peer[1]; } tcpfile_t; -void VFSTCP_Error(tcpfile_t *f) +static void VFSTCP_Error(tcpfile_t *f) { if (f->sock != INVALID_SOCKET) { @@ -8193,16 +8193,16 @@ qboolean QDECL VFSTCP_Seek (struct vfsfile_s *file, qofs_t pos) VFSTCP_Error((tcpfile_t*)file); return false; } -qofs_t QDECL VFSTCP_Tell (struct vfsfile_s *file) +static qofs_t QDECL VFSTCP_Tell (struct vfsfile_s *file) { VFSTCP_Error((tcpfile_t*)file); return 0; } -qofs_t QDECL VFSTCP_GetLen (struct vfsfile_s *file) +static qofs_t QDECL VFSTCP_GetLen (struct vfsfile_s *file) { return 0; } -qboolean QDECL VFSTCP_Close (struct vfsfile_s *file) +static qboolean QDECL VFSTCP_Close (struct vfsfile_s *file) { tcpfile_t *f = (tcpfile_t *)file; qboolean success = f->sock != INVALID_SOCKET; diff --git a/engine/common/plugin.c b/engine/common/plugin.c index e6b82f01a..f4bc64988 100644 --- a/engine/common/plugin.c +++ b/engine/common/plugin.c @@ -66,9 +66,6 @@ typedef struct plugin_s { //protocol-in-a-plugin qintptr_t connectionlessclientpacket; - - //called to discolour console input text if they spelt it wrongly - qintptr_t spellcheckmaskedtext; #endif qintptr_t svmsgfunction; qintptr_t chatmsgfunction; @@ -270,7 +267,7 @@ static char *Plug_CleanName(const char *file, char *out, size_t sizeof_out) } return out; } -plugin_t *Plug_Load(const char *file, int type) +static plugin_t *Plug_Load(const char *file, int type) { char temp[MAX_OSPATH]; plugin_t *newplug; @@ -497,8 +494,6 @@ static qintptr_t VARGS Plug_ExportToEngine(void *offset, quintptr_t mask, const currentplug->chatmsgfunction = functionid; else if (!strcmp(name, "CenterPrintMessage")) currentplug->centerprintfunction = functionid; - else if (!strcmp(name, "SpellCheckMaskedText")) - currentplug->spellcheckmaskedtext = functionid; #endif else return 0; @@ -1039,7 +1034,7 @@ static qintptr_t VARGS Plug_Net_Accept(void *offset, quintptr_t mask, const qint return handle; } //EBUILTIN(int, NET_TCPConnect, (char *ip, int port)); -qintptr_t VARGS Plug_Net_TCPConnect(void *offset, quintptr_t mask, const qintptr_t *arg) +static qintptr_t VARGS Plug_Net_TCPConnect(void *offset, quintptr_t mask, const qintptr_t *arg) { char *remoteip = VM_POINTER(arg[0]); unsigned short remoteport = VM_LONG(arg[1]); @@ -1057,7 +1052,7 @@ qintptr_t VARGS Plug_Net_TCPConnect(void *offset, quintptr_t mask, const qintptr void Plug_Net_Close_Internal(int handle); #ifdef HAVE_SSL -qintptr_t VARGS Plug_Net_SetTLSClient(void *offset, quintptr_t mask, const qintptr_t *arg) +static qintptr_t VARGS Plug_Net_SetTLSClient(void *offset, quintptr_t mask, const qintptr_t *arg) { pluginstream_t *stream; unsigned int handle = VM_LONG(arg[0]); @@ -1082,7 +1077,7 @@ qintptr_t VARGS Plug_Net_SetTLSClient(void *offset, quintptr_t mask, const qintp return 0; } -qintptr_t VARGS Plug_Net_GetTLSBinding(void *offset, quintptr_t mask, const qintptr_t *arg) +static qintptr_t VARGS Plug_Net_GetTLSBinding(void *offset, quintptr_t mask, const qintptr_t *arg) { pluginstream_t *stream; unsigned int handle = VM_LONG(arg[0]); @@ -1114,7 +1109,7 @@ qintptr_t VARGS Plug_Net_GetTLSBinding(void *offset, quintptr_t mask, const qint #endif #endif -qintptr_t VARGS Plug_VFS_Open(void *offset, quintptr_t mask, const qintptr_t *arg) +static qintptr_t VARGS Plug_VFS_Open(void *offset, quintptr_t mask, const qintptr_t *arg) { char *fname = VM_POINTER(arg[0]); vfsfile_t **handle = VM_POINTER(arg[1]); @@ -1124,7 +1119,7 @@ qintptr_t VARGS Plug_VFS_Open(void *offset, quintptr_t mask, const qintptr_t *ar return true; return false; } -qintptr_t VARGS Plug_FS_NativePath(void *offset, quintptr_t mask, const qintptr_t *arg) +static qintptr_t VARGS Plug_FS_NativePath(void *offset, quintptr_t mask, const qintptr_t *arg) { const char *fname = VM_POINTER(arg[0]); enum fs_relative relativeto = VM_LONG(arg[1]); @@ -1154,7 +1149,7 @@ static qintptr_t VARGS Plug_Con_POpen(void *offset, quintptr_t mask, const qintp return handle; } -qintptr_t VARGS Plug_FS_Open(void *offset, quintptr_t mask, const qintptr_t *arg) +static qintptr_t VARGS Plug_FS_Open(void *offset, quintptr_t mask, const qintptr_t *arg) { //modes: //1: read @@ -1220,7 +1215,7 @@ qintptr_t VARGS Plug_FS_Open(void *offset, quintptr_t mask, const qintptr_t *arg *ret = handle; return VFS_GETLEN(pluginstreamarray[handle].vfs); } -qintptr_t VARGS Plug_FS_Seek(void *offset, quintptr_t mask, const qintptr_t *arg) +static qintptr_t VARGS Plug_FS_Seek(void *offset, quintptr_t mask, const qintptr_t *arg) { unsigned int handle = VM_LONG(arg[0]); unsigned int low = VM_LONG(arg[1]), high = VM_LONG(arg[2]); @@ -1235,7 +1230,7 @@ qintptr_t VARGS Plug_FS_Seek(void *offset, quintptr_t mask, const qintptr_t *arg return VFS_TELL(stream->vfs); } -qintptr_t VARGS Plug_FS_GetLength(void *offset, quintptr_t mask, const qintptr_t *arg) +static qintptr_t VARGS Plug_FS_GetLength(void *offset, quintptr_t mask, const qintptr_t *arg) { unsigned int handle = VM_LONG(arg[0]); unsigned int *low = VM_POINTER(arg[1]), *high = VM_POINTER(arg[2]); @@ -1267,7 +1262,7 @@ qintptr_t VARGS Plug_FS_GetLength(void *offset, quintptr_t mask, const qintptr_t return false; } -qintptr_t VARGS Plug_memset(void *offset, quintptr_t mask, const qintptr_t *arg) +static qintptr_t VARGS Plug_memset(void *offset, quintptr_t mask, const qintptr_t *arg) { void *p = VM_POINTER(arg[0]); @@ -1279,7 +1274,7 @@ qintptr_t VARGS Plug_memset(void *offset, quintptr_t mask, const qintptr_t *arg) return arg[0]; } -qintptr_t VARGS Plug_memcpy(void *offset, quintptr_t mask, const qintptr_t *arg) +static qintptr_t VARGS Plug_memcpy(void *offset, quintptr_t mask, const qintptr_t *arg) { void *p1 = VM_POINTER(arg[0]); void *p2 = VM_POINTER(arg[1]); @@ -1295,7 +1290,7 @@ qintptr_t VARGS Plug_memcpy(void *offset, quintptr_t mask, const qintptr_t *arg) return arg[0]; } -qintptr_t VARGS Plug_memmove(void *offset, quintptr_t mask, const qintptr_t *arg) +static qintptr_t VARGS Plug_memmove(void *offset, quintptr_t mask, const qintptr_t *arg) { void *p1 = VM_POINTER(arg[0]); void *p2 = VM_POINTER(arg[1]); @@ -1312,7 +1307,7 @@ qintptr_t VARGS Plug_memmove(void *offset, quintptr_t mask, const qintptr_t *arg return arg[0]; } -qintptr_t VARGS Plug_sqrt(void *offset, quintptr_t mask, const qintptr_t *arg) +static qintptr_t VARGS Plug_sqrt(void *offset, quintptr_t mask, const qintptr_t *arg) { union { qintptr_t i; @@ -1321,7 +1316,7 @@ qintptr_t VARGS Plug_sqrt(void *offset, quintptr_t mask, const qintptr_t *arg) ret.f = sqrt(VM_FLOAT(arg[0])); return ret.i; } -qintptr_t VARGS Plug_sin(void *offset, quintptr_t mask, const qintptr_t *arg) +static qintptr_t VARGS Plug_sin(void *offset, quintptr_t mask, const qintptr_t *arg) { union { qintptr_t i; @@ -1330,7 +1325,7 @@ qintptr_t VARGS Plug_sin(void *offset, quintptr_t mask, const qintptr_t *arg) ret.f = sin(VM_FLOAT(arg[0])); return ret.i; } -qintptr_t VARGS Plug_cos(void *offset, quintptr_t mask, const qintptr_t *arg) +static qintptr_t VARGS Plug_cos(void *offset, quintptr_t mask, const qintptr_t *arg) { union { qintptr_t i; @@ -1339,7 +1334,7 @@ qintptr_t VARGS Plug_cos(void *offset, quintptr_t mask, const qintptr_t *arg) ret.f = cos(VM_FLOAT(arg[0])); return ret.i; } -qintptr_t VARGS Plug_atan2(void *offset, quintptr_t mask, const qintptr_t *arg) +static qintptr_t VARGS Plug_atan2(void *offset, quintptr_t mask, const qintptr_t *arg) { union { qintptr_t i; @@ -1387,7 +1382,7 @@ void Plug_Net_Close_Internal(int handle) pluginstreamarray[handle].type = STREAM_NONE; pluginstreamarray[handle].plugin = NULL; } -qintptr_t VARGS Plug_Net_Recv(void *offset, quintptr_t mask, const qintptr_t *arg) +static qintptr_t VARGS Plug_Net_Recv(void *offset, quintptr_t mask, const qintptr_t *arg) { int read; int handle = VM_LONG(arg[0]); @@ -1423,7 +1418,7 @@ qintptr_t VARGS Plug_Net_Recv(void *offset, quintptr_t mask, const qintptr_t *ar return -2; } } -qintptr_t VARGS Plug_Net_Send(void *offset, quintptr_t mask, const qintptr_t *arg) +static qintptr_t VARGS Plug_Net_Send(void *offset, quintptr_t mask, const qintptr_t *arg) { int written; int handle = VM_LONG(arg[0]); @@ -1455,7 +1450,7 @@ qintptr_t VARGS Plug_Net_Send(void *offset, quintptr_t mask, const qintptr_t *ar return -2; } } -qintptr_t VARGS Plug_Net_SendTo(void *offset, quintptr_t mask, const qintptr_t *arg) +static qintptr_t VARGS Plug_Net_SendTo(void *offset, quintptr_t mask, const qintptr_t *arg) { int written; int handle = VM_LONG(arg[0]); @@ -1496,7 +1491,7 @@ qintptr_t VARGS Plug_Net_SendTo(void *offset, quintptr_t mask, const qintptr_t * return -2; } } -qintptr_t VARGS Plug_Net_Close(void *offset, quintptr_t mask, const qintptr_t *arg) +static qintptr_t VARGS Plug_Net_Close(void *offset, quintptr_t mask, const qintptr_t *arg) { int handle = VM_LONG(arg[0]); if (handle < 0 || handle >= pluginstreamarraylen || pluginstreamarray[handle].plugin != currentplug) @@ -1506,7 +1501,7 @@ qintptr_t VARGS Plug_Net_Close(void *offset, quintptr_t mask, const qintptr_t *a return 0; } -qintptr_t VARGS Plug_ReadInputBuffer(void *offset, quintptr_t mask, const qintptr_t *arg) +static qintptr_t VARGS Plug_ReadInputBuffer(void *offset, quintptr_t mask, const qintptr_t *arg) { void *buffer = VM_POINTER(arg[0]); int bufferlen = VM_LONG(arg[1]); @@ -1515,7 +1510,7 @@ qintptr_t VARGS Plug_ReadInputBuffer(void *offset, quintptr_t mask, const qintpt memcpy(buffer, currentplug->inputptr, currentplug->inputbytes); return bufferlen; } -qintptr_t VARGS Plug_UpdateInputBuffer(void *offset, quintptr_t mask, const qintptr_t *arg) +static qintptr_t VARGS Plug_UpdateInputBuffer(void *offset, quintptr_t mask, const qintptr_t *arg) { void *buffer = VM_POINTER(arg[0]); int bufferlen = VM_LONG(arg[1]); @@ -1528,7 +1523,7 @@ qintptr_t VARGS Plug_UpdateInputBuffer(void *offset, quintptr_t mask, const qint #ifdef USERBE #include "pr_common.h" //functions useful for rigid body engines. -qintptr_t VARGS Plug_RBE_GetPluginFuncs(void *offset, quintptr_t mask, const qintptr_t *arg) +static qintptr_t VARGS Plug_RBE_GetPluginFuncs(void *offset, quintptr_t mask, const qintptr_t *arg) { static rbeplugfuncs_t funcs = { @@ -1553,7 +1548,7 @@ qintptr_t VARGS Plug_RBE_GetPluginFuncs(void *offset, quintptr_t mask, const qin void Plug_CloseAll_f(void); void Plug_List_f(void); void Plug_Close_f(void); -void Plug_Load_f(void) +static void Plug_Load_f(void) { char *plugin; plugin = Cmd_Argv(1); @@ -1844,23 +1839,6 @@ int Plug_SubConsoleCommand(console_t *con, char *line) currentplug = oldplug; return ret; } - -void Plug_SpellCheckMaskedText(unsigned int *maskedstring, int maskedchars, int x, int y, int cs, int firstc, int charlimit) -{ - plugin_t *oldplug = currentplug; - for (currentplug = plugs; currentplug; currentplug = currentplug->next) - { - if (currentplug->spellcheckmaskedtext) - { - currentplug->inputptr = maskedstring; - currentplug->inputbytes = sizeof(*maskedstring)*maskedchars; - VM_Call(currentplug->vm, currentplug->spellcheckmaskedtext, x, y, cs, firstc, charlimit); - currentplug->inputptr = NULL; - currentplug->inputbytes = 0; - } - } - currentplug = oldplug; -} #endif #ifndef SERVERONLY diff --git a/engine/common/pmove.c b/engine/common/pmove.c index cacfbc78c..48d9497d4 100644 --- a/engine/common/pmove.c +++ b/engine/common/pmove.c @@ -975,6 +975,7 @@ void PM_CategorizePosition (void) pmove.watertype = FTECONTENTS_EMPTY; //FIXME: gravitydir + VectorCopy(pmove.origin, point); point[2] = pmove.origin[2] + pmove.player_mins[2] + 1; cont = PM_PointContents (point); @@ -1058,7 +1059,7 @@ void PM_CategorizePosition (void) PM_CheckJump ============= */ -void PM_CheckJump (void) +static void PM_CheckJump (void) { if (pmove.pm_type == PM_FLY) return; @@ -1130,7 +1131,7 @@ void PM_CheckJump (void) PM_CheckWaterJump ============= */ -void PM_CheckWaterJump (void) +static void PM_CheckWaterJump (void) { vec3_t spot, spot2; // int cont; @@ -1210,7 +1211,7 @@ try nudging slightly on all axis to allow for the cut precision of the net coordinates ================= */ -void PM_NudgePosition (void) +static void PM_NudgePosition (void) { vec3_t base; int x, y, z; diff --git a/engine/common/pmovetst.c b/engine/common/pmovetst.c index 5ea04c852..d7a0cb5de 100644 --- a/engine/common/pmovetst.c +++ b/engine/common/pmovetst.c @@ -70,7 +70,7 @@ To keep everything totally uniform, bounding boxes are turned into small BSP trees instead of being compared directly. =================== */ -hull_t *PM_HullForBox (vec3_t mins, vec3_t maxs) +static hull_t *PM_HullForBox (vec3_t mins, vec3_t maxs) { box_planes[0].dist = maxs[0]; box_planes[1].dist = mins[0]; @@ -83,7 +83,7 @@ hull_t *PM_HullForBox (vec3_t mins, vec3_t maxs) } -int PM_TransformedModelPointContents (model_t *mod, vec3_t p, vec3_t origin, vec3_t angles) +static int PM_TransformedModelPointContents (model_t *mod, vec3_t p, vec3_t origin, vec3_t angles) { vec3_t p_l, axis[3]; VectorSubtract (p, origin, p_l); diff --git a/engine/common/pr_bgcmd.c b/engine/common/pr_bgcmd.c index 8e745c5a5..7bb7706e8 100644 --- a/engine/common/pr_bgcmd.c +++ b/engine/common/pr_bgcmd.c @@ -2535,7 +2535,6 @@ void QCBUILTIN PF_whichpack (pubprogfuncs_t *prinst, struct globalvars_s *pr_glo typedef struct prvmsearch_s { - int handle; pubprogfuncs_t *fromprogs; //share across menu/server int entries; struct @@ -2544,87 +2543,64 @@ typedef struct prvmsearch_s { qofs_t size; time_t mtime; } *entry; - struct prvmsearch_s *next; + char *pattern; } prvmsearch_t; -prvmsearch_t *prvmsearches; -int prvm_nextsearchhandle; +prvmsearch_t *pr_searches; //realloced to extend +size_t numpr_searches; void search_close (pubprogfuncs_t *prinst, int handle) { int i; - prvmsearch_t *prev, *s; + prvmsearch_t *s; - prev = NULL; - for (s = prvmsearches; s; ) + if (handle < 0 || handle >= numpr_searches || pr_searches[handle].fromprogs != prinst) { - if (s->handle == handle) - { //close it down. - if (s->fromprogs != prinst) - { - PF_Warningf(prinst, "Handle wasn't valid with that progs\n"); - return; - } - if (prev) - prev->next = s->next; - else - prvmsearches = s->next; - - for (i = 0; i < s->entries; i++) - { - BZ_Free(s->entry[i].name); - } - BZ_Free(s->entry); - BZ_Free(s); - - return; - } - - prev = s; - s = s->next; + PF_Warningf(prinst, "search_close: Invalid search handle %i\n", handle); + return; } + s = &pr_searches[handle]; + + for (i = 0; i < s->entries; i++) + BZ_Free(s->entry[i].name); + Z_Free(s->pattern); + BZ_Free(s->entry); + memset(s, 0, sizeof(*s)); } //a progs was closed... hunt down it's searches, and warn about any searches left open. void search_close_progs(pubprogfuncs_t *prinst, qboolean complain) { - int i; - prvmsearch_t *prev, *s; + int i, j; + prvmsearch_t *s; + qboolean stillactive = false; - prev = NULL; - for (s = prvmsearches; s; ) + for (j = 0; j < numpr_searches; j++) { + s = &pr_searches[j]; if (s->fromprogs == prinst) { //close it down. if (complain) - Con_Printf("Warning: Progs search was still active\n"); - if (prev) - prev->next = s->next; - else - prvmsearches = s->next; + Con_DPrintf("Warning: Progs search was still active (pattern: %s)\n", s->pattern); for (i = 0; i < s->entries; i++) - { BZ_Free(s->entry[i].name); - } + Z_Free(s->pattern); BZ_Free(s->entry); - BZ_Free(s); - - if (prev) - s = prev->next; - else - s = prvmsearches; - continue; + memset(s, 0, sizeof(*s)); } - - prev = s; - s = s->next; + else if (s->fromprogs) + stillactive = true; } - if (!prvmsearches) - prvm_nextsearchhandle = 0; //might as well. + if (!stillactive) + { //none left, we might as well release the memory. + BZ_Free(pr_searches); + pr_searches = NULL; + numpr_searches = 0; + } } -int QDECL search_enumerate(const char *name, qofs_t fsize, time_t mtime, void *parm, searchpathfuncs_t *spath) +static int QDECL search_enumerate(const char *name, qofs_t fsize, time_t mtime, void *parm, searchpathfuncs_t *spath) { prvmsearch_t *s = parm; @@ -2653,6 +2629,7 @@ void QCBUILTIN PF_search_begin (pubprogfuncs_t *prinst, struct globalvars_s *pr_ // qboolean caseinsensitive = G_FLOAT(OFS_PARM1); // qboolean quiet = G_FLOAT(OFS_PARM2); prvmsearch_t *s; + size_t j; if (!*pattern || (*pattern == '.' && pattern[1] == '.') || *pattern == '/' || *pattern == '\\' || strchr(pattern, ':')) { @@ -2661,15 +2638,24 @@ void QCBUILTIN PF_search_begin (pubprogfuncs_t *prinst, struct globalvars_s *pr_ return; } - s = Z_Malloc(sizeof(*s)); - s->fromprogs = prinst; - s->handle = prvm_nextsearchhandle++; + for (j = 0; j < numpr_searches; j++) + if (!pr_searches[j].fromprogs) + break; + if (j == numpr_searches) + { + if (!ZF_ReallocElements((void**)&pr_searches, &numpr_searches, j+1, sizeof(*s))) + { //o.O + G_FLOAT(OFS_RETURN) = -1; + return; + } + } + s = &pr_searches[j]; + s->pattern = Z_StrDup(pattern); + s->fromprogs = prinst; COM_EnumerateFiles(pattern, search_enumerate, s); - s->next = prvmsearches; - prvmsearches = s; - G_FLOAT(OFS_RETURN) = s->handle; + G_FLOAT(OFS_RETURN) = j; } //void search_end(float handle) = #75; void QCBUILTIN PF_search_end (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) @@ -2683,20 +2669,15 @@ void QCBUILTIN PF_search_getsize (pubprogfuncs_t *prinst, struct globalvars_s *p int handle = G_FLOAT(OFS_PARM0); prvmsearch_t *s; G_FLOAT(OFS_RETURN) = 0; - for (s = prvmsearches; s; s = s->next) - { - if (s->handle == handle) - { //close it down. - if (s->fromprogs != prinst) - { - PF_Warningf(prinst, "Handle wasn't valid with that progs\n"); - return; - } - G_FLOAT(OFS_RETURN) = s->entries; - return; - } + if (handle < 0 || handle >= numpr_searches || pr_searches[handle].fromprogs != prinst) + { + PF_Warningf(prinst, "PF_search_getsize: Invalid search handle %i\n", handle); + return; } + s = &pr_searches[handle]; + + G_FLOAT(OFS_RETURN) = s->entries; } //string search_getfilename(float handle, float num) = #77; void QCBUILTIN PF_search_getfilename (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) @@ -2706,24 +2687,16 @@ void QCBUILTIN PF_search_getfilename (pubprogfuncs_t *prinst, struct globalvars_ prvmsearch_t *s; G_INT(OFS_RETURN) = 0; - for (s = prvmsearches; s; s = s->next) + if (handle < 0 || handle >= numpr_searches || pr_searches[handle].fromprogs != prinst) { - if (s->handle == handle) - { //close it down. - if (s->fromprogs != prinst) - { - PF_Warningf(prinst, "Search handle wasn't valid with that progs\n"); - return; - } - - if (num < 0 || num >= s->entries) - return; - RETURN_TSTRING(s->entry[num].name); - return; - } + PF_Warningf(prinst, "PF_search_getfilename: Invalid search handle %i\n", handle); + return; } + s = &pr_searches[handle]; - PF_Warningf(prinst, "Search handle wasn't valid\n"); + if (num < 0 || num >= s->entries) + return; + RETURN_TSTRING(s->entry[num].name); } void QCBUILTIN PF_search_getfilesize (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { @@ -2732,24 +2705,16 @@ void QCBUILTIN PF_search_getfilesize (pubprogfuncs_t *prinst, struct globalvars_ prvmsearch_t *s; G_INT(OFS_RETURN) = 0; - for (s = prvmsearches; s; s = s->next) + if (handle < 0 || handle >= numpr_searches || pr_searches[handle].fromprogs != prinst) { - if (s->handle == handle) - { //close it down. - if (s->fromprogs != prinst) - { - PF_Warningf(prinst, "Search handle wasn't valid with that progs\n"); - return; - } - - if (num < 0 || num >= s->entries) - return; - G_FLOAT(OFS_RETURN) = s->entry[num].size; - return; - } + PF_Warningf(prinst, "PF_search_getfilesize: Invalid search handle %i\n", handle); + return; } + s = &pr_searches[handle]; - PF_Warningf(prinst, "Search handle wasn't valid\n"); + if (num < 0 || num >= s->entries) + return; + G_FLOAT(OFS_RETURN) = s->entry[num].size; } void QCBUILTIN PF_search_getfilemtime (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { @@ -2759,28 +2724,20 @@ void QCBUILTIN PF_search_getfilemtime (pubprogfuncs_t *prinst, struct globalvars char timestr[128]; G_INT(OFS_RETURN) = 0; - for (s = prvmsearches; s; s = s->next) + if (handle < 0 || handle >= numpr_searches || pr_searches[handle].fromprogs != prinst) { - if (s->handle == handle) - { //close it down. - if (s->fromprogs != prinst) - { - PF_Warningf(prinst, "Search handle wasn't valid with that progs\n"); - return; - } - - if (num < 0 || num >= s->entries) - return; - if (s->entry[num].mtime != 0) //return null/empty if the time isn't set/known. - { - strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S", localtime(&s->entry[num].mtime)); - RETURN_TSTRING(timestr); - } - return; - } + PF_Warningf(prinst, "PF_search_getfilemtime: Invalid search handle %i\n", handle); + return; } + s = &pr_searches[handle]; - PF_Warningf(prinst, "Search handle wasn't valid\n"); + if (num < 0 || num >= s->entries) + return; + if (s->entry[num].mtime != 0) //return null/empty if the time isn't set/known. + { + strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S", localtime(&s->entry[num].mtime)); + RETURN_TSTRING(timestr); + } } //closes filesystem type stuff for when a progs has stopped needing it. @@ -3981,19 +3938,101 @@ size_t strbufmax; static void PR_buf_savegame(vfsfile_t *f, pubprogfuncs_t *prinst, qboolean binary) { unsigned int i, bufno; + char *tmp = NULL; + size_t tmpsize = 0, ns; for (bufno = 0; bufno < strbufmax; bufno++) { if (strbuflist[bufno].prinst == prinst && (strbuflist[bufno].flags & BUFFLAG_SAVED)) { - VFS_PRINTF (f, "buffer %u %i %i %u\n", bufno, 1, ev_string, (unsigned int)strbuflist[bufno].used); + VFS_PRINTF (f, "buffer %u %i %i %u\n", bufno+BUFSTRBASE, strbuflist[bufno].flags, ev_string, (unsigned int)strbuflist[bufno].used); VFS_PRINTF (f, "{\n"); for (i = 0; i < strbuflist[bufno].used; i++) if (strbuflist[bufno].strings[i]) - VFS_PRINTF (f, "%u %s\n", i, strbuflist[bufno].strings[i]); + { + ns = strlen(strbuflist[bufno].strings[i])*2 + 4; + if (ns > tmpsize) + Z_ReallocElements((void**)&tmp, &tmpsize, ns, sizeof(char)); + VFS_PRINTF (f, "%u %s\n", i, COM_QuotedString(strbuflist[bufno].strings[i], tmp, tmpsize, false)); + } VFS_PRINTF (f, "}\n"); } } + free(tmp); +} +static const char *PR_buf_loadgame(pubprogfuncs_t *prinst, const char *l) +{ + char token[65536]; + int bufno; + unsigned int flags; + size_t buffersize, index; + com_tokentype_t tt; + struct strbuf *buf; + l = COM_ParseTokenOut(l, NULL, token, sizeof(token), &tt);if (tt != TTP_RAWTOKEN)return NULL; + bufno = atoi(token)-BUFSTRBASE; + l = COM_ParseTokenOut(l, NULL, token, sizeof(token), &tt);if (tt != TTP_RAWTOKEN)return NULL; + flags = atoi(token); + l = COM_ParseTokenOut(l, NULL, token, sizeof(token), &tt);if (tt != TTP_RAWTOKEN)return NULL; + if (atoi(token) != ev_string) return NULL; //we only support string buffers right now. FIXME: if the token was "string" then create an empty strbuf. + l = COM_ParseTokenOut(l, NULL, token, sizeof(token), &tt);if (tt != TTP_RAWTOKEN)return NULL; + buffersize = atoi(token); + + l = COM_ParseTokenOut(l, NULL, token, sizeof(token), &tt);if (tt != TTP_LINEENDING)return NULL; + l = COM_ParseTokenOut(l, NULL, token, sizeof(token), &tt);if (tt != TTP_PUNCTUATION)return NULL; + if (strcmp(token, "{")) return NULL; + + if (bufno < 0 || bufno >= 1<<16) + return NULL; + if (bufno >= strbufmax) + Z_ReallocElements((void**)&strbuflist, &strbufmax, bufno+1, sizeof(*strbuflist)); + + buf = &strbuflist[bufno]; + if (buf->prinst) + { //already alive... wipe it. + for (index = 0; index < buf->used; index++) + Z_Free(buf->strings[index]); + Z_Free(buf->strings); + + buf->strings = NULL; + buf->used = 0; + buf->allocated = 0; + } + buf->prinst = prinst; + buf->flags = flags; + + if (buffersize) + { //preallocate the buffer to match what it used to be. + if (buffersize < 1<<20) + { + Z_ReallocElements((void**)&buf->strings, &buf->allocated, buffersize, sizeof(*buf->strings)); + buf->used = buf->allocated; + } + } + + for(;;) + { + l = COM_ParseTokenOut(l, NULL, token, sizeof(token), &tt); + if (tt == TTP_LINEENDING) + continue; + if (tt == TTP_PUNCTUATION && !strcmp(token, "}")) + break; + if (tt != TTP_RAWTOKEN) + break; + index = atoi(token); + l = COM_ParseTokenOut(l, NULL, token, sizeof(token), &tt);if (tt != TTP_STRING)return false; + + if (index < 0 || index >= buf->allocated) + continue; //some sort of error. + + if (buf->strings[index]) //shouldn't really happen, but just in case we're given bad input... + Z_Free(buf->strings[index]); + buf->strings[index] = Z_Malloc(strlen(token)+1); + strcpy(buf->strings[index], token); + + if (index >= buf->used) + buf->used = index+1; + } + return l; } void PF_buf_shutdown(pubprogfuncs_t *prinst) @@ -4278,7 +4317,7 @@ void QCBUILTIN PF_bufstr_set (pubprogfuncs_t *prinst, struct globalvars_s *pr_g strbuflist[bufno].used = index+1; } -size_t PF_bufstr_add_internal(int bufno, const char *string, int appendonend) +static size_t PF_bufstr_add_internal(int bufno, const char *string, int appendonend) { size_t index; if (appendonend) @@ -4476,7 +4515,7 @@ void QCBUILTIN PF_crc16 (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals G_FLOAT(OFS_RETURN) = QCRC_Block(str, len); } -void QCBUILTIN PF_digest_internal (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals, const char *hashtype, const void *str, size_t len) +static void QCBUILTIN PF_digest_internal (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals, const char *hashtype, const void *str, size_t len) { int digestsize, i; unsigned char digest[64]; @@ -6338,6 +6377,21 @@ void PR_Common_Shutdown(pubprogfuncs_t *progs, qboolean errored) #endif tokenize_flush(); } + +qboolean PR_Common_LoadGame(pubprogfuncs_t *prinst, char *command, const char **file) +{ + const char *l = *file; + if (!strcmp(command, "buffer")) + { + l = PR_buf_loadgame(prinst, l); + if (!l) + return false; + } + else + return false; + *file = l; + return true; +} void PR_Common_SaveGame(vfsfile_t *f, pubprogfuncs_t *prinst, qboolean binary) { PR_buf_savegame(f, prinst, binary); @@ -6411,7 +6465,7 @@ void PR_AutoCvar(pubprogfuncs_t *prinst, cvar_t *var) } } -void PDECL PR_FoundAutoCvarGlobal(pubprogfuncs_t *progfuncs, char *name, eval_t *val, etype_t type, void *ctx) +static void PDECL PR_FoundAutoCvarGlobal(pubprogfuncs_t *progfuncs, char *name, eval_t *val, etype_t type, void *ctx) { cvar_t *var; const char *vals; diff --git a/engine/common/pr_common.h b/engine/common/pr_common.h index 462dfd38a..90c656450 100644 --- a/engine/common/pr_common.h +++ b/engine/common/pr_common.h @@ -304,7 +304,7 @@ void QCBUILTIN PF_setattachment(pubprogfuncs_t *prinst, struct globalvars_s *pr_ void skel_dodelete(world_t *world); void skel_reset(world_t *world); void skel_reload(void); - void skel_updateentbounds(); + void skel_updateentbounds(world_t *w, wedict_t *ent); #endif void QCBUILTIN PF_physics_supported(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_physics_enable(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); @@ -519,6 +519,7 @@ void QCBUILTIN PF_whichpack (pubprogfuncs_t *prinst, struct globalvars_s *pr_glo int QDECL QCEditor (pubprogfuncs_t *prinst, const char *filename, int *line, int *statement, char *reason, pbool fatal); void PR_Common_Shutdown(pubprogfuncs_t *progs, qboolean errored); void PR_Common_SaveGame(vfsfile_t *f, pubprogfuncs_t *prinst, qboolean binary); +qboolean PR_Common_LoadGame(pubprogfuncs_t *prinst, char *command, const char **file); uploadfmt_t PR_TranslateTextureFormat(int qcformat); diff --git a/engine/common/sys.h b/engine/common/sys.h index 6a538dcc1..8f9052c69 100644 --- a/engine/common/sys.h +++ b/engine/common/sys.h @@ -74,9 +74,13 @@ qboolean Sys_RandomBytes(qbyte *string, int len); char *Sys_ConsoleInput (void); -char *Sys_GetClipboard(void); //A stub would return NULL -void Sys_CloseClipboard(char *buf); //a stub would do nothing -void Sys_SaveClipboard(char *text); //a stub would do nothing. +typedef enum +{ + CBT_SELECTION, //select-to-copy, middle-to-paste + CBT_CLIPBOARD //ctrl+c, ctrl+v +} clipboardtype_t; +void Sys_Clipboard_PasteText(clipboardtype_t clipboardtype, void (*callback)(void *cb, char *utf8), void *ctx); //calls the callback once the text is available (maybe instantly). utf8 arg may be NULL if the clipboard was unavailable. +void Sys_SaveClipboard(clipboardtype_t clipboardtype, char *text); //a stub would do nothing. //stuff for dynamic dedicated console -> gfx and back. void Sys_CloseTerminal (void); diff --git a/engine/common/zone.c b/engine/common/zone.c index 7a4cffcba..a4d779efc 100644 --- a/engine/common/zone.c +++ b/engine/common/zone.c @@ -31,9 +31,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #endif //must be multiple of 4. -#define TEMPDEBUG 4 -#define ZONEDEBUG 4 -#define HUNKDEBUG 4 +//#define TEMPDEBUG 4 +//#define ZONEDEBUG 4 +//#define HUNKDEBUG 4 //these need to be defined because it makes some bits of code simpler #ifndef HUNKDEBUG @@ -197,8 +197,6 @@ void *ZF_Malloc(int size) void *ret = NULL; if (!posix_memalign(&ret, max(sizeof(float)*4, sizeof(void*)), size)) memset(ret, 0, size); - else - ret = NULL; return ret; #else return calloc(size, 1); diff --git a/engine/gl/gl_alias.c b/engine/gl/gl_alias.c index 0258aee3e..916dddad1 100644 --- a/engine/gl/gl_alias.c +++ b/engine/gl/gl_alias.c @@ -1685,7 +1685,7 @@ void R_GAlias_GenerateBatches(entity_t *e, batch_t **batches) texnums_t *skin; - if ((r_refdef.externalview || r_refdef.recurse) && e->flags & RF_WEAPONMODEL) + if ((r_refdef.externalview || r_refdef.recurse) && (e->flags & RF_WEAPONMODEL)) return; clmodel = e->model; @@ -2758,6 +2758,7 @@ void BE_GenModelBatches(batch_t **batches, const dlight_t *dl, unsigned int bemo unsigned int orig_numvisedicts = cl_numvisedicts; // unsigned int orig_numstrisidx = cl_numstrisidx; // unsigned int orig_numstrisvert = cl_numstrisvert; + extern cvar_t chase_active; //I fucking hate this cvar. die die die. /*clear the batch list*/ for (i = 0; i < SHADER_SORT_COUNT; i++) @@ -2792,7 +2793,7 @@ void BE_GenModelBatches(batch_t **batches, const dlight_t *dl, unsigned int bemo { ent = &cl_visedicts[i]; - if (!r_refdef.externalview && (ent->flags & RF_EXTERNALMODEL)) + if (!r_refdef.externalview && (ent->flags & RF_EXTERNALMODEL) && !chase_active.ival) continue; #ifdef RTLIGHTS diff --git a/engine/gl/gl_font.c b/engine/gl/gl_font.c index 940d09a28..cc44d7f51 100644 --- a/engine/gl/gl_font.c +++ b/engine/gl/gl_font.c @@ -22,11 +22,16 @@ void Font_BeginScaledString(struct font_s *font, float vx, float vy, float szx, void Font_Transform(float vx, float vy, int *px, int *py); int Font_CharHeight(void); float Font_CharScaleHeight(void); + +//FIXME: if we want to do emoji properly, then we're going to need support for variants somehow +// easiest is probably to make the next codepoint available too (and consumable) +// handling variants in the font cache is another issue. gah. not worth it. int Font_CharWidth(unsigned int charflags, unsigned int codepoint); float Font_CharScaleWidth(unsigned int charflags, unsigned int codepoint); int Font_CharEndCoord(struct font_s *font, int x, unsigned int charflags, unsigned int codepoint); int Font_DrawChar(int px, int py, unsigned int charflags, unsigned int codepoint); float Font_DrawScaleChar(float px, float py, unsigned int charflags, unsigned int codepoint); /*avoid using*/ + void Font_EndString(struct font_s *font); int Font_LineBreaks(conchar_t *start, conchar_t *end, int maxpixelwidth, int maxlines, conchar_t **starts, conchar_t **ends); struct font_s *font_default; @@ -251,6 +256,7 @@ typedef struct fontface_s struct { int activeheight; //needs reconfiguring when different sizes are used + int actualsize; //sometimes that activeheight isn't usable. :( FT_Face face; void *membuf; } ft; @@ -676,7 +682,8 @@ static struct charcache_s *Font_LoadGlyphData(font_t *f, CHARIDXTYPE charidx, FT } } else if ((unsigned int)pixelmode == FT_PIXEL_MODE_RGBA_SA) - { //rgba font + { //rgba source using standard alpha. + //(we'll multiply out the alpha for the gpu) for (y = -pad; y < 0; y++) { for (x = -pad; x < (int)bmw+pad; x++) @@ -1056,15 +1063,31 @@ static struct charcache_s *Font_TryLoadGlyph(font_t *f, CHARIDXTYPE charidx) { FT_Face face = qface->ft.face; -// if (qface->activeheight) - if (qface->ft.activeheight != f->charheight) - { - qface->ft.activeheight = f->charheight; -// if (FT_HAS_FIXED_SIZES(face)) -// pFT_Select_Size(face, 0); -// else - pFT_Set_Pixel_Sizes(face, 0, f->charheight); + if (qface->ft.activeheight != f->charheight) + { + qface->ft.activeheight = f->charheight; + if (FT_HAS_FIXED_SIZES(face)) + { //freetype doesn't like scaling these for us, so we have to pick a usable size ourselves. + FT_Int best = 0, s; + int bestheight = 0, h; + for (s = 0; s < qface->ft.face->num_fixed_sizes; s++) + { + h = qface->ft.face->available_sizes[s].height; + if (h >= f->charheight && h < bestheight) + { + bestheight = h; + best = s; + } + } + qface->ft.actualsize = qface->ft.face->available_sizes[best].height; + pFT_Select_Size(face, best); } + else + { + pFT_Set_Pixel_Sizes(face, 0, f->charheight); + qface->ft.actualsize = f->charheight; + } + } if (charidx == 0xfffe || pFT_Get_Char_Index(face, charidx)) //ignore glyph 0 (undefined) if (pFT_Load_Char(face, charidx, FT_LOAD_RENDER|FT_LOAD_COLOR) == 0) { @@ -1073,14 +1096,28 @@ static struct charcache_s *Font_TryLoadGlyph(font_t *f, CHARIDXTYPE charidx) slot = face->glyph; bm = &slot->bitmap; - if (!qface->ft.activeheight && bm->pixel_mode == FT_PIXEL_MODE_BGRA) + if (qface->ft.activeheight!=qface->ft.actualsize) { - unsigned int *out = alloca(f->charheight*f->charheight*4); - Image_ResampleTexture((void*)bm->buffer, bm->width, bm->rows, out, f->charheight, f->charheight); - c = Font_LoadGlyphData(f, charidx, bm->pixel_mode, out, f->charheight, f->charheight, f->charheight*4); + //I'm just going to assume full-height raster glyphs here. I'm sure I'll be proven wrong some time but w/e. + int nh = f->charheight; + int nw = (bm->width*nh)/bm->rows; + if (bm->pixel_mode == FT_PIXEL_MODE_BGRA) + { + unsigned int *out = alloca(nw*nh*sizeof(*out)); + Image_ResampleTexture((void*)bm->buffer, bm->width, bm->rows, out, nw, nh); + c = Font_LoadGlyphData(f, charidx, bm->pixel_mode, out, nw, nh, nw*sizeof(*out)); + } + else if (bm->pixel_mode == FT_PIXEL_MODE_GRAY) + { + unsigned char *out = alloca(nw*nh*sizeof(*out)); + Image_ResampleTexture8((void*)bm->buffer, bm->width, bm->rows, out, nw, nh); + c = Font_LoadGlyphData(f, charidx, bm->pixel_mode, out, nw, nh, nw*sizeof(*out)); + } + else + c = NULL; if (c) { - c->advance = f->charheight; + c->advance = nw; c->left = 0; c->top = 0; return c; @@ -1088,7 +1125,7 @@ static struct charcache_s *Font_TryLoadGlyph(font_t *f, CHARIDXTYPE charidx) } else { - c = Font_LoadGlyphData(f, charidx, bm->pixel_mode, bm->buffer, bm->width, bm->rows, bm->pitch); + c = Font_LoadGlyphData(f, charidx, bm->pixel_mode, bm->buffer, bm->width, bm->rows, bm->pitch); if (c) { @@ -1476,6 +1513,13 @@ qboolean Font_LoadFreeTypeFont(struct font_s *f, int height, const char *fontfil error = pFT_New_Face(fontlib, va("%s/%s.ttf", fontdir, fontfilename), 0, &face); } } +#else + if (error) + { //eg: /usr/share/fonts/truetype/droid/DroidSansFallbackFull.ttf + error = pFT_New_Face(fontlib, va("/usr/share/fonts/%s", fontfilename), 0, &face); + if (error) + error = pFT_New_Face(fontlib, va("/usr/share/fonts/truetype/%s.ttf", fontfilename), 0, &face); + } #endif if (!error) { @@ -1496,7 +1540,7 @@ qboolean Font_LoadFreeTypeFont(struct font_s *f, int height, const char *fontfil if (qface->fnext) qface->fnext->flink = &qface->fnext; qface->ft.face = face; - qface->ft.activeheight = height; + qface->ft.activeheight = qface->ft.actualsize = height; qface->ft.membuf = fbase; qface->refs++; Q_strncpyz(qface->name, fontfilename, sizeof(qface->name)); @@ -1680,8 +1724,8 @@ static texid_t Font_LoadFallbackConchars(void) qbyte *lump; uploadfmt_t format; lump = ReadTargaFile(default_conchar, sizeof(default_conchar), &width, &height, &format, false, PTI_INVALID); - if (!lump || format != PTI_RGBA8) - Sys_Error("Corrupt internal drawchars"); + if (!lump || (format != PTI_RGBX8 && format != PTI_RGBA8 && format != PTI_LLLX8)) + Sys_Error("Corrupt internal drawchars (%i)", format); /*convert greyscale to alpha*/ for (i = 0; i < width*height; i++) { diff --git a/engine/gl/gl_heightmap.c b/engine/gl/gl_heightmap.c index d98756225..4d58c9f8b 100644 --- a/engine/gl/gl_heightmap.c +++ b/engine/gl/gl_heightmap.c @@ -4093,106 +4093,111 @@ qboolean Heightmap_Trace(struct model_s *model, int hulloverride, framestate_t * Heightmap_Trace_Square(&hmtrace, x, y); } - //make sure the start tile is valid - for (y = floor(pos[1] + emins[1]); y <= ceil(pos[1] + emaxs[1]); y++) - for (x = floor(pos[0] + emins[0]); x <= ceil(pos[0] + emaxs[0]); x++) - Heightmap_Trace_Square(&hmtrace, x, y); - - //now walk over the terrain - if (hmtrace.end[0] != hmtrace.start[0] || hmtrace.end[1] != hmtrace.start[1]) + //trace against the heightmap, if it exists. + if (hmtrace.hm->maxsegx != hmtrace.hm->firstsegx) { - vec2_t dir, trstart, trdist; + //make sure the start tile is valid + for (y = floor(pos[1] + emins[1]); y <= ceil(pos[1] + emaxs[1]); y++) + for (x = floor(pos[0] + emins[0]); x <= ceil(pos[0] + emaxs[0]); x++) + Heightmap_Trace_Square(&hmtrace, x, y); - //figure out the leading point - for (axis = 0; axis < 2; axis++) + //now walk over the terrain + if (hmtrace.end[0] != hmtrace.start[0] || hmtrace.end[1] != hmtrace.start[1]) { - trdist[axis] = hmtrace.end[axis]-hmtrace.start[axis]; - dir[axis] = (hmtrace.end[axis] - hmtrace.start[axis])/hmtrace.htilesize; + vec2_t dir, trstart, trdist; - if (dir[axis] > 0) - { - ipos[axis] = pos[axis] + emins[axis]; - trstart[axis] = CHUNKBIAS*hmtrace.hm->sectionsize + (maxs[axis]) + hmtrace.start[axis]; - } - else - { - ipos[axis] = pos[axis] + emaxs[axis]; - trstart[axis] = CHUNKBIAS*hmtrace.hm->sectionsize + (mins[axis]) + hmtrace.start[axis]; - } - trstart[axis] /= hmtrace.htilesize; - trdist[axis] /= hmtrace.htilesize; - } - for(;;) - { - if (breaklimit--< 0) - break; + //figure out the leading point for (axis = 0; axis < 2; axis++) { + trdist[axis] = hmtrace.end[axis]-hmtrace.start[axis]; + dir[axis] = (hmtrace.end[axis] - hmtrace.start[axis])/hmtrace.htilesize; + if (dir[axis] > 0) { - npos[axis] = ipos[axis]+1; - frac[axis] = (npos[axis]-trstart[axis])/trdist[axis]; - } - else if (dir[axis] < 0) - { - npos[axis] = ipos[axis]; - frac[axis] = (ipos[axis]-trstart[axis])/trdist[axis]; + ipos[axis] = pos[axis] + emins[axis]; + trstart[axis] = CHUNKBIAS*hmtrace.hm->sectionsize + (maxs[axis]) + hmtrace.start[axis]; } else - frac[axis] = 1000000000000000.0; + { + ipos[axis] = pos[axis] + emaxs[axis]; + trstart[axis] = CHUNKBIAS*hmtrace.hm->sectionsize + (mins[axis]) + hmtrace.start[axis]; + } + trstart[axis] /= hmtrace.htilesize; + trdist[axis] /= hmtrace.htilesize; } - - //which side are we going down? - if (frac[0] < frac[1]) - axis = 0; - else - axis = 1; - - if (frac[axis] >= 1) - break; - - //progress to the crossed boundary - if (dir[axis] < 0) - ipos[axis] = ipos[axis]-1; - else - ipos[axis] = ipos[axis]+1; - - axis = !axis; - if (dir[axis] > 0) - { //leading edge is on the right, so start on the left and keep going until we hit the leading edge - npos[0] = ipos[0]; - npos[1] = ipos[1]; - - npos[axis] -= ceil(emins[axis]-emaxs[axis]); - e = ipos[axis]; - - npos[axis] -= 1; - e++; - - for (; npos[axis] <= e; npos[axis]++) - Heightmap_Trace_Square(&hmtrace, npos[0], npos[1]); - } - else + for(;;) { - //leading edge is on the left - npos[0] = ipos[0]; - npos[1] = ipos[1]; - e = ipos[axis] + ceil(emaxs[axis]-emins[axis]); + if (breaklimit--< 0) + break; + for (axis = 0; axis < 2; axis++) + { + if (dir[axis] > 0) + { + npos[axis] = ipos[axis]+1; + frac[axis] = (npos[axis]-trstart[axis])/trdist[axis]; + } + else if (dir[axis] < 0) + { + npos[axis] = ipos[axis]; + frac[axis] = (ipos[axis]-trstart[axis])/trdist[axis]; + } + else + frac[axis] = 1000000000000000.0; + } - npos[axis] -= 1; - e++; + //which side are we going down? + if (frac[0] < frac[1]) + axis = 0; + else + axis = 1; - for (; npos[axis] <= e; npos[axis]++) - Heightmap_Trace_Square(&hmtrace, npos[0], npos[1]); + if (frac[axis] >= 1) + break; + + //progress to the crossed boundary + if (dir[axis] < 0) + ipos[axis] = ipos[axis]-1; + else + ipos[axis] = ipos[axis]+1; + + axis = !axis; + if (dir[axis] > 0) + { //leading edge is on the right, so start on the left and keep going until we hit the leading edge + npos[0] = ipos[0]; + npos[1] = ipos[1]; + + npos[axis] -= ceil(emins[axis]-emaxs[axis]); + e = ipos[axis]; + + npos[axis] -= 1; + e++; + + for (; npos[axis] <= e; npos[axis]++) + Heightmap_Trace_Square(&hmtrace, npos[0], npos[1]); + } + else + { + //leading edge is on the left + npos[0] = ipos[0]; + npos[1] = ipos[1]; + e = ipos[axis] + ceil(emaxs[axis]-emins[axis]); + + npos[axis] -= 1; + e++; + + for (; npos[axis] <= e; npos[axis]++) + Heightmap_Trace_Square(&hmtrace, npos[0], npos[1]); + } + +// axis = !axis; + //and make sure our position on the other axis is correct, for the next time around the loop +// if (frac[axis] > hmtrace.truefrac) +// break; } - -// axis = !axis; - //and make sure our position on the other axis is correct, for the next time around the loop -// if (frac[axis] > hmtrace.truefrac) -// break; } } + //now trace against the brushes. //FIXME: optimise into the section grid { brushes_t *brushes = hmtrace.hm->wbrushes; diff --git a/engine/gl/gl_model.c b/engine/gl/gl_model.c index d6d0521b2..b8580dd95 100644 --- a/engine/gl/gl_model.c +++ b/engine/gl/gl_model.c @@ -780,10 +780,10 @@ void Mod_Init (qboolean initial) Cmd_AddCommand("version_modelformats", Mod_PrintFormats_f); #ifndef SERVERONLY - Cmd_AddCommandD("map_findcubemaps", Mod_FindCubemaps_f, "Scans the entities of a map to find reflection envmap sites and determines the nearest one to each surface."); - Cmd_AddCommandD("map_realign", Mod_Realign_f, "Reads the named bsp and writes it back out with only alignment changes."); - Cmd_AddCommandD("map_bspx_list", Mod_BSPX_List_f, "Lists all lumps (and their sizes) in the specified bsp."); - Cmd_AddCommandD("map_bspx_strip", Mod_BSPX_Strip_f, "Strips a named extension lump from a bsp file."); + Cmd_AddCommandD("mod_findcubemaps", Mod_FindCubemaps_f, "Scans the entities of a map to find reflection envmap sites and determines the nearest one to each surface."); + Cmd_AddCommandD("mod_realign", Mod_Realign_f, "Reads the named bsp and writes it back out with only alignment changes."); + Cmd_AddCommandD("mod_bspx_list", Mod_BSPX_List_f, "Lists all lumps (and their sizes) in the specified bsp."); + Cmd_AddCommandD("mod_bspx_strip", Mod_BSPX_Strip_f, "Strips a named extension lump from a bsp file."); #endif } diff --git a/engine/gl/gl_model.h b/engine/gl/gl_model.h index 0b2bbd7b4..087e191ab 100644 --- a/engine/gl/gl_model.h +++ b/engine/gl/gl_model.h @@ -1135,3 +1135,6 @@ qofs_t CM_ReadPortalState (model_t *mod, qbyte *ptr, qofs_t ptrsize); #endif //Q2BSPS + +void CategorizePlane ( mplane_t *plane ); +void CalcSurfaceExtents (model_t *mod, msurface_t *s); diff --git a/engine/gl/gl_shader.c b/engine/gl/gl_shader.c index ed1f7e56c..119f5e44a 100644 --- a/engine/gl/gl_shader.c +++ b/engine/gl/gl_shader.c @@ -2285,15 +2285,6 @@ static void Shaderpass_QF_Material(shader_t *shader, shaderpass_t *pass, char ** } static qboolean Shaderpass_MapGen (shader_t *shader, shaderpass_t *pass, char *tname); -static void Shader_ProgMap(shader_t *shader, shaderpass_t *pass, char **ptr) -{ - //fixme -// Shaderpass_BlendFunc (shader, pass, ptr); -} -static void Shader_ProgBlendFunc(shader_t *shader, shaderpass_t *pass, char **ptr) -{ - //fixme -} static void Shader_Translucent(shader_t *shader, shaderpass_t *pass, char **ptr) { @@ -2495,19 +2486,26 @@ static shaderkey_t shaderkeys[] = {"uppermap", Shader_UpperMap, "fte"}, {"lowermap", Shader_LowerMap, "fte"}, {"reflectmask", Shader_ReflectMask, "fte"}, + {"portalfboscale", Shader_PortalFBOScale, "fte"}, //portal/mirror/refraction/reflection FBOs are resized by this scale + {"basefactor", NULL, "fte"}, //material scalers for glsl + {"specularfactor", NULL, "fte"}, //material scalers for glsl + {"fullbrightfactor", NULL, "fte"}, //material scalers for glsl + + //TODO: PBR textures... +// {"albedomap", Shader_DiffuseMap, "fte"}, //rgb(a) +// {"loweruppermap", Shader_LowerUpperMap, "fte"}, //r=lower, g=upper (team being more important than personal colours, this allows the texture to gracefully revert to red-only) + //{"normalmap", Shader_NormalMap, "fte"}, //xy-h +// {"omrmap", Shader_SpecularMap, "fte"}, //r=occlusion, g=metalness, b=roughness. + //{"glowmap", Shader_FullbrightMap, "fte"}, //rgb /*program stuff at the material level is an outdated practise.*/ {"program", Shader_ProgramName, "fte"}, //usable with any renderer that has a usable shader language... {"glslprogram", Shader_GLSLProgramName, "fte"}, //for renderers that accept embedded glsl {"hlslprogram", Shader_HLSL9ProgramName, "fte"}, //for d3d with embedded hlsl {"hlsl11program", Shader_HLSL11ProgramName, "fte"}, //for d3d with embedded hlsl - {"progblendfunc", Shader_ProgBlendFunc, "fte"}, //specifies the blend mode (actually just overrides the first subpasses' blendmode. - {"progmap", Shader_ProgMap, "fte"}, //avoids needing extra subpasses (actually just inserts an extra pass). - - {"basefactor", NULL, "fte"}, //material scalers for glsl - {"specularfactor", NULL, "fte"}, //material scalers for glsl - {"fullbrightfactor", NULL, "fte"}, //material scalers for glsl +// {"progblendfunc", Shader_ProgBlendFunc, "fte"}, //specifies the blend mode (actually just overrides the first subpasses' blendmode. +// {"progmap", Shader_ProgMap, "fte"}, //avoids needing extra subpasses (actually just inserts an extra pass). //dp compat {"reflectcube", Shader_ReflectCube, "dp"}, @@ -2532,7 +2530,7 @@ static shaderkey_t shaderkeys[] = {"nooverlays", NULL, "doom3"}, {"nofragment", NULL, "doom3"}, - /*RTCW vompat*/ + /*RTCW compat*/ {"nocompress", NULL, "rtcw"}, {"allowcompress", NULL, "rtcw"}, {"nofog", NULL, "rtcw"}, @@ -6706,31 +6704,34 @@ static qboolean Shader_ParseShader(char *parsename, shader_t *s) char *file; const char *token; - //if the named shader is a .shader file then just directly load it. - token = COM_GetFileExtension(parsename, NULL); - if (!strcmp(token, ".shader") || !*token) + if (!strchr(parsename, ':')) { - char shaderfile[MAX_QPATH]; - if (!*token) + //if the named shader is a .shader file then just directly load it. + token = COM_GetFileExtension(parsename, NULL); + if (!strcmp(token, ".shader") || !*token) { - Q_snprintfz(shaderfile, sizeof(shaderfile), "%s.shader", parsename); - file = COM_LoadTempMoreFile(shaderfile, &length); - } - else - file = COM_LoadTempMoreFile(parsename, &length); - if (file) - { - Shader_Reset(s); - token = COM_ParseExt (&file, true, false); //we need to skip over the leading {. - if (*token != '{') - token = COM_ParseExt (&file, true, false); //try again, in case we found some legacy name. - if (*token == '{') + char shaderfile[MAX_QPATH]; + if (!*token) { - Shader_ReadShader(s, file, NULL); - return true; + Q_snprintfz(shaderfile, sizeof(shaderfile), "%s.shader", parsename); + file = COM_LoadTempMoreFile(shaderfile, &length); } else - Con_Printf("file %s.shader does not appear to contain a shader\n", shaderfile); + file = COM_LoadTempMoreFile(parsename, &length); + if (file) + { + Shader_Reset(s); + token = COM_ParseExt (&file, true, false); //we need to skip over the leading {. + if (*token != '{') + token = COM_ParseExt (&file, true, false); //try again, in case we found some legacy name. + if (*token == '{') + { + Shader_ReadShader(s, file, NULL); + return true; + } + else + Con_Printf("file %s.shader does not appear to contain a shader\n", shaderfile); + } } } diff --git a/engine/gl/gl_shadow.c b/engine/gl/gl_shadow.c index a32b882b5..38b6749a0 100644 --- a/engine/gl/gl_shadow.c +++ b/engine/gl/gl_shadow.c @@ -3597,6 +3597,8 @@ void Sh_PreGenerateLights(void) int i; r_shadow_realtime_world_lightmaps.value = atof(r_shadow_realtime_world_lightmaps.string); + if (!cl.worldmodel) + return; if ((r_shadow_realtime_dlight.ival || r_shadow_realtime_world.ival) && rtlights_max == RTL_FIRST) { qboolean okay = false; diff --git a/engine/gl/gl_videgl.c b/engine/gl/gl_videgl.c index 596d01ab3..d47fbe74d 100644 --- a/engine/gl/gl_videgl.c +++ b/engine/gl/gl_videgl.c @@ -89,7 +89,7 @@ void *EGL_Proc(char *f) return proc; } -const char *EGL_GetErrorString(int error) +static const char *EGL_GetErrorString(int error) { switch(error) { @@ -263,7 +263,11 @@ qboolean EGL_Init (rendererstate_t *info, unsigned char *palette, int eglplat, v if (qeglGetPlatformDisplay && eglplat) egldpy = qeglGetPlatformDisplay(eglplat, ndpy, NULL/*attribs*/); else + { + if (eglplat == EGL_PLATFORM_WAYLAND_KHR) + Con_Printf(CON_ERROR "EGL: eglGetPlatformDisplay[EXT] not supported. Your EGL implementation is probably too old.\n"); egldpy = qeglGetDisplay(dpyid); + } if (egldpy == EGL_NO_DISPLAY) { Con_Printf(CON_WARNING "EGL: creating default display\n"); @@ -309,8 +313,8 @@ qboolean EGL_Init (rendererstate_t *info, unsigned char *palette, int eglplat, v if (eglsurf == EGL_NO_SURFACE) { int err = qeglGetError(); - if (eglplat == EGL_PLATFORM_WAYLAND_KHR && err == EGL_BAD_CONTEXT) //slightly more friendly error that slags off nvidia for their refusal to implement existing standards, as is apparently appropriate. - Con_Printf(CON_ERROR "EGL: eglCreateWindowSurface failed: Bad Display. This often happens with nvidia... Try different drivers...\n"); + if (eglplat == EGL_PLATFORM_WAYLAND_KHR && err == EGL_BAD_DISPLAY) //slightly more friendly error that slags off nvidia for their refusal to implement existing standards, as is apparently appropriate. + Con_Printf(CON_ERROR "EGL: eglCreateWindowSurface failed: Bad Display. Your wayland setup is probably not properly supported by your video drivers.\n"); else Con_Printf(CON_ERROR "EGL: eglCreateWindowSurface failed: %s\n", EGL_GetErrorString(err)); return false; diff --git a/engine/gl/gl_vidlinuxglx.c b/engine/gl/gl_vidlinuxglx.c index f4b11c2b6..f912df4ce 100644 --- a/engine/gl/gl_vidlinuxglx.c +++ b/engine/gl/gl_vidlinuxglx.c @@ -119,7 +119,7 @@ extern int sys_parentwidth; extern int sys_parentheight; extern long sys_parentwindow; -qboolean X11_CheckFeature(const char *featurename, qboolean defaultval) +static qboolean X11_CheckFeature(const char *featurename, qboolean defaultval) { cvar_t *var; if (COM_CheckParm(va("-no%s", featurename))) @@ -131,6 +131,7 @@ qboolean X11_CheckFeature(const char *featurename, qboolean defaultval) return !!var->ival; return defaultval; } +static qboolean X11_Clipboard_Notify(XSelectionEvent *xselection); #define KEY_MASK (KeyPressMask | KeyReleaseMask) #define MOUSE_MASK (ButtonPressMask | ButtonReleaseMask | \ @@ -1312,13 +1313,15 @@ static struct int swapint; } glx; -void GLX_CloseLibrary(void) +/*Note: closing the GLX library is unsafe as nvidia's drivers like to crash once its reloaded. +static void GLX_CloseLibrary(void) { Sys_CloseLibrary(glx.gllibrary); glx.gllibrary = NULL; } +*/ -void *GLX_GetSymbol(char *name) +static void *GLX_GetSymbol(char *name) { void *symb; @@ -1332,7 +1335,7 @@ void *GLX_GetSymbol(char *name) return symb; } -qboolean GLX_InitLibrary(char *driver) +static qboolean GLX_InitLibrary(char *driver) { dllfunction_t funcs[] = { @@ -1381,7 +1384,7 @@ qboolean GLX_InitLibrary(char *driver) #define GLX_CONTEXT_OPENGL_NO_ERROR_ARB 0x31B3 #endif -qboolean GLX_CheckExtension(const char *ext) +static qboolean GLX_CheckExtension(const char *ext) { const char *e = glx.glxextensions, *n; size_t el = strlen(ext); @@ -1405,7 +1408,7 @@ qboolean GLX_CheckExtension(const char *ext) } //Since GLX1.3 (equivelent to gl1.2) -GLXFBConfig GLX_GetFBConfig(rendererstate_t *info) +static GLXFBConfig GLX_GetFBConfig(rendererstate_t *info) { int attrib[32]; int n, i; @@ -1521,7 +1524,7 @@ GLXFBConfig GLX_GetFBConfig(rendererstate_t *info) return NULL; } //for GLX<1.3 -XVisualInfo *GLX_GetVisual(rendererstate_t *info) +static XVisualInfo *GLX_GetVisual(rendererstate_t *info) { XVisualInfo *visinfo; int attrib[32]; @@ -1568,7 +1571,7 @@ XVisualInfo *GLX_GetVisual(rendererstate_t *info) return NULL; } -qboolean GLX_Init(rendererstate_t *info, GLXFBConfig fbconfig, XVisualInfo *visinfo) +static qboolean GLX_Init(rendererstate_t *info, GLXFBConfig fbconfig, XVisualInfo *visinfo) { extern cvar_t vid_gl_context_version; extern cvar_t vid_gl_context_forwardcompatible; @@ -2049,7 +2052,7 @@ static void ClearAllStates (void) int i; // send an up event for each key, to make sure the server clears them all - for (i=0 ; i<256 ; i++) + for (i=0 ; idisplay == vid_dpy && xselection->selection == x11paste.clipboard && xselection->requestor == vid_window && xselection->property == x11paste.prop) + { + int fmt; + Atom type; + unsigned long nitems, bytesleft; + unsigned char *data = NULL; + x11.pXGetWindowProperty(vid_dpy, vid_window, x11paste.prop, 0, 65536, False, AnyPropertyType, &type, &fmt, &nitems, &bytesleft, &data); + if (paste_callback) + paste_callback(pastectx, data); + x11.pXFree(data); + paste_callback = NULL; + pastectx = NULL; + return true; + } + return false; +} + +/*char *Sys_GetClipboard(void) { if(vid_dpy) { @@ -3729,17 +3800,9 @@ char *Sys_GetClipboard(void) } return clipboard_buffer; } +*/ -void Sys_CloseClipboard(char *bf) -{ - if (bf == clipboard_buffer) - return; - - if(vid_dpy) - x11.pXFree(bf); -} - -void Sys_SaveClipboard(char *text) +void Sys_SaveClipboard(clipboardtype_t clipboardtype, char *text) { Q_strncpyz(clipboard_buffer, text, SYS_CLIPBOARD_SIZE); if(vid_dpy) @@ -3747,7 +3810,7 @@ void Sys_SaveClipboard(char *text) Atom xa_clipboard = x11.pXInternAtom(vid_dpy, "PRIMARY", false); x11.pXSetSelectionOwner(vid_dpy, xa_clipboard, vid_window, CurrentTime); - //Set both clipboards. Because x11 is kinda annoying. + //Set both clipboards for now. Because x11 is kinda annoying. xa_clipboard = x11.pXInternAtom(vid_dpy, "CLIPBOARD", false); x11.pXSetSelectionOwner(vid_dpy, xa_clipboard, vid_window, CurrentTime); } @@ -3887,10 +3950,10 @@ void Sys_SendKeyEvents(void) #endif } -void Force_CenterView_f (void) +/*static void Force_CenterView_f (void) { cl.playerview[0].viewangles[PITCH] = 0; -} +}*/ //these are done from the x11 event handler. we don't support evdev. diff --git a/engine/gl/gl_vidmacos.c b/engine/gl/gl_vidmacos.c index fe94d90fe..66dbaf377 100644 --- a/engine/gl/gl_vidmacos.c +++ b/engine/gl/gl_vidmacos.c @@ -213,19 +213,14 @@ void INS_Move (void) { } -#define SYS_CLIPBOARD_SIZE 256 +#define SYS_CLIPBOARD_SIZE 256 static char clipboard_buffer[SYS_CLIPBOARD_SIZE] = {0}; - -char *Sys_GetClipboard(void) +void Sys_Clipboard_PasteText(clipboardtype_t cbt, void (*callback)(void *cb, char *utf8), void *ctx) { - return clipboard_buffer; + callback(ctx, clipboard_buffer); +} +void Sys_SaveClipboard(clipboardtype_t cbt, char *text) +{ + Q_strncpyz(clipboard_buffer, text, SYS_CLIPBOARD_SIZE); } -void Sys_CloseClipboard(char *bf) -{ -} - -void Sys_SaveClipboard(char *text) -{ - Q_strncpyz(clipboard_buffer, text, SYS_CLIPBOARD_SIZE); -} diff --git a/engine/gl/gl_vidwayland.c b/engine/gl/gl_vidwayland.c index 6dc7afb26..9148655b6 100644 --- a/engine/gl/gl_vidwayland.c +++ b/engine/gl/gl_vidwayland.c @@ -538,7 +538,7 @@ static void WL_SwapBuffers(void) } #ifdef VKQUAKE -static qboolean WLVK_SetupSurface() +static qboolean WLVK_SetupSurface(void) { VkWaylandSurfaceCreateInfoKHR inf = {VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR}; inf.flags = 0; diff --git a/engine/gl/r_bishaders.h b/engine/gl/r_bishaders.h index 33a5ab74e..085522920 100644 --- a/engine/gl/r_bishaders.h +++ b/engine/gl/r_bishaders.h @@ -2945,6 +2945,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND "#endif\n" "col.rgb *= light;\n" +"col *= e_colourident;\n" "#ifdef FULLBRIGHT\n" "vec4 fb = texture2D(s_fullbright, tc);\n" @@ -2953,7 +2954,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND "#endif\n" "#endif\n" -"gl_FragColor = fog4(col * e_colourident);\n" +"gl_FragColor = fog4(col);\n" "}\n" "#endif\n" diff --git a/engine/nacl/sys_ppapi.c b/engine/nacl/sys_ppapi.c index a062b8049..bff93aafe 100644 --- a/engine/nacl/sys_ppapi.c +++ b/engine/nacl/sys_ppapi.c @@ -124,15 +124,15 @@ void Sys_CloseTerminal (void) { } -char *Sys_GetClipboard(void) +#define SYS_CLIPBOARD_SIZE 256 +static char clipboard_buffer[SYS_CLIPBOARD_SIZE] = {0}; +void Sys_Clipboard_PasteText(clipboardtype_t cbt, void (*callback)(void *cb, char *utf8), void *ctx) { - return NULL; + callback(ctx, clipboard_buffer); } -void Sys_CloseClipboard(char *buf) -{ -} -void Sys_SaveClipboard(char *text) +void Sys_SaveClipboard(clipboardtype_t cbt, char *text) { + Q_strncpyz(clipboard_buffer, text, SYS_CLIPBOARD_SIZE); } void Sys_ServerActivity(void) { @@ -693,4 +693,4 @@ PP_EXPORT const void* PPP_GetInterface(const char* interface_name) } PP_EXPORT void PPP_ShutdownModule() { -} \ No newline at end of file +} diff --git a/engine/qclib/cmdlib.h b/engine/qclib/cmdlib.h index 592818bbb..8c49b457b 100644 --- a/engine/qclib/cmdlib.h +++ b/engine/qclib/cmdlib.h @@ -71,7 +71,8 @@ static void VARGS QC_snprintfz (char *dest, size_t size, const char *fmt, ...) double I_FloatTime (void); void VARGS QCC_Error (int errortype, const char *error, ...) LIKEPRINTF(2); -int CheckParm (char *check); +int QCC_CheckParm (const char *check); +const char *QCC_ReadParm (const char *check); int SafeOpenWrite (char *filename, int maxsize); diff --git a/engine/qclib/comprout.c b/engine/qclib/comprout.c index 16ddb7482..57e47d574 100644 --- a/engine/qclib/comprout.c +++ b/engine/qclib/comprout.c @@ -78,7 +78,6 @@ pbool PreCompile(void) } pbool QCC_main (int argc, char **argv); -void QCC_ContinueCompile(void); void QCC_FinishCompile(void); int comp_nump;char **comp_parms; @@ -94,7 +93,7 @@ pbool CompileParams(progfuncs_t *progfuncs, void(*cb)(void), int nump, char **pa PostCompile(); if (*errorfile) { - printf("Error in %s on line %i\n", errorfile, errorline); + externs->Printf("Error in %s on line %i\n", errorfile, errorline); } return false; } diff --git a/engine/qclib/execloop.h b/engine/qclib/execloop.h index 814dbb39c..844baea9a 100644 --- a/engine/qclib/execloop.h +++ b/engine/qclib/execloop.h @@ -57,29 +57,29 @@ //this will fire on the next instruction after the variable got changed. pr_xstatement = s; if (current_progstate->linenums) - printf("Watch point hit in %s:%u, \"%s\" changed", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), current_progstate->linenums[s-1], prinst.watch_name); + externs->Printf("Watch point hit in %s:%u, \"%s\" changed", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), current_progstate->linenums[s-1], prinst.watch_name); else - printf("Watch point hit in %s, \"%s\" changed", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), prinst.watch_name); + externs->Printf("Watch point hit in %s, \"%s\" changed", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), prinst.watch_name); switch(prinst.watch_type) { case ev_float: - printf(" from %g to %g", prinst.watch_old._float, prinst.watch_ptr->_float); + externs->Printf(" from %g to %g", prinst.watch_old._float, prinst.watch_ptr->_float); break; case ev_vector: - printf(" from '%g %g %g' to '%g %g %g'", prinst.watch_old._vector[0], prinst.watch_old._vector[1], prinst.watch_old._vector[2], prinst.watch_ptr->_vector[0], prinst.watch_ptr->_vector[1], prinst.watch_ptr->_vector[2]); + externs->Printf(" from '%g %g %g' to '%g %g %g'", prinst.watch_old._vector[0], prinst.watch_old._vector[1], prinst.watch_old._vector[2], prinst.watch_ptr->_vector[0], prinst.watch_ptr->_vector[1], prinst.watch_ptr->_vector[2]); break; default: - printf(" from %i to %i", prinst.watch_old._int, prinst.watch_ptr->_int); + externs->Printf(" from %i to %i", prinst.watch_old._int, prinst.watch_ptr->_int); break; case ev_entity: - printf(" from %i(%s) to %i(%s)", prinst.watch_old._int, PR_GetEdictClassname(progfuncs, prinst.watch_old._int), prinst.watch_ptr->_int, PR_GetEdictClassname(progfuncs, prinst.watch_ptr->_int)); + externs->Printf(" from %i(%s) to %i(%s)", prinst.watch_old._int, PR_GetEdictClassname(progfuncs, prinst.watch_old._int), prinst.watch_ptr->_int, PR_GetEdictClassname(progfuncs, prinst.watch_ptr->_int)); break; case ev_function: case ev_string: - printf(", now set to %s", PR_ValueString(progfuncs, prinst.watch_type, prinst.watch_ptr, false)); + externs->Printf(", now set to %s", PR_ValueString(progfuncs, prinst.watch_type, prinst.watch_ptr, false)); break; } - printf(".\n"); + externs->Printf(".\n"); prinst.watch_old = *prinst.watch_ptr; // prinst.watch_ptr = NULL; progfuncs->funcs.debug_trace=DEBUG_TRACE_INTO; //this is what it's for @@ -143,7 +143,7 @@ reeval: /* errorif (OPB->_float == 0) { pr_xstatement = st-pr_statements; - printf ("Division by 0 in %s\n", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name)); + externs->Printf ("Division by 0 in %s\n", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name)); PR_StackTrace (&progfuncs->funcs, 1); OPC->_float = 0.0; } @@ -155,7 +155,7 @@ reeval: /* errorif (!tmpf) { pr_xstatement = st-pr_statements; - printf ("Division by 0 in %s\n", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name)); + externs->Printf ("Division by 0 in %s\n", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name)); PR_StackTrace (&progfuncs->funcs, 1); } */ @@ -659,7 +659,7 @@ reeval: //skip the instruction if they just try stepping over it anyway. PR_StackTrace(&progfuncs->funcs, 0); - printf(msg, PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name)); + externs->Printf(msg, PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name)); pr_globals[OFS_RETURN] = 0; pr_globals[OFS_RETURN+1] = 0; @@ -1310,7 +1310,7 @@ reeval: case OP_BOUNDCHECK: errorif ((unsigned int)OPA->_int < (unsigned int)st->c || (unsigned int)OPA->_int >= (unsigned int)st->b) { - printf("Progs boundcheck failed. Value is %i. Must be %u<=value<%u\n", OPA->_int, st->c, st->b); + externs->Printf("Progs boundcheck failed. Value is %i. Must be %u<=value<%u\n", OPA->_int, st->c, st->b); QCFAULT(&progfuncs->funcs, "Progs boundcheck failed. Value is %i. Must be %u<=value<%u\n", OPA->_int, st->c, st->b); /* s=ShowStepf(progfuncs, st - pr_statements, "Progs boundcheck failed. Value is %i. Must be between %u and %u\n", OPA->_int, st->c, st->b); if (st == pr_statements + s) @@ -1347,7 +1347,7 @@ reeval: if (pr_xstatement != s) { pr_xstatement = s; - printf("Break point hit in %s.\n", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name)); + externs->Printf("Break point hit in %s.\n", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name)); s = ShowStep(progfuncs, s, NULL, false); st = &pr_statements[s]; //let the user move execution pr_xstatement = s = st-pr_statements; diff --git a/engine/qclib/hash.c b/engine/qclib/hash.c index 0bde8a6a2..6923a21d6 100644 --- a/engine/qclib/hash.c +++ b/engine/qclib/hash.c @@ -54,7 +54,7 @@ unsigned int Hash_Key(const char *name, unsigned int modulus) return (key%modulus); } -unsigned int Hash_KeyInsensitive(const char *name, unsigned int modulus) +static unsigned int Hash_KeyInsensitive(const char *name, unsigned int modulus) { //fixme: optimize. unsigned int key; for (key=0;*name; name++) diff --git a/engine/qclib/initlib.c b/engine/qclib/initlib.c index 88c46db6d..5e50168cf 100644 --- a/engine/qclib/initlib.c +++ b/engine/qclib/initlib.c @@ -8,7 +8,7 @@ typedef struct prmemb_s { struct prmemb_s *prev; int level; } prmemb_t; -void *PRHunkAlloc(progfuncs_t *progfuncs, int ammount, char *name) +void *PRHunkAlloc(progfuncs_t *progfuncs, int ammount, const char *name) { prmemb_t *mem; ammount = sizeof(prmemb_t)+((ammount + 3)&~3); @@ -177,7 +177,7 @@ static void PF_fmem_unlink(progfuncs_t *progfuncs, qcmemfreeblock_t *p) #ifdef _DEBUG if (p->marker != MARKER_FREE) { - printf("PF_fmem_unlink: memory corruption\n"); + externs->Printf("PF_fmem_unlink: memory corruption\n"); PR_StackTrace(&progfuncs->funcs, false); } p->marker = 0; @@ -207,7 +207,7 @@ static void PR_memvalidate (progfuncs_t *progfuncs) { if ((size_t)b >= (size_t)prinst.addressableused) { - printf("PF_memalloc: memory corruption\n"); + externs->Printf("PF_memalloc: memory corruption\n"); PR_StackTrace(&progfuncs->funcs, false); return; } @@ -223,7 +223,7 @@ static void PR_memvalidate (progfuncs_t *progfuncs) b + p->size >= prinst.addressableused || p->prev >= b) { - printf("PF_memalloc: memory corruption\n"); + externs->Printf("PF_memalloc: memory corruption\n"); PR_StackTrace(&progfuncs->funcs, false); return; } @@ -248,7 +248,7 @@ static void *PDECL PR_memalloc (pubprogfuncs_t *ppf, unsigned int size) { if (/*b < 0 || */b+sizeof(qcmemfreeblock_t) >= prinst.addressableused) { - printf("PF_memalloc: memory corruption\n"); + externs->Printf("PF_memalloc: memory corruption\n"); PR_StackTrace(&progfuncs->funcs, false); return NULL; } @@ -260,7 +260,7 @@ static void *PDECL PR_memalloc (pubprogfuncs_t *ppf, unsigned int size) b + p->size >= prinst.addressableused || p->prev >= b) { - printf("PF_memalloc: memory corruption\n"); + externs->Printf("PF_memalloc: memory corruption\n"); PR_StackTrace(&progfuncs->funcs, false); return NULL; } @@ -307,7 +307,7 @@ static void *PDECL PR_memalloc (pubprogfuncs_t *ppf, unsigned int size) ub = PRAddressableExtend(progfuncs, NULL, size, 0); if (!ub) { - printf("PF_memalloc: memory exausted\n"); + externs->Printf("PF_memalloc: memory exausted\n"); PR_StackTrace(&progfuncs->funcs, false); return NULL; } @@ -342,10 +342,10 @@ static void PDECL PR_memfree (pubprogfuncs_t *ppf, void *memptr) { //the empty string is a point of contention. while we can detect it from fteqcc, its best to not give any special favours (other than nicer debugging, where possible) //we might not actually spot it from other qccs, so warning about it where possible is probably a very good thing. - printf("PF_memfree: unable to free the non-null empty string constant at %x\n", ptr); + externs->Printf("PF_memfree: unable to free the non-null empty string constant at %x\n", ptr); } else - printf("PF_memfree: pointer invalid - out of range (%x >= %x)\n", ptr, (unsigned int)prinst.addressableused); + externs->Printf("PF_memfree: pointer invalid - out of range (%x >= %x)\n", ptr, (unsigned int)prinst.addressableused); PR_StackTrace(&progfuncs->funcs, false); return; } @@ -354,7 +354,7 @@ static void PDECL PR_memfree (pubprogfuncs_t *ppf, void *memptr) ub = (qcmemusedblock_t*)(progfuncs->funcs.stringtable + ptr); if (ub->marker != MARKER_USED || ub->size <= sizeof(*ub) || ptr + ub->size > (unsigned int)prinst.addressableused) { - printf("PR_memfree: pointer lacks marker - double-freed?\n"); + externs->Printf("PR_memfree: pointer lacks marker - double-freed?\n"); PR_StackTrace(&progfuncs->funcs, false); return; } @@ -368,7 +368,7 @@ static void PDECL PR_memfree (pubprogfuncs_t *ppf, void *memptr) { if (/*na < 0 ||*/ na >= prinst.addressableused) { - printf("PF_memfree: memory corruption\n"); + externs->Printf("PF_memfree: memory corruption\n"); PR_StackTrace(&progfuncs->funcs, false); return; } @@ -377,14 +377,14 @@ static void PDECL PR_memfree (pubprogfuncs_t *ppf, void *memptr) pb = pa?(qcmemfreeblock_t*)(progfuncs->funcs.stringtable + pa):NULL; if (pb && pa+pb->size>ptr) { //previous free block extends into the block that we're trying to free. - printf("PF_memfree: double free\n"); + externs->Printf("PF_memfree: double free\n"); PR_StackTrace(&progfuncs->funcs, false); return; } #ifdef _DEBUG if (pb && pb->marker != MARKER_FREE) { - printf("PF_memfree: use-after-free?\n"); + externs->Printf("PF_memfree: use-after-free?\n"); PR_StackTrace(&progfuncs->funcs, false); return; } @@ -393,14 +393,14 @@ static void PDECL PR_memfree (pubprogfuncs_t *ppf, void *memptr) nb = na?(qcmemfreeblock_t*)(progfuncs->funcs.stringtable + na):NULL; if (nb && ptr+size > na) { - printf("PF_memfree: block extends into neighbour\n"); + externs->Printf("PF_memfree: block extends into neighbour\n"); PR_StackTrace(&progfuncs->funcs, false); return; } #ifdef _DEBUG if (nb && nb->marker != MARKER_FREE) { - printf("PF_memfree: use-after-free?\n"); + externs->Printf("PF_memfree: use-after-free?\n"); PR_StackTrace(&progfuncs->funcs, false); return; } @@ -490,7 +490,7 @@ int PDECL PR_InitEnts(pubprogfuncs_t *ppf, int max_ents) int i; for (i = 0; i < prinst.numfields; i++) { - printf("%s(%i) %i -> %i\n", prinst.field[i].name, prinst.field[i].type, prinst.field[i].progsofs, prinst.field[i].ofs); + externs->Printf("%s(%i) %i -> %i\n", prinst.field[i].name, prinst.field[i].type, prinst.field[i].progsofs, prinst.field[i].ofs); } } #endif @@ -551,7 +551,8 @@ static void PDECL PR_Configure (pubprogfuncs_t *ppf, size_t addressable_size, in } if (addressable_size > 0x80000000) addressable_size = 0x80000000; - PRAddressableFlush(progfuncs, addressable_size); + PRAddressableFlush(progfuncs, addressable_size); + progfuncs->funcs.stringtable = prinst.addressablehunk; pr_progstate = PRHunkAlloc(progfuncs, sizeof(progstate_t) * max_progs, "progstatetable"); @@ -675,20 +676,21 @@ func_t PDECL PR_FindFunc(pubprogfuncs_t *ppf, const char *funcname, progsnum_t p { ddef16_t *var16; ddef32_t *var32; - switch(pr_progstate[pnum].structtype) + progstate_t *ps = &pr_progstate[pnum]; + switch(ps->structtype) { case PST_KKQWSV: case PST_DEFAULT: - var16 = ED_FindTypeGlobalFromProgs16(progfuncs, funcname, pnum, ev_function); //we must make sure we actually have a function def - 'light' is defined as a field before it is defined as a function. + var16 = ED_FindTypeGlobalFromProgs16(progfuncs, ps, funcname, ev_function); //we must make sure we actually have a function def - 'light' is defined as a field before it is defined as a function. if (!var16) - return (f - pr_progstate[pnum].functions) | (pnum << 24); - return *(int *)&pr_progstate[pnum].globals[var16->ofs]; + return (f - ps->functions) | (pnum << 24); + return *(int *)&ps->globals[var16->ofs]; case PST_QTEST: case PST_FTE32: - var32 = ED_FindTypeGlobalFromProgs32(progfuncs, funcname, pnum, ev_function); //we must make sure we actually have a function def - 'light' is defined as a field before it is defined as a function. + var32 = ED_FindTypeGlobalFromProgs32(progfuncs, ps, funcname, ev_function); //we must make sure we actually have a function def - 'light' is defined as a field before it is defined as a function. if (!var32) - return (f - pr_progstate[pnum].functions) | (pnum << 24); - return *(int *)&pr_progstate[pnum].globals[var32->ofs]; + return (f - ps->functions) | (pnum << 24); + return *(int *)&ps->globals[var32->ofs]; } Sys_Error("Error with def size (PR_FindFunc)"); } @@ -748,11 +750,12 @@ eval_t *PDECL PR_FindGlobal(pubprogfuncs_t *ppf, const char *globname, progsnum_ unsigned int i; ddef16_t *var16; ddef32_t *var32; + progstate_t *cp; if (type) *type = ev_void; - if (pnum == PR_CURRENT) - pnum = prinst.pr_typecurrent; - if (pnum == PR_ANY) + if (pnum == PR_CURRENT && current_progstate) + cp = current_progstate; + else if (pnum == PR_ANY) { eval_t *ev; for (i = 0; i < prinst.maxprogs; i++) @@ -765,26 +768,28 @@ eval_t *PDECL PR_FindGlobal(pubprogfuncs_t *ppf, const char *globname, progsnum_ } return NULL; } - if (pnum < 0 || (unsigned)pnum >= prinst.maxprogs || !pr_progstate[pnum].progs) + else if (pnum >= 0 && (unsigned)pnum < prinst.maxprogs && pr_progstate[pnum].progs) + cp = &pr_progstate[pnum]; + else return NULL; - switch(pr_progstate[pnum].structtype) + switch(cp->structtype) { case PST_DEFAULT: case PST_KKQWSV: - if (!(var16 = ED_FindGlobalFromProgs16(progfuncs, globname, pnum))) + if (!(var16 = ED_FindGlobalFromProgs16(progfuncs, cp, globname))) return NULL; if (type) *type = var16->type; - return (eval_t *)&pr_progstate[pnum].globals[var16->ofs]; + return (eval_t *)&cp->globals[var16->ofs]; case PST_QTEST: case PST_FTE32: - if (!(var32 = ED_FindGlobalFromProgs32(progfuncs, globname, pnum))) + if (!(var32 = ED_FindGlobalFromProgs32(progfuncs, cp, globname))) return NULL; if (type) *type = var32->type; - return (eval_t *)&pr_progstate[pnum].globals[var32->ofs]; + return (eval_t *)&cp->globals[var32->ofs]; } Sys_Error("Error with def size (PR_FindGlobal)"); return NULL; @@ -811,7 +816,7 @@ char *PDECL PR_VarString (pubprogfuncs_t *ppf, int first) return out; } -int PDECL PR_QueryField (pubprogfuncs_t *ppf, unsigned int fieldoffset, etype_t *type, char **name, evalc_t *fieldcache) +int PDECL PR_QueryField (pubprogfuncs_t *ppf, unsigned int fieldoffset, etype_t *type, char const**name, evalc_t *fieldcache) { progfuncs_t *progfuncs = (progfuncs_t*)ppf; fdef_t *var; @@ -832,7 +837,7 @@ int PDECL PR_QueryField (pubprogfuncs_t *ppf, unsigned int fieldoffset, etype_t return true; } -eval_t *PDECL QC_GetEdictFieldValue(pubprogfuncs_t *ppf, struct edict_s *ed, char *name, etype_t type, evalc_t *cache) +eval_t *PDECL QC_GetEdictFieldValue(pubprogfuncs_t *ppf, struct edict_s *ed, const char *name, etype_t type, evalc_t *cache) { progfuncs_t *progfuncs = (progfuncs_t*)ppf; fdef_t *var; @@ -868,7 +873,7 @@ struct edict_s *PDECL ProgsToEdict (pubprogfuncs_t *ppf, int progs) progfuncs_t *progfuncs = (progfuncs_t*)ppf; if ((unsigned)progs >= (unsigned)prinst.maxedicts) { - printf("Bad entity index %i\n", progs); + externs->Printf("Bad entity index %i\n", progs); if (pr_depth) { PR_StackTrace (ppf, false); @@ -1282,7 +1287,7 @@ pbool PR_RunGC (progfuncs_t *progfuncs) } // endtime = Sys_GetClock(); -// printf("live: %u, dead: %u, time: mark=%f, sweep=%f\n", r_l, r_d, (double)(markedtime - starttime) / Sys_GetClockRate(), (double)(endtime - markedtime) / Sys_GetClockRate()); +// externs->Printf("live: %u, dead: %u, time: mark=%f, sweep=%f\n", r_l, r_d, (double)(markedtime - starttime) / Sys_GetClockRate(), (double)(endtime - markedtime) / Sys_GetClockRate()); return true; } @@ -1341,7 +1346,7 @@ pbool PDECL PR_DumpProfiles (pubprogfuncs_t *ppf, pbool resetprofiles) if (ps->progs == NULL) //we havn't loaded it yet, for some reason continue; - printf("%s:\n", ps->filename); + externs->Printf("%s:\n", ps->filename); sorted = malloc(sizeof(*sorted) * ps->progs->numfunctions); //pull out the functions in order to sort them for (s = 0, f = 0; f < ps->progs->numfunctions; f++) @@ -1374,9 +1379,9 @@ pbool PDECL PR_DumpProfiles (pubprogfuncs_t *ppf, pbool resetprofiles) } //print it out - printf("%8s %9s %10s: %s\n", "ops", "self-time", "total-time", "function"); + externs->Printf("%8s %9s %10s: %s\n", "ops", "self-time", "total-time", "function"); for (f = 0; f < s; f++) - printf("%8u %9f %10f: %s\n", sorted[f].profile, ull2dbl(sorted[f].profiletime) / ull2dbl(cpufrequency), ull2dbl(sorted[f].totaltime) / ull2dbl(cpufrequency), sorted[f].fname); + externs->Printf("%8u %9f %10f: %s\n", sorted[f].profile, ull2dbl(sorted[f].profiletime) / ull2dbl(cpufrequency), ull2dbl(sorted[f].totaltime) / ull2dbl(cpufrequency), sorted[f].fname); free(sorted); } return true; @@ -1384,7 +1389,7 @@ pbool PDECL PR_DumpProfiles (pubprogfuncs_t *ppf, pbool resetprofiles) static void PDECL PR_CloseProgs(pubprogfuncs_t *ppf); -static void PDECL RegisterBuiltin(pubprogfuncs_t *progfncs, char *name, builtin_t func); +static void PDECL RegisterBuiltin(pubprogfuncs_t *progfncs, const char *name, builtin_t func); pubprogfuncs_t deffuncs = { PROGSTRUCT_VERSION, @@ -1617,7 +1622,7 @@ static void PDECL PR_CloseProgs(pubprogfuncs_t *ppf) f(inst); } -static void PDECL RegisterBuiltin(pubprogfuncs_t *progfuncs, char *name, builtin_t func) +static void PDECL RegisterBuiltin(pubprogfuncs_t *progfuncs, const char *name, builtin_t func) { /* extensionbuiltin_t *eb; diff --git a/engine/qclib/pr_edict.c b/engine/qclib/pr_edict.c index 8e519080c..342cad471 100644 --- a/engine/qclib/pr_edict.c +++ b/engine/qclib/pr_edict.c @@ -188,9 +188,9 @@ void PDECL ED_Free (pubprogfuncs_t *ppf, struct edict_s *ed) if (e->ereftype == ER_FREE) //this happens on start.bsp where an onlyregistered trigger killtargets itself (when all of this sort die after 1 trigger anyway). { if (pr_depth) - printf("Tried to free free entity within %s\n", pr_xfunction->s_name+progfuncs->funcs.stringtable); + externs->Printf("Tried to free free entity within %s\n", pr_xfunction->s_name+progfuncs->funcs.stringtable); else - printf("Engine tried to free free entity\n"); + externs->Printf("Engine tried to free free entity\n"); // if (developer.value == 1) // progfuncs->funcs.pr_trace = true; return; @@ -272,7 +272,7 @@ fdef_t *ED_ClassFieldAtOfs (progfuncs_t *progfuncs, unsigned int ofs, const char { int classnamelen = strlen(classname); unsigned int j; - char *mname; + const char *mname; for (j = 0; j < prinst.numfields; j++) { if (prinst.field[j].ofs == ofs) @@ -316,7 +316,7 @@ fdef_t *ED_FindField (progfuncs_t *progfuncs, const char *name) ED_FindGlobal ============ */ -ddef16_t *ED_FindGlobal16 (progfuncs_t *progfuncs, char *name) +ddef16_t *ED_FindGlobal16 (progfuncs_t *progfuncs, const char *name) { ddef16_t *def; unsigned int i; @@ -329,7 +329,7 @@ ddef16_t *ED_FindGlobal16 (progfuncs_t *progfuncs, char *name) } return NULL; } -ddef32_t *ED_FindGlobal32 (progfuncs_t *progfuncs, char *name) +ddef32_t *ED_FindGlobal32 (progfuncs_t *progfuncs, const char *name) { ddef32_t *def; unsigned int i; @@ -362,46 +362,46 @@ unsigned int ED_FindGlobalOfs (progfuncs_t *progfuncs, char *name) return 0; } -ddef16_t *ED_FindGlobalFromProgs16 (progfuncs_t *progfuncs, const char *name, progsnum_t prnum) +ddef16_t *ED_FindGlobalFromProgs16 (progfuncs_t *progfuncs, progstate_t *ps, const char *name) { ddef16_t *def; unsigned int i; - for (i=1 ; inumglobaldefs ; i++) + for (i=1 ; iprogs->numglobaldefs ; i++) { - def = &pr_progstate[prnum].globaldefs16[i]; + def = &ps->globaldefs16[i]; if (!strcmp(def->s_name+progfuncs->funcs.stringtable,name) ) return def; } return NULL; } -ddef32_t *ED_FindGlobalFromProgs32 (progfuncs_t *progfuncs, const char *name, progsnum_t prnum) +ddef32_t *ED_FindGlobalFromProgs32 (progfuncs_t *progfuncs, progstate_t *ps, const char *name) { ddef32_t *def; unsigned int i; - for (i=1 ; inumglobaldefs ; i++) + for (i=1 ; iprogs->numglobaldefs ; i++) { - def = &pr_progstate[prnum].globaldefs32[i]; + def = &ps->globaldefs32[i]; if (!strcmp(def->s_name+progfuncs->funcs.stringtable,name) ) return def; } return NULL; } -ddef16_t *ED_FindTypeGlobalFromProgs16 (progfuncs_t *progfuncs, const char *name, progsnum_t prnum, int type) +ddef16_t *ED_FindTypeGlobalFromProgs16 (progfuncs_t *progfuncs, progstate_t *ps, const char *name, int type) { ddef16_t *def; unsigned int i; - for (i=1 ; inumglobaldefs ; i++) + for (i=1 ; iprogs->numglobaldefs ; i++) { - def = &pr_progstate[prnum].globaldefs16[i]; + def = &ps->globaldefs16[i]; if (!strcmp(def->s_name+progfuncs->funcs.stringtable,name) ) { - if (pr_progstate[prnum].types) + if (ps->types) { - if (pr_progstate[prnum].types[def->type&~DEF_SAVEGLOBAL].type != type) + if (ps->types[def->type&~DEF_SAVEGLOBAL].type != type) continue; } else if ((def->type&(~DEF_SAVEGLOBAL)) != type) @@ -413,19 +413,19 @@ ddef16_t *ED_FindTypeGlobalFromProgs16 (progfuncs_t *progfuncs, const char *name } -ddef32_t *ED_FindTypeGlobalFromProgs32 (progfuncs_t *progfuncs, const char *name, progsnum_t prnum, int type) +ddef32_t *ED_FindTypeGlobalFromProgs32 (progfuncs_t *progfuncs, progstate_t *ps, const char *name, int type) { ddef32_t *def; unsigned int i; - for (i=1 ; inumglobaldefs ; i++) + for (i=1 ; iprogs->numglobaldefs ; i++) { - def = &pr_progstate[prnum].globaldefs32[i]; + def = &ps->globaldefs32[i]; if (!strcmp(def->s_name+progfuncs->funcs.stringtable,name) ) { - if (pr_progstate[prnum].types) + if (ps->types) { - if (pr_progstate[prnum].types[def->type&~DEF_SAVEGLOBAL].type != type) + if (ps->types[def->type&~DEF_SAVEGLOBAL].type != type) continue; } else if ((def->type&(~DEF_SAVEGLOBAL)) != (unsigned)type) @@ -436,23 +436,23 @@ ddef32_t *ED_FindTypeGlobalFromProgs32 (progfuncs_t *progfuncs, const char *name return NULL; } -unsigned int *ED_FindGlobalOfsFromProgs (progfuncs_t *progfuncs, char *name, progsnum_t prnum, int type) +unsigned int *ED_FindGlobalOfsFromProgs (progfuncs_t *progfuncs, progstate_t *ps, char *name, int type) { ddef16_t *def16; ddef32_t *def32; static unsigned int pos; - switch(pr_progstate[prnum].structtype) + switch(ps->structtype) { case PST_DEFAULT: case PST_KKQWSV: - def16 = ED_FindTypeGlobalFromProgs16(progfuncs, name, prnum, type); + def16 = ED_FindTypeGlobalFromProgs16(progfuncs, ps, name, type); if (!def16) return NULL; pos = def16->ofs; return &pos; case PST_QTEST: case PST_FTE32: - def32 = ED_FindTypeGlobalFromProgs32(progfuncs, name, prnum, type); + def32 = ED_FindTypeGlobalFromProgs32(progfuncs, ps, name, type); if (!def32) return NULL; return &def32->ofs; @@ -496,7 +496,7 @@ mfunction_t *ED_FindFunction (progfuncs_t *progfuncs, const char *name, progsnum if ((unsigned)pnum > (unsigned)prinst.maxprogs) { - printf("Progsnum %i out of bounds\n", pnum); + externs->Printf("Progsnum %i out of bounds\n", pnum); return NULL; } @@ -997,16 +997,16 @@ void PDECL ED_Print (pubprogfuncs_t *ppf, struct edict_s *ed) fdef_t *d; int *v; unsigned int i;unsigned int j; - char *name; + const char *name; int type; if (((edictrun_t *)ed)->ereftype == ER_FREE) { - printf ("FREE\n"); + externs->Printf ("FREE\n"); return; } - printf("\nEDICT %i:\n", NUM_FOR_EDICT(progfuncs, (struct edict_s *)ed)); + externs->Printf("\nEDICT %i:\n", NUM_FOR_EDICT(progfuncs, (struct edict_s *)ed)); for (i=1 ; iPrintf ("%s",name); l = strlen (name); while (l++ < 15) - printf (" "); + externs->Printf (" "); - printf ("%s\n", PR_ValueString(progfuncs, d->type, (eval_t *)v, false)); + externs->Printf ("%s\n", PR_ValueString(progfuncs, d->type, (eval_t *)v, false)); } } #if 0 @@ -1055,7 +1055,7 @@ void ED_PrintEdicts (progfuncs_t *progfuncs) { unsigned int i; - printf ("%i entities\n", sv_num_edicts); + externs->Printf ("%i entities\n", sv_num_edicts); for (i=0 ; iPrintf ("num_edicts:%3i\n", sv_num_edicts); + externs->Printf ("active :%3i\n", active); // Con_Printf ("view :%3i\n", models); // Con_Printf ("touch :%3i\n", solid); // Con_Printf ("step :%3i\n", step); @@ -1217,7 +1217,7 @@ pbool PDECL ED_ParseEval (pubprogfuncs_t *ppf, eval_t *eval, int type, const cha def = ED_FindField (progfuncs, s); if (!def) { - printf ("Can't find field %s\n", s); + externs->Printf ("Can't find field %s\n", s); return false; } eval->_int = def->ofs; @@ -1232,7 +1232,7 @@ pbool PDECL ED_ParseEval (pubprogfuncs_t *ppf, eval_t *eval, int type, const cha func = ED_FindFunction (progfuncs, s, &i, -1); if (!func) { - printf ("Can't find function %s\n", s); + externs->Printf ("Can't find function %s\n", s); return false; } eval->function = (func - pr_progstate[i].functions) | (i<<24); @@ -1306,7 +1306,7 @@ pbool ED_ParseEpair (progfuncs_t *progfuncs, size_t qcptr, unsigned int fldofs, def = ED_FindField (progfuncs, s); if (!def) { - printf ("Can't find field %s\n", s); + externs->Printf ("Can't find field %s\n", s); return false; } *(int *)(progfuncs->funcs.stringtable + qcptr) = def->ofs; @@ -1321,7 +1321,7 @@ pbool ED_ParseEpair (progfuncs_t *progfuncs, size_t qcptr, unsigned int fldofs, func = ED_FindFunction (progfuncs, s, &i, -1); if (!func) { - printf ("Can't find function %s\n", s); + externs->Printf ("Can't find function %s\n", s); return false; } *(func_t *)(progfuncs->funcs.stringtable + qcptr) = (func - pr_progstate[i].functions) | (i<<24); @@ -1374,7 +1374,7 @@ static const char *ED_ParseEdict (progfuncs_t *progfuncs, const char *data, edic nest++; if (!data) { - printf ("ED_ParseEntity: EOF without closing brace\n"); + externs->Printf ("ED_ParseEntity: EOF without closing brace\n"); return NULL; } if (nest > 1) @@ -1395,13 +1395,13 @@ static const char *ED_ParseEdict (progfuncs_t *progfuncs, const char *data, edic data = QCC_COM_Parse (data); if (!data) { - printf ("ED_ParseEntity: EOF without closing brace\n"); + externs->Printf ("ED_ParseEntity: EOF without closing brace\n"); return NULL; } if (qcc_token[0] == '}') { - printf ("ED_ParseEntity: closing brace without data\n"); + externs->Printf ("ED_ParseEntity: closing brace without data\n"); return NULL; } @@ -1633,7 +1633,7 @@ char *ED_WriteEdict(progfuncs_t *progfuncs, edictrun_t *ed, char *buf, size_t *b fdef_t *d; int *v; unsigned int i;unsigned int j; - char *name; + const char *name; int type; int len; char *tmp; @@ -2126,7 +2126,7 @@ int PDECL PR_LoadEnts(pubprogfuncs_t *ppf, const char *file, void *ctx, void (PD case PST_KKQWSV: if (!(d16 = ED_FindGlobal16(progfuncs, qcc_token))) { - printf("global value %s not found\n", qcc_token); + externs->Printf("global value %s not found\n", qcc_token); file = QCC_COM_Parse(file); } else @@ -2139,7 +2139,7 @@ int PDECL PR_LoadEnts(pubprogfuncs_t *ppf, const char *file, void *ctx, void (PD case PST_FTE32: if (!(d32 = ED_FindGlobal32(progfuncs, qcc_token))) { - printf("global value %s not found\n", qcc_token); + externs->Printf("global value %s not found\n", qcc_token); file = QCC_COM_Parse(file); } else @@ -2203,7 +2203,7 @@ int PDECL PR_LoadEnts(pubprogfuncs_t *ppf, const char *file, void *ctx, void (PD memcpy(oldglobals, pr_progstate[0].globals, oldglobalssize); } else - printf("Unable to alloc %i bytes\n", pr_progstate[0].globals_size); + externs->Printf("Unable to alloc %i bytes\n", pr_progstate[0].globals_size); } PRAddressableFlush(progfuncs, 0); @@ -2241,7 +2241,7 @@ int PDECL PR_LoadEnts(pubprogfuncs_t *ppf, const char *file, void *ctx, void (PD case PST_KKQWSV: if (!(d16 = ED_FindGlobal16(progfuncs, qcc_token))) { - printf("global value %s not found\n", qcc_token); + externs->Printf("global value %s not found\n", qcc_token); file = QCC_COM_Parse(file); } else @@ -2254,7 +2254,7 @@ int PDECL PR_LoadEnts(pubprogfuncs_t *ppf, const char *file, void *ctx, void (PD case PST_FTE32: if (!(d32 = ED_FindGlobal32(progfuncs, qcc_token))) { - printf("global value %s not found\n", qcc_token); + externs->Printf("global value %s not found\n", qcc_token); file = QCC_COM_Parse(file); } else @@ -2345,7 +2345,7 @@ char *PDECL PR_SaveEnt (pubprogfuncs_t *ppf, char *buf, size_t *size, size_t max fdef_t *d; int *v; unsigned int i;unsigned int j; - char *name, *mname; + const char *name, *mname; const char *classname = NULL; int classnamelen = 0; int type; @@ -2493,7 +2493,7 @@ void PR_TestForWierdness(progfuncs_t *progfuncs) if ((pr_globaldefs16[i].type&~(DEF_SHARED|DEF_SAVEGLOBAL)) == ev_string) { if (G_INT(pr_globaldefs16[i].ofs) < 0 || G_INT(pr_globaldefs16[i].ofs) >= addressableused) - printf("String type irregularity on \"%s\" \"%s\"\n", pr_globaldefs16[i].s_name+progfuncs->funcs.stringtable, G_INT(pr_globaldefs16[i].ofs)+progfuncs->funcs.stringtable); + externs->Printf("String type irregularity on \"%s\" \"%s\"\n", pr_globaldefs16[i].s_name+progfuncs->funcs.stringtable, G_INT(pr_globaldefs16[i].ofs)+progfuncs->funcs.stringtable); } } @@ -2507,7 +2507,7 @@ void PR_TestForWierdness(progfuncs_t *progfuncs) if (ed->isfree) continue; if (((int *)ed->fields)[field[i].ofs] < 0 || ((int *)ed->fields)[field[i].ofs] >= addressableused) - printf("String type irregularity \"%s\" \"%s\"\n", field[i].name, ((int *)ed->fields)[field[i].ofs]+progfuncs->funcs.stringtable); + externs->Printf("String type irregularity \"%s\" \"%s\"\n", field[i].name, ((int *)ed->fields)[field[i].ofs]+progfuncs->funcs.stringtable); } } } @@ -2629,7 +2629,7 @@ int PR_ReallyLoadProgs (progfuncs_t *progfuncs, const char *filename, progstate_ if (externs->autocompile == PR_COMPILEALWAYS) //always compile before loading { - printf("Forcing compile of progs %s\n", filename); + externs->Printf("Forcing compile of progs %s\n", filename); if (!CompileFile(progfuncs, filename)) return false; } @@ -2645,13 +2645,13 @@ retry: { if (hmark==0xffffffff) //first try { - printf("couldn't open progs %s. Attempting to compile.\n", filename); + externs->Printf("couldn't open progs %s. Attempting to compile.\n", filename); CompileFile(progfuncs, filename); } pr_progs = externs->ReadFile(filename, PR_GetHeapBuffer, progfuncs, &fsz, false); if (!pr_progs) { - printf("Couldn't find or compile file %s\n", filename); + externs->Printf("Couldn't find or compile file %s\n", filename); return false; } } @@ -2659,7 +2659,7 @@ retry: return false; else { - printf("Couldn't find file %s\n", filename); + externs->Printf("Couldn't find file %s\n", filename); return false; } } @@ -2675,7 +2675,7 @@ retry: if (pr_progs->version == PROG_VERSION) { -// printf("Opening standard progs file \"%s\"\n", filename); +// externs->Printf("Opening standard progs file \"%s\"\n", filename); current_progstate->structtype = PST_DEFAULT; } else if (pr_progs->version == PROG_QTESTVERSION) @@ -2690,23 +2690,23 @@ retry: #endif if (pr_progs->secondaryversion == PROG_SECONDARYVERSION16) { -// printf("Opening 16bit fte progs file \"%s\"\n", filename); +// externs->Printf("Opening 16bit fte progs file \"%s\"\n", filename); current_progstate->structtype = PST_DEFAULT; } else if (pr_progs->secondaryversion == PROG_SECONDARYVERSION32) { -// printf("Opening 32bit fte progs file \"%s\"\n", filename); +// externs->Printf("Opening 32bit fte progs file \"%s\"\n", filename); current_progstate->structtype = PST_FTE32; } else { -// printf("Opening KK7 progs file \"%s\"\n", filename); +// externs->Printf("Opening KK7 progs file \"%s\"\n", filename); current_progstate->structtype = PST_KKQWSV; //KK progs. Yuck. Disabling saving would be a VERY good idea. pr_progs->version = PROG_VERSION; //not fte. } /* else { - printf ("Progs extensions are not compatible\nTry recompiling with the FTE compiler\n"); + externs->Printf ("Progs extensions are not compatible\nTry recompiling with the FTE compiler\n"); HunkFree(hmark); pr_progs=NULL; return false; @@ -2714,7 +2714,7 @@ retry: */ } else { - printf ("%s has wrong version number (%i should be %i)\n", filename, pr_progs->version, PROG_VERSION); + externs->Printf ("%s has wrong version number (%i should be %i)\n", filename, pr_progs->version, PROG_VERSION); PRHunkFree(progfuncs, hmark); pr_progs=NULL; return false; @@ -2725,7 +2725,7 @@ retry: { if (PR_TestRecompile(progfuncs)) { - printf("Source file has changed\nRecompiling.\n"); + externs->Printf("Source file has changed\nRecompiling.\n"); if (CompileFile(progfuncs, filename)) { PRHunkFree(progfuncs, hmark); @@ -2737,11 +2737,11 @@ retry: } } if (!trysleft) //the progs exists, let's just be happy about it. - printf("Progs is out of date and uncompilable\n"); + externs->Printf("Progs is out of date and uncompilable\n"); if (externs->CheckHeaderCrc && !externs->CheckHeaderCrc(&progfuncs->funcs, prinst.pr_typecurrent, pr_progs->crc)) { -// printf ("%s system vars have been modified, progdefs.h is out of date\n", filename); +// externs->Printf ("%s system vars have been modified, progdefs.h is out of date\n", filename); PRHunkFree(progfuncs, hmark); pr_progs=NULL; return false; @@ -2749,7 +2749,7 @@ retry: if (pr_progs->version == PROG_EXTENDEDVERSION && pr_progs->blockscompressed && !QC_decodeMethodSupported(2)) { - printf ("%s uses compression\n", filename); + externs->Printf ("%s uses compression\n", filename); PRHunkFree(progfuncs, hmark); pr_progs=NULL; return false; @@ -3327,7 +3327,7 @@ retry: break; case ev_string: if (((unsigned int *)glob)[gd16[i].ofs]>=progstate->progs->numstrings) - printf("PR_LoadProgs: invalid string value (%x >= %x) in '%s'\n", ((unsigned int *)glob)[gd16[i].ofs], progstate->progs->numstrings, gd16[i].s_name+pr_strings-stringadjust); + externs->Printf("PR_LoadProgs: invalid string value (%x >= %x) in '%s'\n", ((unsigned int *)glob)[gd16[i].ofs], progstate->progs->numstrings, gd16[i].s_name+pr_strings-stringadjust); else if (isfriked != -1) { if (pr_strings[((int *)glob)[gd16[i].ofs]]) //quakec uses string tables. 0 must remain null, or 'if (s)' can break. @@ -3391,7 +3391,7 @@ retry: for (i = 0; i < pr_progs->numbodylessfuncs; i++) { d32 = ED_FindGlobal32(progfuncs, s); - d2 = ED_FindGlobalOfsFromProgs(progfuncs, s, 0, ev_function); + d2 = ED_FindGlobalOfsFromProgs(progfuncs, &pr_progstate[0], s, ev_function); if (!d2) Sys_Error("Runtime-linked function %s was not found in existing progs", s); if (!d32) @@ -3408,7 +3408,7 @@ retry: if ((isfriked && prinst.pr_typecurrent)) //friked progs only allow one file. { - printf("You are trying to load a string-stripped progs as an addon.\nThis behaviour is not supported. Try removing some optimizations."); + externs->Printf("You are trying to load a string-stripped progs as an addon.\nThis behaviour is not supported. Try removing some optimizations."); PRHunkFree(progfuncs, hmark); pr_progs=NULL; return false; @@ -3445,7 +3445,7 @@ retry: d16 = ED_FindGlobal16(progfuncs, s); if (!d16) { - printf("\"%s\" requires the external function \"%s\", but the definition was stripped\n", filename, s); + externs->Printf("\"%s\" requires the external function \"%s\", but the definition was stripped\n", filename, s); PRHunkFree(progfuncs, hmark); pr_progs=NULL; return false; @@ -3453,7 +3453,7 @@ retry: ((int *)glob)[d16->ofs] = PR_FindFunc(&progfuncs->funcs, s, PR_ANY); if (!((int *)glob)[d16->ofs]) - printf("Warning: Runtime-linked function %s could not be found (loading %s)\n", s, filename); + externs->Printf("Warning: Runtime-linked function %s could not be found (loading %s)\n", s, filename); s+=strlen(s)+1; } } @@ -3470,7 +3470,7 @@ retry: d32 = ED_FindGlobal32(progfuncs, s); if (!d32) { - printf("\"%s\" requires the external function \"%s\", but the definition was stripped\n", filename, s); + externs->Printf("\"%s\" requires the external function \"%s\", but the definition was stripped\n", filename, s); PRHunkFree(progfuncs, hmark); pr_progs=NULL; return false; @@ -3478,7 +3478,7 @@ retry: ((int *)glob)[d32->ofs] = PR_FindFunc(&progfuncs->funcs, s, PR_ANY); if (!((int *)glob)[d32->ofs]) - printf("Warning: Runtime-linked function %s could not be found (loading %s)\n", s, filename); + externs->Printf("Warning: Runtime-linked function %s could not be found (loading %s)\n", s, filename); s+=strlen(s)+1; } } diff --git a/engine/qclib/pr_exec.c b/engine/qclib/pr_exec.c index 338dbe002..ee1cb21a8 100644 --- a/engine/qclib/pr_exec.c +++ b/engine/qclib/pr_exec.c @@ -126,36 +126,36 @@ static void PR_PrintStatement (progfuncs_t *progfuncs, int statementnum) if ( (unsigned)op < OP_NUMOPS) { int i; - printf ("%s ", pr_opcodes[op].name); + externs->Printf ("%s ", pr_opcodes[op].name); i = strlen(pr_opcodes[op].name); for ( ; i<10 ; i++) - printf (" "); + externs->Printf (" "); } else #endif - printf ("op%3i ", op); + externs->Printf ("op%3i ", op); if (op == OP_IF_F || op == OP_IFNOT_F) - printf ("%sbranch %i",PR_GlobalString(progfuncs, arg[0]),arg[1]); + externs->Printf ("%sbranch %i",PR_GlobalString(progfuncs, arg[0]),arg[1]); else if (op == OP_GOTO) { - printf ("branch %i",arg[0]); + externs->Printf ("branch %i",arg[0]); } else if ( (unsigned)(op - OP_STORE_F) < 6) { - printf ("%s",PR_GlobalString(progfuncs, arg[0])); - printf ("%s", PR_GlobalStringNoContents(progfuncs, arg[1])); + externs->Printf ("%s",PR_GlobalString(progfuncs, arg[0])); + externs->Printf ("%s", PR_GlobalStringNoContents(progfuncs, arg[1])); } else { if (arg[0]) - printf ("%s",PR_GlobalString(progfuncs, arg[0])); + externs->Printf ("%s",PR_GlobalString(progfuncs, arg[0])); if (arg[1]) - printf ("%s",PR_GlobalString(progfuncs, arg[1])); + externs->Printf ("%s",PR_GlobalString(progfuncs, arg[1])); if (arg[2]) - printf ("%s", PR_GlobalStringNoContents(progfuncs, arg[2])); + externs->Printf ("%s", PR_GlobalStringNoContents(progfuncs, arg[2])); } - printf ("\n"); + externs->Printf ("\n"); } #ifdef _WIN32 @@ -355,9 +355,9 @@ static void PDECL PR_PrintRelevantLocals(progfuncs_t *progfuncs) else fdef = ED_FieldAtOfs(progfuncs, ((eval_t *)&pr_globals[st16[st].b])->_int); if (fdef) - printf(" %s.%s: %s\n", PR_StringToNative(&progfuncs->funcs, ent->s_name), PR_StringToNative(&progfuncs->funcs, fld->s_name), PR_ValueString(progfuncs, fdef->type, ptr, false)); + externs->Printf(" %s.%s: %s\n", PR_StringToNative(&progfuncs->funcs, ent->s_name), PR_StringToNative(&progfuncs->funcs, fld->s_name), PR_ValueString(progfuncs, fdef->type, ptr, false)); else - printf(" %s.%s: BAD FIELD DEF - %#x\n", PR_StringToNative(&progfuncs->funcs, ent->s_name), PR_StringToNative(&progfuncs->funcs, fld->s_name), ptr->_int); + externs->Printf(" %s.%s: BAD FIELD DEF - %#x\n", PR_StringToNative(&progfuncs->funcs, ent->s_name), PR_StringToNative(&progfuncs->funcs, fld->s_name), ptr->_int); } } } @@ -376,7 +376,7 @@ void PDECL PR_StackTrace (pubprogfuncs_t *ppf, int showlocals) if (pr_depth == 0) { - printf ("\n"); + externs->Printf ("\n"); return; } @@ -402,7 +402,7 @@ void PDECL PR_StackTrace (pubprogfuncs_t *ppf, int showlocals) if (!f) { - printf ("\n"); + externs->Printf ("\n"); } else { @@ -412,16 +412,16 @@ void PDECL PR_StackTrace (pubprogfuncs_t *ppf, int showlocals) { progs = prnum; - printf ("<%s>\n", pr_progstate[progs].filename); + externs->Printf ("<%s>\n", pr_progstate[progs].filename); } if (!f->s_file) - printf ("stripped : %s\n", PR_StringToNative(ppf, f->s_name)); + externs->Printf ("stripped : %s\n", PR_StringToNative(ppf, f->s_name)); else { if (pr_progstate[progs].linenums) - printf ("%12s:%i: %s\n", PR_StringToNative(ppf, f->s_file), pr_progstate[progs].linenums[st], PR_StringToNative(ppf, f->s_name)); + externs->Printf ("%12s:%i: %s\n", PR_StringToNative(ppf, f->s_file), pr_progstate[progs].linenums[st], PR_StringToNative(ppf, f->s_name)); else - printf ("%12s : %s\n", PR_StringToNative(ppf, f->s_file), PR_StringToNative(ppf, f->s_name)); + externs->Printf ("%12s : %s\n", PR_StringToNative(ppf, f->s_file), PR_StringToNative(ppf, f->s_name)); } //locals:0 = no locals @@ -446,20 +446,20 @@ void PDECL PR_StackTrace (pubprogfuncs_t *ppf, int showlocals) { if (f->parm_size[arg] == 3) { //looks like a vector. print it as such - printf(" arg%i(%i): [%g, %g, %g]\n", arg, f->parm_start+ofs, *(float *)(globalbase+ofs), *(float *)(globalbase+ofs+1), *(float *)(globalbase+ofs+2)); + externs->Printf(" arg%i(%i): [%g, %g, %g]\n", arg, f->parm_start+ofs, *(float *)(globalbase+ofs), *(float *)(globalbase+ofs+1), *(float *)(globalbase+ofs+2)); ofs += 2; } else - printf(" arg%i(%i): %g===%i\n", arg, f->parm_start+ofs, *(float *)(globalbase+ofs), *(int *)(globalbase+ofs) ); + externs->Printf(" arg%i(%i): %g===%i\n", arg, f->parm_start+ofs, *(float *)(globalbase+ofs), *(int *)(globalbase+ofs) ); } else { - printf(" unk(%i): %g===%i\n", f->parm_start+ofs, *(float *)(globalbase+ofs), *(int *)(globalbase+ofs) ); + externs->Printf(" unk(%i): %g===%i\n", f->parm_start+ofs, *(float *)(globalbase+ofs), *(int *)(globalbase+ofs) ); } } else { - printf(" %s: %s\n", local->s_name+progfuncs->funcs.stringtable, PR_ValueString(progfuncs, local->type, (eval_t*)(globalbase+ofs), false)); + externs->Printf(" %s: %s\n", local->s_name+progfuncs->funcs.stringtable, PR_ValueString(progfuncs, local->type, (eval_t*)(globalbase+ofs), false)); if (local->type == ev_vector) ofs+=2; } @@ -501,7 +501,7 @@ int ASMCALL PR_EnterFunction (progfuncs_t *progfuncs, mfunction_t *f, int progsn { PR_StackTrace (&progfuncs->funcs, false); - printf ("stack overflow on call to %s (depth %i)\n", progfuncs->funcs.stringtable+f->s_name, pr_depth); + externs->Printf ("stack overflow on call to %s (depth %i)\n", progfuncs->funcs.stringtable+f->s_name, pr_depth); //comment this out if you want the progs to try to continue anyway (could cause infinate loops) PR_AbortStack(&progfuncs->funcs); @@ -587,7 +587,7 @@ int ASMCALL PR_LeaveFunction (progfuncs_t *progfuncs) prclocks_t cycles; cycles = Sys_GetClock() - st->timestamp; if (cycles > prinst.profilingalert) - printf("QC call to %s took over a second\n", PR_StringToNative(&progfuncs->funcs,pr_xfunction->s_name)); + externs->Printf("QC call to %s took over a second\n", PR_StringToNative(&progfuncs->funcs,pr_xfunction->s_name)); pr_xfunction->profiletime += cycles; pr_xfunction = st->f; if (pr_depth) @@ -600,17 +600,18 @@ int ASMCALL PR_LeaveFunction (progfuncs_t *progfuncs) return st->s; } -ddef32_t *ED_FindLocalOrGlobal(progfuncs_t *progfuncs, char *name, eval_t **val) +ddef32_t *ED_FindLocalOrGlobal(progfuncs_t *progfuncs, const char *name, eval_t **val) { static ddef32_t def; ddef32_t *def32; ddef16_t *def16; int i; + progstate_t *cp = current_progstate; - if (prinst.pr_typecurrent < 0) + if (!cp) return NULL; - switch (pr_progstate[prinst.pr_typecurrent].structtype) + switch (cp->structtype) { case PST_DEFAULT: case PST_KKQWSV: @@ -623,7 +624,7 @@ ddef32_t *ED_FindLocalOrGlobal(progfuncs_t *progfuncs, char *name, eval_t **val) continue; if (!strcmp(def16->s_name+progfuncs->funcs.stringtable, name)) { - *val = (eval_t *)&pr_progstate[prinst.pr_typecurrent].globals[pr_xfunction->parm_start+i]; + *val = (eval_t *)&cp->globals[pr_xfunction->parm_start+i]; //we need something like this for functions that are not the top layer // *val = (eval_t *)&localstack[localstack_used-pr_xfunction->numparms*4]; @@ -652,7 +653,7 @@ ddef32_t *ED_FindLocalOrGlobal(progfuncs_t *progfuncs, char *name, eval_t **val) continue; if (!strcmp(def32->s_name+progfuncs->funcs.stringtable, name)) { - *val = (eval_t *)&pr_progstate[prinst.pr_typecurrent].globals[pr_xfunction->parm_start+i]; + *val = (eval_t *)&cp->globals[pr_xfunction->parm_start+i]; //we need something like this for functions that are not the top layer // *val = (eval_t *)&localstack[localstack_used-pr_xfunction->numparms*4]; @@ -668,11 +669,11 @@ ddef32_t *ED_FindLocalOrGlobal(progfuncs_t *progfuncs, char *name, eval_t **val) def32 = NULL; } - *val = (eval_t *)&pr_progstate[prinst.pr_typecurrent].globals[def32->ofs]; + *val = (eval_t *)&cp->globals[def32->ofs]; return &def; } -static char *COM_TrimString(char *str, char *buffer, int buffersize) +static char *COM_TrimString(const char *str, char *buffer, int buffersize) { int i; while (*str <= ' ' && *str>'\0') @@ -688,7 +689,7 @@ static char *COM_TrimString(char *str, char *buffer, int buffersize) return buffer; } -pbool LocateDebugTerm(progfuncs_t *progfuncs, char *key, eval_t **result, etype_t *rettype, eval_t *store) +pbool LocateDebugTerm(progfuncs_t *progfuncs, const char *key, eval_t **result, etype_t *rettype, eval_t *store) { ddef32_t *def; fdef_t *fdef; @@ -781,7 +782,7 @@ pbool LocateDebugTerm(progfuncs_t *progfuncs, char *key, eval_t **result, etype_ return true; } -pbool PDECL PR_SetWatchPoint(pubprogfuncs_t *ppf, char *key) +pbool PDECL PR_SetWatchPoint(pubprogfuncs_t *ppf, const char *key) { progfuncs_t *progfuncs = (progfuncs_t *)ppf; eval_t *val; @@ -798,17 +799,17 @@ pbool PDECL PR_SetWatchPoint(pubprogfuncs_t *ppf, char *key) } if (!LocateDebugTerm(progfuncs, key, &val, &type, &fakeval)) { - printf("Unable to evaluate watch term \"%s\"\n", key); + externs->Printf("Unable to evaluate watch term \"%s\"\n", key); return false; } if (val == &fakeval) { - printf("Do you like watching paint dry?\n"); + externs->Printf("Do you like watching paint dry?\n"); return false; } if (type == ev_vector) { - printf("Unable to watch vectors. Watching the x field instead.\n"); + externs->Printf("Unable to watch vectors. Watching the x field instead.\n"); type = ev_float; } @@ -820,7 +821,7 @@ pbool PDECL PR_SetWatchPoint(pubprogfuncs_t *ppf, char *key) return true; } -static char *PR_ParseCast(char *key, etype_t *t, pbool *isptr) +static const char *PR_ParseCast(const char *key, etype_t *t, pbool *isptr) { extern char *basictypenames[]; int type; @@ -857,7 +858,7 @@ static char *PR_ParseCast(char *key, etype_t *t, pbool *isptr) } return key; } -char *PDECL PR_EvaluateDebugString(pubprogfuncs_t *ppf, char *key) +char *PDECL PR_EvaluateDebugString(pubprogfuncs_t *ppf, const char *key) { progfuncs_t *progfuncs = (progfuncs_t*)ppf; static char buf[8192]; @@ -1122,31 +1123,36 @@ int PDECL PR_SortBreakFunctions(const void *va, const void *vb) } //0 clear. 1 set, 2 toggle, 3 check -int PDECL PR_ToggleBreakpoint(pubprogfuncs_t *ppf, char *filename, int linenum, int flag) //write alternate route to work by function name. +int PDECL PR_ToggleBreakpoint(pubprogfuncs_t *ppf, const char *filename, int linenum, int flag) //write alternate route to work by function name. { progfuncs_t *progfuncs = (progfuncs_t*)ppf; int ret=0; unsigned int fl, stline; - unsigned int i; - int pn = prinst.pr_typecurrent; + unsigned int i, j; + + progstate_t *cp; mfunction_t *f; int op = 0; //warning about not being initialized before use - for (pn = 0; (unsigned)pn < prinst.maxprogs; pn++) + if (!pr_progstate) + return ret; + + for (j = 0; j < prinst.maxprogs; j++) { - if (!pr_progstate || !pr_progstate[pn].progs) + cp = &pr_progstate[j]; + if (!cp->progs) continue; if (linenum) //linenum is set means to set the breakpoint on a file and line { struct sortedfunc_s *sortedstatements; int numfilefunctions = 0; - if (!pr_progstate[pn].linenums) + if (!cp->linenums) continue; - sortedstatements = alloca(pr_progstate[pn].progs->numfunctions * sizeof(*sortedstatements)); + sortedstatements = alloca(cp->progs->numfunctions * sizeof(*sortedstatements)); //we need to use the function table in order to set breakpoints in the right file. - for (f = pr_progstate[pn].functions, fl = 0; fl < pr_progstate[pn].progs->numfunctions; f++, fl++) + for (f = cp->functions, fl = 0; fl < cp->progs->numfunctions; f++, fl++) { const char *fncfile = f->s_file+progfuncs->funcs.stringtable; if (fncfile[0] == '.' && fncfile[1] == '/') @@ -1154,10 +1160,10 @@ int PDECL PR_ToggleBreakpoint(pubprogfuncs_t *ppf, char *filename, int linenum, if (!stricmp(fncfile, filename)) { sortedstatements[numfilefunctions].firststatement = f->first_statement; - if (f->first_statement < 0 || f->first_statement >= (int)pr_progstate[pn].progs->numstatements) + if (f->first_statement < 0 || f->first_statement >= (int)cp->progs->numstatements) sortedstatements[numfilefunctions].firstline = 0; else - sortedstatements[numfilefunctions].firstline = pr_progstate[pn].linenums[f->first_statement]; + sortedstatements[numfilefunctions].firstline = cp->linenums[f->first_statement]; numfilefunctions++; } } @@ -1167,25 +1173,25 @@ int PDECL PR_ToggleBreakpoint(pubprogfuncs_t *ppf, char *filename, int linenum, //our functions are now in terms of ascending line numbers. for (fl = 0; fl < numfilefunctions; fl++) { - for (i = sortedstatements[fl].firststatement; i < pr_progstate[pn].progs->numstatements; i++) + for (i = sortedstatements[fl].firststatement; i < cp->progs->numstatements; i++) { - if (pr_progstate[pn].linenums[i] >= linenum) + if (cp->linenums[i] >= linenum) { - stline = pr_progstate[pn].linenums[i]; + stline = cp->linenums[i]; for (; ; i++) { - if ((unsigned int)pr_progstate[pn].linenums[i] != stline) + if ((unsigned int)cp->linenums[i] != stline) break; - switch(pr_progstate[pn].structtype) + switch(cp->structtype) { case PST_DEFAULT: case PST_QTEST: - op = ((dstatement16_t*)pr_progstate[pn].statements + i)->op; + op = ((dstatement16_t*)cp->statements + i)->op; break; case PST_KKQWSV: case PST_FTE32: - op = ((dstatement32_t*)pr_progstate[pn].statements + i)->op; + op = ((dstatement32_t*)cp->statements + i)->op; break; default: Sys_Error("Bad structtype"); @@ -1219,44 +1225,47 @@ int PDECL PR_ToggleBreakpoint(pubprogfuncs_t *ppf, char *filename, int linenum, if (op & OP_BIT_BREAKPOINT) return true; } - switch(pr_progstate[pn].structtype) + switch(cp->structtype) { case PST_DEFAULT: case PST_QTEST: - ((dstatement16_t*)pr_progstate[pn].statements + i)->op = op; + ((dstatement16_t*)cp->statements + i)->op = op; break; case PST_KKQWSV: case PST_FTE32: - ((dstatement32_t*)pr_progstate[pn].statements + i)->op = op; + ((dstatement32_t*)cp->statements + i)->op = op; break; default: Sys_Error("Bad structtype"); op = 0; } if (ret) //if its set, only set one breakpoint statement, not all of them. - return true; + break; + + if ((op & ~OP_BIT_BREAKPOINT) == OP_DONE) + break; //give up when we see the function's done. } - goto cont; + goto cont; //next progs } } } } else //set the breakpoint on the first statement of the function specified. { - for (f = pr_progstate[pn].functions, fl = 0; fl < pr_progstate[pn].progs->numfunctions; f++, fl++) + for (f = cp->functions, fl = 0; fl < cp->progs->numfunctions; f++, fl++) { if (!strcmp(f->s_name+progfuncs->funcs.stringtable, filename)) { i = f->first_statement; - switch(pr_progstate[pn].structtype) + switch(cp->structtype) { case PST_DEFAULT: case PST_QTEST: - op = ((dstatement16_t*)pr_progstate[pn].statements + i)->op; + op = ((dstatement16_t*)cp->statements + i)->op; break; case PST_KKQWSV: case PST_FTE32: - op = ((dstatement32_t*)pr_progstate[pn].statements + i)->op; + op = ((dstatement32_t*)cp->statements + i)->op; break; default: Sys_Error("Bad structtype"); @@ -1289,15 +1298,15 @@ int PDECL PR_ToggleBreakpoint(pubprogfuncs_t *ppf, char *filename, int linenum, if (op & 0x8000) return true; } - switch(pr_progstate[pn].structtype) + switch(cp->structtype) { case PST_DEFAULT: case PST_QTEST: - ((dstatement16_t*)pr_progstate[pn].statements + i)->op = op; + ((dstatement16_t*)cp->statements + i)->op = op; break; case PST_KKQWSV: case PST_FTE32: - ((dstatement32_t*)pr_progstate[pn].statements + i)->op = op; + ((dstatement32_t*)cp->statements + i)->op = op; break; default: Sys_Error("Bad structtype"); @@ -1315,11 +1324,11 @@ cont: int ShowStep(progfuncs_t *progfuncs, int statement, char *fault, pbool fatal) { -// return statement; -// texture realcursortex; +//FIXME: statics are evil, but at least the lastfile pointer check _should_ isolate different vms. static unsigned int lastline = 0; -static unsigned int ignorestatement = 0; // -static const char *lastfile = 0; +static unsigned int ignorestatement = 0; +static const char *lastfile = NULL; + const char *file = NULL; int pn = prinst.pr_typecurrent; int i; @@ -1336,13 +1345,14 @@ static const char *lastfile = 0; return statement; } - if (f && externs->useeditor) + if (f) { for(;;) //for DEBUG_TRACE_NORESUME handling { + file = PR_StringToNative(&progfuncs->funcs, f->s_file); if (pr_progstate[pn].linenums) { - if (lastline == pr_progstate[pn].linenums[statement] && lastfile == f->s_file+progfuncs->funcs.stringtable && statement == ignorestatement && !fault) + if (lastline == pr_progstate[pn].linenums[statement] && lastfile == file && statement == ignorestatement && !fault) { ignorestatement++; return statement; //no info/same line as last time @@ -1352,13 +1362,16 @@ static const char *lastfile = 0; } else lastline = -1; - lastfile = PR_StringToNative(&progfuncs->funcs, f->s_file); + lastfile = file; faultline = lastline; debugaction = externs->useeditor(&progfuncs->funcs, lastfile, ((lastline!=-1)?&lastline:NULL), &statement, fault, fatal); +// if (pn != prinst.pr_typecurrent) + //if they changed the line to execute, we need to find a statement that is on that line if (lastline && faultline != lastline) + if (pr_progstate[pn].linenums) { switch(pr_progstate[pn].structtype) { @@ -1425,13 +1438,6 @@ static const char *lastfile = 0; break; } } - else if (f) //annoying. - { - if (*(f->s_file+progfuncs->funcs.stringtable)) //if we can't get the filename, then it was stripped, and debugging it like this is useless - if (externs->useeditor) - externs->useeditor(&progfuncs->funcs, f->s_file+progfuncs->funcs.stringtable, NULL, NULL, fault, fatal); - return statement; - } ignorestatement = statement+1; return statement; @@ -1470,7 +1476,7 @@ PR_RunError Aborts the currently executing function ============ */ -void VARGS PR_RunError (pubprogfuncs_t *progfuncs, char *error, ...) +void VARGS PR_RunError (pubprogfuncs_t *progfuncs, const char *error, ...) { va_list argptr; char string[1024]; @@ -1587,7 +1593,7 @@ static casecmprange_t casecmprange[] = pr_xstatement = st-pr_statements; \ PR_RunError (&progfuncs->funcs, "runaway loop error\n");\ PR_StackTrace(&progfuncs->funcs,false); \ - printf ("runaway loop error\n"); \ + externs->Printf ("runaway loop error\n"); \ while(pr_depth > prinst.exitdepth) \ PR_LeaveFunction(progfuncs); \ prinst.spushed = 0; \ @@ -1723,20 +1729,20 @@ static void PR_ExecuteCode (progfuncs_t *progfuncs, int s) switch(prinst.watch_type) { case ev_float: - printf("Watch point \"%s\" changed by engine from %g to %g.\n", prinst.watch_name, prinst.watch_old._float, prinst.watch_ptr->_float); + externs->Printf("Watch point \"%s\" changed by engine from %g to %g.\n", prinst.watch_name, prinst.watch_old._float, prinst.watch_ptr->_float); break; case ev_vector: - printf("Watch point \"%s\" changed by engine from '%g %g %g' to '%g %g %g'.\n", prinst.watch_name, prinst.watch_old._vector[0], prinst.watch_old._vector[1], prinst.watch_old._vector[2], prinst.watch_ptr->_vector[0], prinst.watch_ptr->_vector[1], prinst.watch_ptr->_vector[2]); + externs->Printf("Watch point \"%s\" changed by engine from '%g %g %g' to '%g %g %g'.\n", prinst.watch_name, prinst.watch_old._vector[0], prinst.watch_old._vector[1], prinst.watch_old._vector[2], prinst.watch_ptr->_vector[0], prinst.watch_ptr->_vector[1], prinst.watch_ptr->_vector[2]); break; default: - printf("Watch point \"%s\" changed by engine from %i to %i.\n", prinst.watch_name, prinst.watch_old._int, prinst.watch_ptr->_int); + externs->Printf("Watch point \"%s\" changed by engine from %i to %i.\n", prinst.watch_name, prinst.watch_old._int, prinst.watch_ptr->_int); break; case ev_entity: - printf("Watch point \"%s\" changed by engine from %i(%s) to %i(%s).\n", prinst.watch_name, prinst.watch_old._int, PR_GetEdictClassname(progfuncs, prinst.watch_old._int), prinst.watch_ptr->_int, PR_GetEdictClassname(progfuncs, prinst.watch_ptr->_int)); + externs->Printf("Watch point \"%s\" changed by engine from %i(%s) to %i(%s).\n", prinst.watch_name, prinst.watch_old._int, PR_GetEdictClassname(progfuncs, prinst.watch_old._int), prinst.watch_ptr->_int, PR_GetEdictClassname(progfuncs, prinst.watch_ptr->_int)); break; case ev_function: case ev_string: - printf("Watch point \"%s\" set by engine to %s.\n", prinst.watch_name, PR_ValueString(progfuncs, prinst.watch_type, prinst.watch_ptr, false)); + externs->Printf("Watch point \"%s\" set by engine to %s.\n", prinst.watch_name, PR_ValueString(progfuncs, prinst.watch_type, prinst.watch_ptr, false)); break; } prinst.watch_old = *prinst.watch_ptr; @@ -1802,7 +1808,7 @@ void PDECL PR_ExecuteProgram (pubprogfuncs_t *ppf, func_t fnum) { if (newprogs >= prinst.maxprogs || !pr_progstate[newprogs].globals) //can happen with hexen2... { - printf("PR_ExecuteProgram: tried branching into invalid progs (%#x)\n", fnum); + externs->Printf("PR_ExecuteProgram: tried branching into invalid progs (%#x)\n", fnum); return; } PR_SwitchProgsParms(progfuncs, newprogs); @@ -1813,9 +1819,9 @@ void PDECL PR_ExecuteProgram (pubprogfuncs_t *ppf, func_t fnum) // if (pr_global_struct->self) // ED_Print (PROG_TO_EDICT(pr_global_struct->self)); #if defined(__GNUC__) && !defined(FTE_TARGET_WEB) && !defined(NACL) - printf("PR_ExecuteProgram: NULL function from exe (address %p)\n", __builtin_return_address(0)); + externs->Printf("PR_ExecuteProgram: NULL function from exe (address %p)\n", __builtin_return_address(0)); #else - printf("PR_ExecuteProgram: NULL function from exe\n"); + externs->Printf("PR_ExecuteProgram: NULL function from exe\n"); #endif // Host_Error ("PR_ExecuteProgram: NULL function from exe"); @@ -1836,7 +1842,7 @@ void PDECL PR_ExecuteProgram (pubprogfuncs_t *ppf, func_t fnum) (*externs->globalbuiltins[i]) (&progfuncs->funcs, (struct globalvars_s *)current_progstate->globals); else { - printf ("Bad builtin call number %i (from exe)\n", -f->first_statement); + externs->Printf ("Bad builtin call number %i (from exe)\n", -f->first_statement); // PR_MoveParms(p, pr_typecurrent); PR_SwitchProgs(progfuncs, initial_progs); } @@ -1956,7 +1962,7 @@ struct qcthread_s *PDECL PR_ForkStack(pubprogfuncs_t *ppf) thread->lstackused = localsoffset - baselocalsoffset; thread->xstatement = pr_xstatement; - thread->xfunction = pr_xfunction - pr_progstate[prinst.pr_typecurrent].functions; + thread->xfunction = pr_xfunction - current_progstate->functions; thread->xprogs = prinst.pr_typecurrent; return thread; diff --git a/engine/qclib/pr_multi.c b/engine/qclib/pr_multi.c index 08d622ad8..743606e12 100644 --- a/engine/qclib/pr_multi.c +++ b/engine/qclib/pr_multi.c @@ -60,7 +60,7 @@ pbool PR_SwitchProgsParms(progfuncs_t *progfuncs, progsnum_t newpr) //from 2 to if ((unsigned)newpr >= prinst.maxprogs || !np->globals) { - printf("QCLIB: Bad prog type - %i", newpr); + externs->Printf("QCLIB: Bad prog type - %i", newpr); return false; } if ((unsigned)oldpr >= prinst.maxprogs || !op->globals) //startup? @@ -227,7 +227,7 @@ void QC_FlushProgsOffsets(progfuncs_t *progfuncs) //origionaloffs is used to track matching field offsets. fields with the same progs offset overlap //note: we probably suffer from progs with renamed system globals. -int PDECL QC_RegisterFieldVar(pubprogfuncs_t *ppf, unsigned int type, char *name, signed long engineofs, signed long progsofs) +int PDECL QC_RegisterFieldVar(pubprogfuncs_t *ppf, unsigned int type, const char *name, signed long engineofs, signed long progsofs) { progfuncs_t *progfuncs = (progfuncs_t*)ppf; // progstate_t *p; @@ -246,7 +246,7 @@ int PDECL QC_RegisterFieldVar(pubprogfuncs_t *ppf, unsigned int type, char *name { progfuncs->funcs.fieldadjust = prinst.fields_size/4; #ifdef MAPPING_DEBUG - printf("FIELD ADJUST: %i %i %i\n", progfuncs->funcs.fieldadjust, prinst.fields_size, (int)prinst.fields_size/4); + externs->Printf("FIELD ADJUST: %i %i %i\n", progfuncs->funcs.fieldadjust, prinst.fields_size, (int)prinst.fields_size/4); #endif } return 0; @@ -270,7 +270,7 @@ int PDECL QC_RegisterFieldVar(pubprogfuncs_t *ppf, unsigned int type, char *name if (prinst.field[i].type == ev_string && type == ev_float && !strcmp(name, "message")) ; //hexen2 uses floats here instead of strings. else - printf("Field type mismatch on \"%s\". %i != %i\n", name, prinst.field[i].type, type); + externs->Printf("Field type mismatch on \"%s\". %i != %i\n", name, prinst.field[i].type, type); continue; } } @@ -281,7 +281,7 @@ int PDECL QC_RegisterFieldVar(pubprogfuncs_t *ppf, unsigned int type, char *name if (prinst.field[i].progsofs == -1) prinst.field[i].progsofs = progsofs; #ifdef MAPPING_DEBUG - printf("Dupfield %s %i -> %i\n", name, prinst.field[i].progsofs,prinst.field[i].ofs); + externs->Printf("Dupfield %s %i -> %i\n", name, prinst.field[i].progsofs,prinst.field[i].ofs); #endif return prinst.field[i].ofs-progfuncs->funcs.fieldadjust; //got a match } @@ -343,7 +343,7 @@ int PDECL QC_RegisterFieldVar(pubprogfuncs_t *ppf, unsigned int type, char *name if (otherofs == (unsigned)progsofs) { #ifdef MAPPING_DEBUG - printf("union(%s) ", prinst.field[i].name); + externs->Printf("union(%s) ", prinst.field[i].name); #endif prinst.field[fnum].ofs = ofs = prinst.field[i].ofs; break; @@ -351,7 +351,7 @@ int PDECL QC_RegisterFieldVar(pubprogfuncs_t *ppf, unsigned int type, char *name if (prinst.field[i].type == ev_vector && otherofs+1 == (unsigned)progsofs) { #ifdef MAPPING_DEBUG - printf("union(%s) ", prinst.field[i].name); + externs->Printf("union(%s) ", prinst.field[i].name); #endif prinst.field[fnum].ofs = ofs = prinst.field[i].ofs+1; break; @@ -359,7 +359,7 @@ int PDECL QC_RegisterFieldVar(pubprogfuncs_t *ppf, unsigned int type, char *name if (prinst.field[i].type == ev_vector && otherofs+2 == (unsigned)progsofs) { #ifdef MAPPING_DEBUG - printf("union(%s) ", prinst.field[i].name); + externs->Printf("union(%s) ", prinst.field[i].name); #endif prinst.field[fnum].ofs = ofs = prinst.field[i].ofs+2; break; @@ -375,7 +375,7 @@ int PDECL QC_RegisterFieldVar(pubprogfuncs_t *ppf, unsigned int type, char *name Sys_Error("Allocated too many additional fields after ents were inited."); #ifdef MAPPING_DEBUG - printf("Field %s %i -> %i\n", name, prinst.field[fnum].progsofs,prinst.field[fnum].ofs); + externs->Printf("Field %s %i -> %i\n", name, prinst.field[fnum].progsofs,prinst.field[fnum].ofs); #endif if (type == ev_vector) @@ -446,7 +446,7 @@ void PDECL QC_AddSharedFieldVar(pubprogfuncs_t *ppf, int num, char *stringtable) #endif *eval = QC_RegisterFieldVar(&progfuncs->funcs, fld[i].type, gname, -1, *eval); #ifdef MAPPING_DEBUG - printf("Field=%s global %i -> %i\n", gd[num].s_name+stringtable, old, *eval); + externs->Printf("Field=%s global %i -> %i\n", gd[num].s_name+stringtable, old, *eval); #endif return; } @@ -462,7 +462,7 @@ void PDECL QC_AddSharedFieldVar(pubprogfuncs_t *ppf, int num, char *stringtable) #endif *eval = prinst.field[i].ofs-progfuncs->funcs.fieldadjust; #ifdef MAPPING_DEBUG - printf("Field global=%s %i -> %i\n", gname, old, *eval); + externs->Printf("Field global=%s %i -> %i\n", gname, old, *eval); #endif return; } @@ -524,10 +524,10 @@ void QC_AddFieldGlobal(pubprogfuncs_t *ppf, int *globdata) #endif *globdata = prinst.field[i].ofs-progfuncs->funcs.fieldadjust; #ifdef MAPPING_DEBUG - printf("Field global %i -> %i\n", old, *globdata); + externs->Printf("Field global %i -> %i\n", old, *globdata); #endif return; } } - printf("Unable to map fieldglobal\n"); + externs->Printf("Unable to map fieldglobal\n"); } diff --git a/engine/qclib/progsint.h b/engine/qclib/progsint.h index 899ce03de..fa8dc0b1b 100644 --- a/engine/qclib/progsint.h +++ b/engine/qclib/progsint.h @@ -83,6 +83,7 @@ typedef struct //FIXME: the defines hidden inside this structure are evil. typedef struct prinst_s { + //temp strings are GCed, and can be created by engine, builtins, or just by ent parsing code. tempstr_t **tempstrings; unsigned int maxtempstrings; unsigned int numtempstrings; @@ -92,15 +93,16 @@ typedef struct prinst_s unsigned int numtempstringsstack; #endif + //alloced strings are generally used to direct strings outside of the vm itself, sharing them with general engine state. char **allocedstrings; int maxallocedstrings; int numallocedstrings; struct progstate_s * progstate; #define pr_progstate prinst.progstate + unsigned int maxprogs; progsnum_t pr_typecurrent; //active index into progstate array. fixme: remove in favour of only using current_progstate - unsigned int maxprogs; struct progstate_s *current_progstate; #define current_progstate prinst.current_progstate @@ -124,6 +126,7 @@ typedef struct prinst_s //pr_exec.c + //call stack #define MAX_STACK_DEPTH 1024 //insanely high value requried for xonotic. prstack_t pr_stack[MAX_STACK_DEPTH]; #define pr_stack prinst.pr_stack @@ -131,19 +134,21 @@ typedef struct prinst_s #define pr_depth prinst.pr_depth int spushed; + //locals #define LOCALSTACK_SIZE 16384 int localstack[LOCALSTACK_SIZE]; int localstack_used; + //step-by-step debug state int debugstatement; int continuestatement; int exitdepth; pbool profiling; - prclocks_t profilingalert; - mfunction_t *pr_xfunction; + prclocks_t profilingalert; //one second, in cpu clocks + mfunction_t *pr_xfunction; //active function #define pr_xfunction prinst.pr_xfunction - int pr_xstatement; + int pr_xstatement; //active statement #define pr_xstatement prinst.pr_xstatement //pr_edict.c @@ -199,6 +204,7 @@ extern QCC_opcode_t pr_opcodes[]; // sized by initialization #define OPF_STORE 0x2 //b+=a or just b=a #define OPF_STOREPTR 0x4 //the form of c=(*b+=a) #define OPF_LOADPTR 0x8 +//FIXME: add jumps @@ -217,12 +223,12 @@ extern QCC_opcode_t pr_opcodes[]; // sized by initialization #define sv_edicts (*externs->sv_edicts) #define PR_DPrintf externs->DPrintf -#define printf externs->Printf +#define printf syntax error #define Sys_Error externs->Sys_Error int PRHunkMark(progfuncs_t *progfuncs); void PRHunkFree(progfuncs_t *progfuncs, int mark); -void *PRHunkAlloc(progfuncs_t *progfuncs, int size, char *name); +void *PRHunkAlloc(progfuncs_t *progfuncs, int size, const char *name); void *PRAddressableExtend(progfuncs_t *progfuncs, void *src, size_t srcsize, int pad); #ifdef printf @@ -237,9 +243,9 @@ void QC_StartShares(progfuncs_t *progfuncs); void PDECL QC_AddSharedVar(pubprogfuncs_t *progfuncs, int num, int type); void PDECL QC_AddSharedFieldVar(pubprogfuncs_t *progfuncs, int num, char *stringtable); void QC_AddFieldGlobal(pubprogfuncs_t *ppf, int *globdata); -int PDECL QC_RegisterFieldVar(pubprogfuncs_t *progfuncs, unsigned int type, char *name, signed long requestedpos, signed long originalofs); -pbool PDECL QC_Decompile(pubprogfuncs_t *progfuncs, char *fname); -int PDECL PR_ToggleBreakpoint(pubprogfuncs_t *progfuncs, char *filename, int linenum, int flag); +int PDECL QC_RegisterFieldVar(pubprogfuncs_t *progfuncs, unsigned int type, const char *name, signed long requestedpos, signed long originalofs); +pbool PDECL QC_Decompile(pubprogfuncs_t *progfuncs, const char *fname); +int PDECL PR_ToggleBreakpoint(pubprogfuncs_t *progfuncs, const char *filename, int linenum, int flag); void StripExtension (char *path); @@ -286,8 +292,8 @@ typedef struct edictrun_s int PDECL Comp_Begin(pubprogfuncs_t *progfuncs, int nump, char **parms); int PDECL Comp_Continue(pubprogfuncs_t *progfuncs); -pbool PDECL PR_SetWatchPoint(pubprogfuncs_t *progfuncs, char *key); -char *PDECL PR_EvaluateDebugString(pubprogfuncs_t *progfuncs, char *key); +pbool PDECL PR_SetWatchPoint(pubprogfuncs_t *progfuncs, const char *key); +char *PDECL PR_EvaluateDebugString(pubprogfuncs_t *progfuncs, const char *key); char *PDECL PR_SaveEnts(pubprogfuncs_t *progfuncs, char *mem, size_t *size, size_t maxsize, int mode); int PDECL PR_LoadEnts(pubprogfuncs_t *ppf, const char *file, void *ctx, void (PDECL *entspawned) (pubprogfuncs_t *progfuncs, struct edict_s *ed, void *ctx, const char *entstart, const char *entend), pbool(PDECL *extendedterm)(pubprogfuncs_t *progfuncs, void *ctx, const char **extline)); char *PDECL PR_SaveEnt (pubprogfuncs_t *progfuncs, char *buf, size_t *size, size_t maxsize, struct edict_s *ed); @@ -315,15 +321,19 @@ typedef struct progstate_s char *strings; union { ddefXX_t *globaldefs; - ddef16_t *globaldefs16; - ddef32_t *globaldefs32; + ddef16_t *globaldefs16; //vanilla, kk + ddef32_t *globaldefs32; //fte, qtest }; union { ddefXX_t *fielddefs; - ddef16_t *fielddefs16; - ddef32_t *fielddefs32; + ddef16_t *fielddefs16; //vanilla, kk + ddef32_t *fielddefs32; //fte, qtest }; - void *statements; +// union { + void *statements; +// dstatement16_t *statements16; //vanilla, qtest +// dstatement32_t *statements32; //fte, kk +// }; // void *global_struct; float *globals; // same as pr_global_struct int globals_size; // in bytes @@ -336,7 +346,7 @@ typedef struct progstate_s int *linenums; //debug versions only - progstructtype_t structtype; + progstructtype_t structtype; //specifies the sized struct types above. FIXME: should probably just load as 32bit or something. #ifdef QCJIT struct jitstate *jit; @@ -378,7 +388,7 @@ void PDECL PR_ExecuteProgram (pubprogfuncs_t *progfuncs, func_t fnum); int PDECL PR_LoadProgs(pubprogfuncs_t *progfncs, const char *s); int PR_ReallyLoadProgs (progfuncs_t *progfuncs, const char *filename, progstate_t *progstate, pbool complain); -void *PRHunkAlloc(progfuncs_t *progfuncs, int ammount, char *name); +void *PRHunkAlloc(progfuncs_t *progfuncs, int ammount, const char *name); void PR_Profile_f (void); @@ -440,7 +450,7 @@ extern const unsigned int type_size[]; extern unsigned short pr_crc; -void VARGS PR_RunError (pubprogfuncs_t *progfuncs, char *error, ...) LIKEPRINTF(2); +void VARGS PR_RunError (pubprogfuncs_t *progfuncs, const char *error, ...) LIKEPRINTF(2); void ED_PrintEdicts (progfuncs_t *progfuncs); void ED_PrintNum (progfuncs_t *progfuncs, int ent); @@ -452,7 +462,7 @@ pbool PR_SwitchProgsParms(progfuncs_t *progfuncs, progsnum_t newprogs); -eval_t *PDECL QC_GetEdictFieldValue(pubprogfuncs_t *progfuncs, struct edict_s *ed, char *name, etype_t type, evalc_t *cache); +eval_t *PDECL QC_GetEdictFieldValue(pubprogfuncs_t *progfuncs, struct edict_s *ed, const char *name, etype_t type, evalc_t *cache); void PDECL PR_GenerateStatementString (pubprogfuncs_t *progfuncs, int statementnum, char *out, int outlen); fdef_t *PDECL ED_FieldInfo (pubprogfuncs_t *progfuncs, unsigned int *count); char *PDECL PR_UglyValueString (pubprogfuncs_t *progfuncs, etype_t type, eval_t *val); @@ -487,10 +497,10 @@ void PDECL PR_AbortStack (pubprogfuncs_t *progfuncs); pbool PDECL PR_GetBuiltinCallInfo (pubprogfuncs_t *ppf, int *builtinnum, char *function, size_t sizeoffunction); eval_t *PDECL PR_FindGlobal(pubprogfuncs_t *prfuncs, const char *globname, progsnum_t pnum, etype_t *type); -ddef16_t *ED_FindTypeGlobalFromProgs16 (progfuncs_t *progfuncs, const char *name, progsnum_t prnum, int type); -ddef32_t *ED_FindTypeGlobalFromProgs32 (progfuncs_t *progfuncs, const char *name, progsnum_t prnum, int type); -ddef16_t *ED_FindGlobalFromProgs16 (progfuncs_t *progfuncs, const char *name, progsnum_t prnum); -ddef32_t *ED_FindGlobalFromProgs32 (progfuncs_t *progfuncs, const char *name, progsnum_t prnum); +ddef16_t *ED_FindTypeGlobalFromProgs16 (progfuncs_t *progfuncs, progstate_t *ps, const char *name, int type); +ddef32_t *ED_FindTypeGlobalFromProgs32 (progfuncs_t *progfuncs, progstate_t *ps, const char *name, int type); +ddef16_t *ED_FindGlobalFromProgs16 (progfuncs_t *progfuncs, progstate_t *ps, const char *name); +ddef32_t *ED_FindGlobalFromProgs32 (progfuncs_t *progfuncs, progstate_t *ps, const char *name); fdef_t *ED_FindField (progfuncs_t *progfuncs, const char *name); fdef_t *ED_ClassFieldAtOfs (progfuncs_t *progfuncs, unsigned int ofs, const char *classname); fdef_t *ED_FieldAtOfs (progfuncs_t *progfuncs, unsigned int ofs); @@ -504,8 +514,8 @@ void PRAddressableFlush(progfuncs_t *progfuncs, size_t totalammount); void QC_FlushProgsOffsets(progfuncs_t *progfuncs); ddef16_t *ED_GlobalAtOfs16 (progfuncs_t *progfuncs, int ofs); -ddef16_t *ED_FindGlobal16 (progfuncs_t *progfuncs, char *name); -ddef32_t *ED_FindGlobal32 (progfuncs_t *progfuncs, char *name); +ddef16_t *ED_FindGlobal16 (progfuncs_t *progfuncs, const char *name); +ddef32_t *ED_FindGlobal32 (progfuncs_t *progfuncs, const char *name); ddef32_t *ED_GlobalAtOfs32 (progfuncs_t *progfuncs, unsigned int ofs); string_t PDECL PR_StringToProgs (pubprogfuncs_t *inst, const char *str); diff --git a/engine/qclib/progslib.h b/engine/qclib/progslib.h index 1ff7ca8b3..5c4a0f171 100644 --- a/engine/qclib/progslib.h +++ b/engine/qclib/progslib.h @@ -60,13 +60,13 @@ enum ereftype_e //used by progs engine. All nulls is reset. typedef struct { - char *varname; + const char *varname; struct fdef_s *ofs32; int spare[2]; } evalc_t; #define sizeofevalc sizeof(evalc_t) -typedef enum {ev_void, ev_string, ev_float, ev_vector, ev_entity, ev_field, ev_function, ev_pointer, ev_integer, ev_variant, ev_struct, ev_union, ev_accessor, ev_enum} etype_t; +typedef enum {ev_void, ev_string, ev_float, ev_vector, ev_entity, ev_field, ev_function, ev_pointer, ev_integer, ev_variant, ev_struct, ev_union, ev_accessor, ev_enum, ev_boolean} etype_t; enum { DEBUG_TRACE_OFF, //debugging should be off. DEBUG_TRACE_INTO, //debug into functions @@ -81,7 +81,7 @@ typedef struct fdef_s unsigned int type; //if DEF_SAVEGLOBAL bit is set then the variable needs to be saved in savegames int ofs; //runtime offset. add fieldadj to get the real array index. unsigned int progsofs; //used at loading time, so maching field offsets (unions/members) are positioned at the same runtime offset. - char * name; //proper name for the field. + const char * name; //proper name for the field. } fdef_t; //the number of pointers to variables (as opposed to functions - those are fine) in these structures is excessive. @@ -99,7 +99,7 @@ struct pubprogfuncs_s struct globalvars_s *(PDECL *globals) (pubprogfuncs_t *prinst, progsnum_t num); //get the globals of a progs struct entvars_s *(PDECL *entvars) (pubprogfuncs_t *prinst, struct edict_s *ent); //return a pointer to the entvars of an ent. can be achieved via the edict_t structure instead, so obsolete. - void (VARGS *RunError) (pubprogfuncs_t *prinst, char *msg, ...) LIKEPRINTF(2); //builtins call this to say there was a problem + void (VARGS *RunError) (pubprogfuncs_t *prinst, const char *msg, ...) LIKEPRINTF(2); //builtins call this to say there was a problem void (PDECL *PrintEdict) (pubprogfuncs_t *prinst, struct edict_s *ed); //get a listing of all vars on an edict (sent back via 'print') struct edict_s *(PDECL *EntAlloc) (pubprogfuncs_t *prinst, pbool object, size_t extrasize); @@ -134,26 +134,26 @@ struct pubprogfuncs_s char *(PDECL *AddString) (pubprogfuncs_t *prinst, const char *val, int minlength, pbool demarkup); //dump a string into the progs memory (for setting globals and whatnot) void *(PDECL *Tempmem) (pubprogfuncs_t *prinst, int ammount, char *whatfor); //grab some mem for as long as the progs stays loaded - union eval_s *(PDECL *GetEdictFieldValue)(pubprogfuncs_t *prinst, struct edict_s *ent, char *name, etype_t type, evalc_t *s); //get an entityvar (cache it) and return the possible values + union eval_s *(PDECL *GetEdictFieldValue)(pubprogfuncs_t *prinst, struct edict_s *ent, const char *name, etype_t type, evalc_t *s); //get an entityvar (cache it) and return the possible values struct edict_s *(PDECL *ProgsToEdict) (pubprogfuncs_t *prinst, int progs); //edicts are stored as ints and need to be adjusted int (PDECL *EdictToProgs) (pubprogfuncs_t *prinst, struct edict_s *ed); //edicts are stored as ints and need to be adjusted - char *(PDECL *EvaluateDebugString) (pubprogfuncs_t *prinst, char *key); //evaluate a string and return it's value (according to current progs) (expands edict vars) + char *(PDECL *EvaluateDebugString) (pubprogfuncs_t *prinst, const char *key); //evaluate a string and return it's value (according to current progs) (expands edict vars) int debug_trace; //start calling the editor for each line executed void (PDECL *StackTrace) (pubprogfuncs_t *prinst, int showlocals); - int (PDECL *ToggleBreak) (pubprogfuncs_t *prinst, char *filename, int linenum, int mode); + int (PDECL *ToggleBreak) (pubprogfuncs_t *prinst, const char *filename, int linenum, int mode); int numprogs; struct progexterns_s *parms; //these are the initial parms, they may be changed - pbool (PDECL *Decompile) (pubprogfuncs_t *prinst, char *fname); + pbool (PDECL *Decompile) (pubprogfuncs_t *prinst, const char *fname); int callargc; //number of args of built-in call - void (PDECL *RegisterBuiltin) (pubprogfuncs_t *prinst, char *, builtin_t); + void (PDECL *RegisterBuiltin) (pubprogfuncs_t *prinst, const char *, builtin_t); char *stringtable; //qc strings are all relative. add to a qc string. this is required for support of frikqcc progs that strip string immediates. int stringtablesize; @@ -166,7 +166,7 @@ struct pubprogfuncs_s pbool (PDECL *GetBuiltinCallInfo) (pubprogfuncs_t *prinst, int *builtinnum, char *function, size_t sizeoffunction); //call to query the qc's name+index for the builtin - int (PDECL *RegisterFieldVar) (pubprogfuncs_t *prinst, unsigned int type, char *name, signed long requestedpos, signed long originalofs); + int (PDECL *RegisterFieldVar) (pubprogfuncs_t *prinst, unsigned int type, const char *name, signed long requestedpos, signed long originalofs); char *tempstringbase; //for engine's use. Store your base tempstring pointer here. int tempstringnum; //for engine's use. @@ -176,7 +176,7 @@ struct pubprogfuncs_s string_t (PDECL *StringToProgs) (pubprogfuncs_t *prinst, const char *str); //commonly makes a semi-permanent mapping from some table to the string value. mapping can be removed via RemoveProgsString const char *(ASMCALL *StringToNative) (pubprogfuncs_t *prinst, string_t str); - int (PDECL *QueryField) (pubprogfuncs_t *prinst, unsigned int fieldoffset, etype_t *type, char **name, evalc_t *fieldcache); //find info on a field definition at an offset + int (PDECL *QueryField) (pubprogfuncs_t *prinst, unsigned int fieldoffset, etype_t *type, char const**name, evalc_t *fieldcache); //find info on a field definition at an offset void (PDECL *EntClear) (pubprogfuncs_t *progfuncs, struct edict_s *e); void (PDECL *FindPrefixGlobals) (pubprogfuncs_t *progfuncs, int prnum, char *prefix, void (PDECL *found) (pubprogfuncs_t *progfuncs, char *name, union eval_s *val, etype_t type, void *ctx), void *ctx); //calls the callback for each named global found @@ -185,7 +185,7 @@ struct pubprogfuncs_s string_t (PDECL *AllocTempString) (pubprogfuncs_t *prinst, char **str, unsigned int len); void (PDECL *AddressableFree) (pubprogfuncs_t *progfuncs, void *mem); /*frees a block of addressable memory*/ - pbool (PDECL *SetWatchPoint) (pubprogfuncs_t *prinst, char *key); + pbool (PDECL *SetWatchPoint) (pubprogfuncs_t *prinst, const char *key); void (PDECL *AddSharedVar) (pubprogfuncs_t *progfuncs, int start, int size); void (PDECL *AddSharedFieldVar) (pubprogfuncs_t *progfuncs, int num, char *relstringtable); diff --git a/engine/qclib/qcc.h b/engine/qclib/qcc.h index bef1d002f..34f57cf78 100644 --- a/engine/qclib/qcc.h +++ b/engine/qclib/qcc.h @@ -335,7 +335,8 @@ struct QCC_typeparam_s { struct QCC_type_s *type; QCC_sref_t defltvalue; - pbool optional; + pbool optional:1; //argument may safely be omitted, for builtin functions. for qc functions use the defltvalue instead. + pbool isvirtual:1; //const, with implicit initialisation only. valid for structs unsigned char out; //0=in,1==inout,2=out unsigned int ofs; unsigned int arraysize; @@ -394,7 +395,6 @@ typedef struct QCC_def_s struct QCC_function_s *scope; // function the var was defined in, or NULL struct QCC_def_s *deftail; // arrays and structs create multiple globaldef objects providing different types at the different parts of the single object (struct), or alternative names (vectors). this allows us to correctly set the const type based upon how its initialised. struct QCC_def_s *generatedfor; - int initialized; // 1 when a declaration included "= immediate". 2 = extern. int constant; // 1 says we can use the value over and over again. 2 is used on fields, for some reason. struct QCC_def_s *symbolheader; //this is the original symbol within which the def is stored. @@ -429,6 +429,8 @@ typedef struct QCC_def_s pbool weak:1; //ignore any initialiser value (only permitted on functions) pbool accumulate:1; //don't finalise the function's statements. pbool nofold:1; + pbool initialized:1; //true when a declaration included "= immediate". + pbool isextern:1; //fteqw-specific lump entry int fromstatement; //statement that it is valid from. temp_t *temp; @@ -454,6 +456,7 @@ typedef struct REF_FIELD, //(entity.field) - reading is a single load, writing requires address+storep REF_STRING, //"hello"[1]=='e' - special opcodes, or str2chr builtin, or something REF_NONVIRTUAL, //(global.ofs) - identical to global except for function calls, where index can be used to provide the 'newself' for the call. + REF_THISCALL, //(global.ofs) - identical to global except for function calls, where index is used as the first argument. REF_ACCESSOR //buf_create()[5] } type; @@ -546,6 +549,7 @@ char *QCC_PR_GetDefinesList(void); //============================================================================ extern pbool pr_dumpasm; +extern pbool preprocessonly; //extern QCC_def_t **pr_global_defs; // to find def for a global variable @@ -701,6 +705,7 @@ QCC_type_t *QCC_PR_ParseFunctionTypeReacc (int newtype, QCC_type_t *returntype); QCC_type_t *QCC_PR_GenFunctionType (QCC_type_t *rettype, struct QCC_typeparam_s *args, int numargs); char *QCC_PR_ParseName (void); CompilerConstant_t *QCC_PR_DefineName(char *name); +struct QCC_typeparam_s *QCC_PR_FindStructMember(QCC_type_t *t, const char *membername, unsigned int *out_ofs); const char *QCC_VarAtOffset(QCC_sref_t ref); @@ -1038,6 +1043,8 @@ void QCC_PR_ParseInitializerDef(QCC_def_t *def, unsigned int flags); void QCC_PR_FinaliseFunctions(void); +pbool QCC_main (int argc, char **argv); //as part of the quake engine +void QCC_ContinueCompile(void); void PostCompile(void); pbool PreCompile(void); void QCC_Cleanup(void); diff --git a/engine/qclib/qcc_cmdlib.c b/engine/qclib/qcc_cmdlib.c index 2eeffce66..9096244ff 100644 --- a/engine/qclib/qcc_cmdlib.c +++ b/engine/qclib/qcc_cmdlib.c @@ -66,7 +66,7 @@ float (*PRBigFloat) (float l); float (*PRLittleFloat) (float l); -short QCC_SwapShort (short l) +static short QCC_SwapShort (short l) { qbyte b1,b2; @@ -76,13 +76,13 @@ short QCC_SwapShort (short l) return (b1<<8) + b2; } -short QCC_Short (short l) +static short QCC_Short (short l) { return l; } -int QCC_SwapLong (int l) +static int QCC_SwapLong (int l) { qbyte b1,b2,b3,b4; @@ -94,13 +94,13 @@ int QCC_SwapLong (int l) return ((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4; } -int QCC_Long (int l) +static int QCC_Long (int l) { return l; } -float QCC_SwapFloat (float l) +static float QCC_SwapFloat (float l) { union {qbyte b[4]; float f;} in, out; @@ -113,7 +113,7 @@ float QCC_SwapFloat (float l) return out.f; } -float QCC_Float (float l) +static float QCC_Float (float l) { return l; } @@ -566,7 +566,7 @@ void VARGS QCC_Error (int errortype, const char *error, ...) QC_vsnprintf (msg,sizeof(msg)-1, error,argptr); va_end (argptr); - printf ("\n************ ERROR ************\n%s\n", msg); + externs->Printf ("\n************ ERROR ************\n%s\n", msg); editbadfile(s_filen, pr_source_line); @@ -591,7 +591,7 @@ Checks for the given parameter in the program's command line arguments Returns the argument number (1 to argc-1) or 0 if not present ================= */ -int QCC_CheckParm (char *check) +int QCC_CheckParm (const char *check) { int i; @@ -604,7 +604,7 @@ int QCC_CheckParm (char *check) return 0; } -const char *QCC_ReadParm (char *check) +const char *QCC_ReadParm (const char *check) { int i; @@ -793,7 +793,7 @@ void ExtractFileExtension (char *path, char *dest) ParseNum / ParseHex ============== */ -long ParseHex (char *hex) +static long ParseHex (char *hex) { char *str; long num; @@ -875,7 +875,7 @@ int SafeOpenWrite (char *filename, int maxsize) return -1; } -void ResizeBuf(int hand, int newsize) +static void ResizeBuf(int hand, int newsize) { char *nb; diff --git a/engine/qclib/qcc_pr_comp.c b/engine/qclib/qcc_pr_comp.c index 3b92701ff..c8ad717e7 100644 --- a/engine/qclib/qcc_pr_comp.c +++ b/engine/qclib/qcc_pr_comp.c @@ -751,7 +751,7 @@ QCC_opcode_t pr_opcodes[] = }; -pbool OpAssignsToC(unsigned int op) +static pbool OpAssignsToC(unsigned int op) { // calls, switches and cases DON'T if(pr_opcodes[op].type_c == &type_void) @@ -778,7 +778,7 @@ pbool OpAssignsToC(unsigned int op) return false; return true; } -pbool OpAssignsToB(unsigned int op) +static pbool OpAssignsToB(unsigned int op) { if(op >= OP_BITSETSTORE_F && op <= OP_BITCLRSTOREP_F) return true; @@ -793,7 +793,7 @@ pbool OpAssignsToB(unsigned int op) return false; } #define OpAssignsToA(op) false -int OpAssignsCount(unsigned int op) +static int OpAssignsCount(unsigned int op) { switch(op) { @@ -1059,8 +1059,8 @@ QCC_opcode_t *opcodes_none[] = }; //these evaluate as top first. -QCC_opcode_t *opcodeprioritized[13+1][128]; -int +static QCC_opcode_t *opcodeprioritized[13+1][128]; +static int #ifdef _MSC_VER __cdecl #endif @@ -1137,7 +1137,7 @@ void QCC_PrioritiseOpcodes(void) qsort (&opcodeprioritized[j][0], pcount[j], sizeof(opcodeprioritized[j][0]), sort_opcodenames); } -pbool QCC_OPCodeValid(QCC_opcode_t *op) +static pbool QCC_OPCodeValid(QCC_opcode_t *op) { int num; num = op - pr_opcodes; @@ -1400,7 +1400,7 @@ pbool QCC_StatementIsAJump(int stnum, int notifdest); //=========================================================================== //typically used for debugging. Also used to determine function names for intrinsics. -const char *QCC_GetSRefName(QCC_sref_t ref) +static const char *QCC_GetSRefName(QCC_sref_t ref) { if (ref.sym && ref.sym->name/* && !ref.ofs*/) { @@ -1413,13 +1413,13 @@ const char *QCC_GetSRefName(QCC_sref_t ref) //NULL is defined as the immediate 0 or 0i (aka __NULL__). //named constants that merely have the value 0 are NOT meant to count. -pbool QCC_SRef_IsNull(QCC_sref_t ref) +static pbool QCC_SRef_IsNull(QCC_sref_t ref) { return (ref.cast->type == ev_integer || ref.cast->type == ev_float) && ref.sym && ref.sym->initialized && ref.sym->constant && !ref.sym->symboldata[ref.ofs]._int; } //retrieves the data associated with the reference if its constant and thus readable at compile time. -const QCC_eval_t *QCC_SRef_EvalConst(QCC_sref_t ref) +static const QCC_eval_t *QCC_SRef_EvalConst(QCC_sref_t ref) { if (ref.sym && ref.sym->initialized && ref.sym->constant) { @@ -1429,7 +1429,7 @@ const QCC_eval_t *QCC_SRef_EvalConst(QCC_sref_t ref) return NULL; } -const char *QCC_GetRefName(QCC_ref_t *ref, char *buffer, size_t buffersize) +static const char *QCC_GetRefName(QCC_ref_t *ref, char *buffer, size_t buffersize) { switch(ref->type) { @@ -1495,7 +1495,7 @@ static int QCC_ShouldConvert(QCC_type_t *from, etype_t wanted) /*impossible*/ return -1; } -QCC_sref_t QCC_SupplyConversionForAssignment(QCC_ref_t *to, QCC_sref_t from, QCC_type_t *wanted, pbool fatal) +static QCC_sref_t QCC_SupplyConversionForAssignment(QCC_ref_t *to, QCC_sref_t from, QCC_type_t *wanted, pbool fatal) { int o; QCC_sref_t rhs; @@ -1540,7 +1540,7 @@ QCC_sref_t QCC_SupplyConversionForAssignment(QCC_ref_t *to, QCC_sref_t from, QCC rhs = nullsref; return QCC_PR_Statement(&pr_opcodes[o], from, rhs, NULL); //conversion return value } -QCC_sref_t QCC_SupplyConversion(QCC_sref_t var, etype_t wanted, pbool fatal) +static QCC_sref_t QCC_SupplyConversion(QCC_sref_t var, etype_t wanted, pbool fatal) { extern char *basictypenames[]; int o; @@ -4260,7 +4260,7 @@ PR_ParseImmediate Looks for a preexisting constant ============ */ -QCC_sref_t QCC_PR_ParseImmediate (void) +static QCC_sref_t QCC_PR_ParseImmediate (void) { QCC_sref_t cn; @@ -4305,7 +4305,7 @@ QCC_sref_t QCC_PR_ParseImmediate (void) } } -QCC_ref_t *QCC_PR_GenerateAddressOf(QCC_ref_t *retbuf, QCC_ref_t *operand) +static QCC_ref_t *QCC_PR_GenerateAddressOf(QCC_ref_t *retbuf, QCC_ref_t *operand) { // QCC_def_t *e2; if (operand->type == REF_FIELD) @@ -4361,7 +4361,7 @@ QCC_ref_t *QCC_PR_GenerateAddressOf(QCC_ref_t *retbuf, QCC_ref_t *operand) } -void QCC_PrecacheSound (const char *n, int ch) +static void QCC_PrecacheSound (const char *n, int ch) { int i; @@ -4391,7 +4391,7 @@ void QCC_PrecacheSound (const char *n, int ch) numsounds++; } -void QCC_PrecacheModel (const char *n, int ch) +static void QCC_PrecacheModel (const char *n, int ch) { int i; @@ -4424,7 +4424,7 @@ void QCC_PrecacheModel (const char *n, int ch) nummodels++; } -void QCC_SetModel (const char *n) +static void QCC_SetModel (const char *n) { int i; @@ -4448,7 +4448,7 @@ void QCC_SetModel (const char *n) precache_model[i].fileline = pr_source_line; nummodels++; } -void QCC_SoundUsed (const char *n) +static void QCC_SoundUsed (const char *n) { int i; @@ -4473,7 +4473,7 @@ void QCC_SoundUsed (const char *n) numsounds++; } -void QCC_PrecacheTexture (const char *n, int ch) +static void QCC_PrecacheTexture (const char *n, int ch) { int i; @@ -4495,7 +4495,7 @@ void QCC_PrecacheTexture (const char *n, int ch) numtextures++; } -void QCC_PrecacheFile (const char *n, int ch) +static void QCC_PrecacheFile (const char *n, int ch) { int i; @@ -4518,7 +4518,7 @@ void QCC_PrecacheFile (const char *n, int ch) } -void QCC_VerifyFormatString (const char *funcname, QCC_ref_t **arglist, unsigned int argcount) +static void QCC_VerifyFormatString (const char *funcname, QCC_ref_t **arglist, unsigned int argcount) { const char *s = "%s"; int firstarg = 1; @@ -4526,6 +4526,7 @@ void QCC_VerifyFormatString (const char *funcname, QCC_ref_t **arglist, unsigned char *err; int width, thisarg, arg; char formatbuf[16]; + char temp[256]; int argpos = firstarg, argn_last = firstarg; int isfloat; const QCC_eval_t *formatstring = QCC_SRef_EvalConst(arglist[0]->base); @@ -4736,9 +4737,7 @@ nolength: break; default: { - char typename[256]; - TypeName(ARGCTYPE(thisarg), typename, sizeof(typename)); - QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: %s requires float at arg %i (got %s)", funcname, formatbuf, thisarg+1, typename); + QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: %s requires float at arg %i (got %s)", funcname, formatbuf, thisarg+1, TypeName(ARGCTYPE(thisarg), temp, sizeof(temp))); } break; } @@ -4753,7 +4752,7 @@ nolength: case ev_variant: break; default: - QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: %s requires pointer at arg %i", funcname, formatbuf, thisarg+1); + QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: %s requires pointer at arg %i (got %s)", funcname, formatbuf, thisarg+1, TypeName(ARGCTYPE(thisarg), temp, sizeof(temp))); break; } } @@ -4769,7 +4768,7 @@ nolength: break; //fallthrough default: - QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: %s requires int at arg %i", funcname, formatbuf, thisarg+1); + QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: %s requires int at arg %i (got %s)", funcname, formatbuf, thisarg+1, TypeName(ARGCTYPE(thisarg), temp, sizeof(temp))); break; } } @@ -4784,12 +4783,12 @@ nolength: case ev_variant: break; default: - QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: %s requires vector at arg %i", funcname, formatbuf, thisarg+1); + QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: %s requires vector at arg %i (got %s)", funcname, formatbuf, thisarg+1, TypeName(ARGCTYPE(thisarg), temp, sizeof(temp))); break; } } else - QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: %s requires intvector at arg %i", funcname, formatbuf, thisarg+1); + QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: %s requires intvector at arg %i (got %s)", funcname, formatbuf, thisarg+1, TypeName(ARGCTYPE(thisarg), temp, sizeof(temp))); break; case 's': case 'S': @@ -4799,7 +4798,7 @@ nolength: case ev_variant: break; default: - QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: %s requires string at arg %i", funcname, formatbuf, thisarg+1); + QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: %s requires string at arg %i", funcname, formatbuf, thisarg+1, TypeName(ARGCTYPE(thisarg), temp, sizeof(temp))); break; } break; @@ -5813,7 +5812,7 @@ QCC_sref_t QCC_PR_GenerateFunctionCall1 (QCC_sref_t newself, QCC_sref_t func, QC PR_ParseFunctionCall ============ */ -QCC_sref_t QCC_PR_ParseFunctionCall (QCC_ref_t *funcref) //warning, the func could have no name set if it's a field call. +static QCC_sref_t QCC_PR_ParseFunctionCall (QCC_ref_t *funcref) //warning, the func could have no name set if it's a field call. { QCC_sref_t newself, func; QCC_sref_t e, d, out; @@ -6571,7 +6570,7 @@ QCC_sref_t QCC_MakeIntConst(int value) } //immediates with no overlapping. this means aliases can be set up to mark them as strings/fields/functions and the engine can safely remap them as needed -QCC_sref_t QCC_MakeUniqueConst(QCC_type_t *type, void *data) +static QCC_sref_t QCC_MakeUniqueConst(QCC_type_t *type, void *data) { QCC_def_t *cn; @@ -6810,7 +6809,7 @@ QCC_type_t **basictypes[] = NULL, //type_union }; -QCC_def_t *QCC_MemberInParentClass(char *name, QCC_type_t *clas) +/*static QCC_def_t *QCC_MemberInParentClass(char *name, QCC_type_t *clas) { //if a member exists, return the member field (rather than mapped-to field) QCC_def_t *def; unsigned int p; @@ -6839,9 +6838,9 @@ QCC_def_t *QCC_MemberInParentClass(char *name, QCC_type_t *clas) } return QCC_MemberInParentClass(name, clas->parentclass); -} +}*/ -void QCC_PR_EmitClassFunctionTable(QCC_type_t *clas, QCC_type_t *childclas, QCC_sref_t ed) +static void QCC_PR_EmitClassFunctionTable(QCC_type_t *clas, QCC_type_t *childclas, QCC_sref_t ed) { //go through clas, do the virtual thing only if the child class does not override. char membername[2048]; @@ -7175,6 +7174,9 @@ struct QCC_typeparam_s *QCC_PR_FindStructMember(QCC_type_t *t, const char *membe QCC_PR_ParseError(0, "multiple members found matching %s.%s", t->name, membername); return NULL; } + if (!r && t->parentclass) //chain through the parent struct + return QCC_PR_FindStructMember(t->parentclass, membername, out_ofs); + return r; } @@ -7447,7 +7449,7 @@ fieldarrayindex: } else if (((t->type == ev_pointer && !arraysize) || (t->type == ev_field && (t->aux_type->type == ev_struct || t->aux_type->type == ev_union)) || t->type == ev_struct || t->type == ev_union) && (QCC_PR_CheckToken(".") || QCC_PR_CheckToken("->"))) { - const char *tname; + const char *tname, *mname; unsigned int ofs; pbool fld = t->type == ev_field; struct QCC_typeparam_s *p; @@ -7472,9 +7474,36 @@ fieldarrayindex: else QCC_PR_ParseError(0, "indirection in something that is not a struct or union", tname); - p = QCC_PR_FindStructMember(t, QCC_PR_ParseName(), &ofs); + mname = QCC_PR_ParseName(); + p = QCC_PR_FindStructMember(t, mname, &ofs); if (!p) - QCC_PR_ParseError(0, "%s is not a member of %s", pr_token, tname); + { //check for static or non-virtual-function + QCC_type_t *c; + char membername[2048]; + for (c = t; c; c = c->parentclass) + { + QC_snprintfz(membername, sizeof(membername), "%s::%s", c->name, mname); + tmp = QCC_PR_GetSRef(NULL, membername, NULL, false, 0, false); + if (tmp.cast) + { //static or non-virtual + QCC_sref_t base = nullsref; //for static + + //for non-virtual types, we need to figure out what the new 'this' should be + /*if (r->type == REF_ARRAYHEAD) + { + r->type = REF_ARRAY; + base = QCC_RefToDef(r, true); + r->type = REF_ARRAYHEAD; + } + else + base = QCC_RefToDef(r, true);*/ + + r = QCC_PR_BuildRef(retbuf, base.cast?REF_THISCALL:REF_GLOBAL, tmp, base, tmp.cast, tmp.sym->constant); + return QCC_PR_ParseRefArrayPointer(retbuf, r, allowarrayassign, makearraypointers); + } + } + QCC_PR_ParseError(0, "%s is not a member of %s", mname, tname); + } if (!ofs && idx.cast) ; else if (QCC_OPCodeValid(&pr_opcodes[OP_ADD_I])) @@ -7749,6 +7778,13 @@ QCC_ref_t *QCC_PR_ParseRefValue (QCC_ref_t *refbuf, QCC_type_t *assumeclass, pbo if (p) continue; } + if (!d.cast && t->type == ev_struct) + { + //use static functions in preference to virtual functions. kinda needed so you can use super::func... + QC_snprintfz(membername, sizeof(membername), "%s::%s", p->name, name); + d = QCC_PR_GetSRef (NULL, membername, pr_scope, false, 0, false); + p = p->parentclass; + } break; } if (!d.cast) @@ -7970,7 +8006,7 @@ QCC_sref_t QCC_PR_GenerateLogicalNot(QCC_sref_t e, const char *errormessage) } //doesn't consider parents -QCC_sref_t QCC_TryEvaluateCast(QCC_sref_t src, QCC_type_t *cast, pbool implicit) +static QCC_sref_t QCC_TryEvaluateCast(QCC_sref_t src, QCC_type_t *cast, pbool implicit) { QCC_type_t *tmp; int totype; @@ -8035,6 +8071,29 @@ QCC_sref_t QCC_TryEvaluateCast(QCC_sref_t src, QCC_type_t *cast, pbool implicit) } src.cast = cast; } + else if (totype == ev_pointer && src.cast->type == ev_pointer) + { + if (implicit) + { //this is safe if the source inherits from the dest type + //but we should warn if the other way around + QCC_type_t *t = src.cast->aux_type; + while(t) + { + if (!typecmp_lax(t, cast->aux_type)) + break; + t = t->parentclass; + } + if (!t) + { + char typea[256]; + char typeb[256]; + TypeName(src.cast, typea, sizeof(typea)); + TypeName(cast, typeb, sizeof(typeb)); + QCC_PR_ParseWarning(0, "Implicit cast from %s to %s", typea, typeb); + } + } + src.cast = cast; + } /*variants can be cast from/to anything without warning, even implicitly. FIXME: size issues*/ else if (totype == ev_variant || src.cast->type == ev_variant || (totype == ev_field && totype == src.cast->type && (tmp->aux_type->type == ev_variant || src.cast->aux_type->type == ev_variant))) @@ -8050,7 +8109,7 @@ QCC_sref_t QCC_TryEvaluateCast(QCC_sref_t src, QCC_type_t *cast, pbool implicit) QCC_PR_ParseWarning(WARN_IMPLICITVARIANTCAST, "Implicit cast from %s to %s", typea, typeb); } } - /*these casts are fine when explicit*/ + /*these casts are acceptable but probably an error (so warn when implicit)*/ else if ( /*you may explicitly cast between pointers and ints (strings count as pointers - WARNING: some strings may not be expressable as pointers)*/ ((totype == ev_pointer || totype == ev_string || totype == ev_integer) && (src.cast->type == ev_pointer || src.cast->type == ev_string || src.cast->type == ev_integer)) @@ -8142,7 +8201,7 @@ QCC_sref_t QCC_EvaluateCast(QCC_sref_t src, QCC_type_t *cast, pbool implicit) PR_Term ============ */ -QCC_ref_t *QCC_PR_RefTerm (QCC_ref_t *retbuf, unsigned int exprflags) +static QCC_ref_t *QCC_PR_RefTerm (QCC_ref_t *retbuf, unsigned int exprflags) { QCC_ref_t *r; QCC_sref_t e, e2; @@ -8363,7 +8422,7 @@ QCC_ref_t *QCC_PR_RefTerm (QCC_ref_t *retbuf, unsigned int exprflags) } -int QCC_canConv(QCC_sref_t from, etype_t to) +static int QCC_canConv(QCC_sref_t from, etype_t to) { while(from.cast->type == ev_accessor) from.cast = from.cast->parentclass; @@ -8475,7 +8534,7 @@ void QCC_StoreToOffset(int dest, int source, QCC_type_t *type) break; } }*/ -void QCC_StoreToSRef(QCC_sref_t dest, QCC_sref_t source, QCC_type_t *type, pbool preservesource, pbool preservedest) +static void QCC_StoreToSRef(QCC_sref_t dest, QCC_sref_t source, QCC_type_t *type, pbool preservesource, pbool preservedest) { unsigned int i; int flags = 0; @@ -8533,7 +8592,7 @@ void QCC_StoreToSRef(QCC_sref_t dest, QCC_sref_t source, QCC_type_t *type, pbool } } //if readable, returns source (or dest if the store was folded), otherwise returns NULL -QCC_sref_t QCC_CollapseStore(QCC_sref_t dest, QCC_sref_t source, QCC_type_t *type, pbool readable, pbool preservedest) +static QCC_sref_t QCC_CollapseStore(QCC_sref_t dest, QCC_sref_t source, QCC_type_t *type, pbool readable, pbool preservedest) { if (opt_assignments && OpAssignsToC(statements[numstatements-1].op) && source.sym == statements[numstatements-1].c.sym && source.ofs == statements[numstatements-1].c.ofs) { @@ -8558,7 +8617,7 @@ QCC_sref_t QCC_CollapseStore(QCC_sref_t dest, QCC_sref_t source, QCC_type_t *typ return source; return nullsref; } -void QCC_StoreToPointer(QCC_sref_t dest, QCC_sref_t source, QCC_type_t *type) +static void QCC_StoreToPointer(QCC_sref_t dest, QCC_sref_t source, QCC_type_t *type) { if (type->type == ev_variant) type = source.cast; @@ -8640,7 +8699,7 @@ void QCC_StoreToPointer(QCC_sref_t dest, QCC_sref_t source, QCC_type_t *type) break; } } -QCC_sref_t QCC_LoadFromPointer(QCC_sref_t source, QCC_sref_t idx, QCC_type_t *type) +static QCC_sref_t QCC_LoadFromPointer(QCC_sref_t source, QCC_sref_t idx, QCC_type_t *type) { QCC_sref_t ret; int op; @@ -8695,7 +8754,7 @@ QCC_sref_t QCC_LoadFromPointer(QCC_sref_t source, QCC_sref_t idx, QCC_type_t *ty ret.cast = type; return ret; } -void QCC_StoreToArray(QCC_sref_t base, QCC_sref_t index, QCC_sref_t source, QCC_type_t *t) +static void QCC_StoreToArray(QCC_sref_t base, QCC_sref_t index, QCC_sref_t source, QCC_type_t *t) { /*if its assigned to, generate a functioncall to do the store*/ QCC_sref_t funcretr; @@ -8992,7 +9051,7 @@ QCC_sref_t QCC_LoadFromArray(QCC_sref_t base, QCC_sref_t index, QCC_type_t *t, p funcretr = QCC_PR_GetSRef(ftype, qcva("ArrayGet*%s", QCC_GetSRefName(base)), base.sym->scope, true, 0, GDF_CONST|(base.sym->scope?GDF_STATIC:0)); funcretr.sym->generatedfor = base.sym; if (!funcretr.sym->constant) - printf("not constant?\n"); + externs->Printf("not constant?\n"); } if (preserve) @@ -9093,6 +9152,7 @@ QCC_sref_t QCC_RefToDef(QCC_ref_t *ref, pbool freetemps) switch(ref->type) { + case REF_THISCALL: case REF_NONVIRTUAL: if (freetemps) QCC_FreeTemp(ref->index); @@ -9445,7 +9505,7 @@ void QCC_PR_DiscardRef(QCC_ref_t *ref) } } -QCC_opcode_t *QCC_PR_ChooseOpcode(QCC_sref_t lhs, QCC_sref_t rhs, QCC_opcode_t **priority) +static QCC_opcode_t *QCC_PR_ChooseOpcode(QCC_sref_t lhs, QCC_sref_t rhs, QCC_opcode_t **priority) { QCC_opcode_t *op, *oldop; @@ -9579,7 +9639,7 @@ QCC_opcode_t *QCC_PR_ChooseOpcode(QCC_sref_t lhs, QCC_sref_t rhs, QCC_opcode_t * } //used to optimise logicops slightly. -pbool QCC_OpHasSideEffects(QCC_statement_t *st) +static pbool QCC_OpHasSideEffects(QCC_statement_t *st) { //function calls potentially always have side effects (and are expensive) if ((st->op >= OP_CALL0 && st->op <= OP_CALL8) || (st->op >= OP_CALL1H && st->op <= OP_CALL8H)) @@ -10065,7 +10125,7 @@ QCC_sref_t QCC_PR_Expression (int priority, int exprflags) } //parse the expression and discard the result. generate a warning if there were no assignments //this avoids generating getter statements from RefToDef in QCC_PR_Expression. -void QCC_PR_DiscardExpression (int priority, int exprflags) +static void QCC_PR_DiscardExpression (int priority, int exprflags) { QCC_ref_t refbuf, *ref; pbool olduseful = qcc_usefulstatement; @@ -10105,7 +10165,7 @@ int QCC_PR_IntConstExpr(void) return true; } -void QCC_PR_GotoStatement (QCC_statement_t *patch2, char *labelname) +static void QCC_PR_GotoStatement (QCC_statement_t *patch2, char *labelname) { if (num_gotos >= max_gotos) { @@ -10120,7 +10180,8 @@ void QCC_PR_GotoStatement (QCC_statement_t *patch2, char *labelname) num_gotos++; } -pbool QCC_PR_StatementBlocksMatch(QCC_statement_t *p1, int p1count, QCC_statement_t *p2, int p2count) +/* +static pbool QCC_PR_StatementBlocksMatch(QCC_statement_t *p1, int p1count, QCC_statement_t *p2, int p2count) { if (p1count != p2count) return false; @@ -10141,7 +10202,7 @@ pbool QCC_PR_StatementBlocksMatch(QCC_statement_t *p1, int p1count, QCC_statemen } return true; -} +}*/ //vanilla qc only has an OP_IFNOT_I, others will be emulated as required, so we tend to need to emulate other opcodes. QCC_statement_t *QCC_Generate_OP_IF(QCC_sref_t e, pbool preserve) @@ -10271,7 +10332,7 @@ QCC_statement_t *QCC_Generate_OP_GOTO(void) } //called for return statements -void PR_GenerateReturnOuts(void) +static void PR_GenerateReturnOuts(void) { unsigned int i; QCC_sref_t p; @@ -10308,7 +10369,7 @@ pulled out of QCC_PR_ParseStatement because of stack use. ============ */ void QCC_PR_ParseStatement (void); -void QCC_PR_ParseStatement_For(void) +static void QCC_PR_ParseStatement_For(void) { int continues; int breaks; @@ -11822,7 +11883,7 @@ void QCC_CompoundJumps(int first, int last) } } #else -void QCC_CompoundJumps(int first, int last) +static void QCC_CompoundJumps(int first, int last) { //jumps to jumps are reordered so they become jumps to the final target. int statement; @@ -11887,7 +11948,7 @@ void QCC_CompoundJumps(int first, int last) } #endif -void QCC_CheckForDeadAndMissingReturns(int first, int last, int rettype) +static void QCC_CheckForDeadAndMissingReturns(int first, int last, int rettype) { QCC_function_t *fnc; int st, st2; @@ -12118,7 +12179,7 @@ void QCC_CommonSubExpressionRemoval(int first, int last) //follow branches (by recursing). //stop on first read(error, return statement) or write(no error, return -1) //end-of-block returns 0, done/return/goto returns -2 -int QCC_CheckOneUninitialised(int firststatement, int laststatement, QCC_def_t *def, unsigned int min, unsigned int max) +static int QCC_CheckOneUninitialised(int firststatement, int laststatement, QCC_def_t *def, unsigned int min, unsigned int max) { int ret; int i; @@ -12221,7 +12282,7 @@ int QCC_CheckOneUninitialised(int firststatement, int laststatement, QCC_def_t * return 0; } -pbool QCC_CheckUninitialised(int firststatement, int laststatement) +static pbool QCC_CheckUninitialised(int firststatement, int laststatement) { QCC_def_t *local; unsigned int i; @@ -12339,7 +12400,7 @@ void QCC_Marshal_Locals(int firststatement, int laststatement) } #ifdef WRITEASM -void QCC_WriteGUIAsmFunction(QCC_function_t *sc, unsigned int firststatement) +static void QCC_WriteGUIAsmFunction(QCC_function_t *sc, unsigned int firststatement) { unsigned int i; // QCC_type_t *type; @@ -12404,9 +12465,9 @@ void QCC_WriteGUIAsmFunction(QCC_function_t *sc, unsigned int firststatement) } } if (currentsourcefile) - printf("code: %s:%i: %i:%s;\n", sc->filen, statements[i].linenum, currentsourcefile, line); + externs->Printf("code: %s:%i: %i:%s;\n", sc->filen, statements[i].linenum, currentsourcefile, line); else - printf("code: %s:%i: %s;\n", sc->filen, statements[i].linenum, line); + externs->Printf("code: %s:%i: %s;\n", sc->filen, statements[i].linenum, line); } } @@ -12499,7 +12560,7 @@ void QCC_WriteAsmFunction(QCC_function_t *sc, unsigned int firststatement, QCC_d } #endif -QCC_function_t *QCC_PR_GenerateBuiltinFunction (QCC_def_t *def, int builtinnum, char *builtinname) +static QCC_function_t *QCC_PR_GenerateBuiltinFunction (QCC_def_t *def, int builtinnum, char *builtinname) { QCC_function_t *func; if (numfunctions >= MAX_FUNCTIONS) @@ -12590,7 +12651,7 @@ static QCC_function_t *QCC_PR_GenerateQCFunction (QCC_def_t *def, QCC_type_t *ty return func; } -void QCC_PR_ResumeFunction(QCC_function_t *f) +static void QCC_PR_ResumeFunction(QCC_function_t *f) { if (pr_scope != f) { @@ -12615,7 +12676,7 @@ void QCC_PR_ResumeFunction(QCC_function_t *f) } } } -void QCC_PR_FinaliseFunction(QCC_function_t *f) +static void QCC_PR_FinaliseFunction(QCC_function_t *f) { QCC_statement_t *st; pbool needsdone=false; @@ -13079,7 +13140,7 @@ QCC_function_t *QCC_PR_ParseImmediateStatements (QCC_def_t *def, QCC_type_t *typ return f; } -void QCC_PR_ArrayRecurseDivideRegular(QCC_sref_t array, QCC_sref_t index, int min, int max) +static void QCC_PR_ArrayRecurseDivideRegular(QCC_sref_t array, QCC_sref_t index, int min, int max) { QCC_statement_t *st; QCC_sref_t eq; @@ -13118,7 +13179,7 @@ void QCC_PR_ArrayRecurseDivideRegular(QCC_sref_t array, QCC_sref_t index, int mi //the idea here is that we return a vector, the caller then figures out the extra 3rd. //This is useful when we have a load of indexes. -void QCC_PR_ArrayRecurseDivideUsingVectors(QCC_sref_t array, QCC_sref_t index, int min, int max) +static void QCC_PR_ArrayRecurseDivideUsingVectors(QCC_sref_t array, QCC_sref_t index, int min, int max) { QCC_statement_t *st; QCC_sref_t eq; @@ -13363,7 +13424,7 @@ void QCC_PR_EmitArrayGetFunction(QCC_def_t *scope, QCC_def_t *arraydef, char *ar QCC_FreeTemps(); } -void QCC_PR_ArraySetRecurseDivide(QCC_sref_t array, QCC_sref_t index, QCC_sref_t value, int min, int max) +static void QCC_PR_ArraySetRecurseDivide(QCC_sref_t array, QCC_sref_t index, QCC_sref_t value, int min, int max) { QCC_statement_t *st; QCC_sref_t eq; @@ -13651,6 +13712,7 @@ QCC_def_t *QCC_PR_DummyDef(QCC_type_t *type, const char *name, QCC_function_t *s case ev_accessor: //shouldn't happen. case ev_enum: case ev_float: + case ev_boolean: case ev_string: case ev_entity: case ev_field: @@ -14027,7 +14089,7 @@ QCC_sref_t QCC_PR_GetSRef (QCC_type_t *type, const char *name, QCC_function_t *s } //.union {}; -QCC_def_t *QCC_PR_DummyFieldDef(QCC_type_t *type, QCC_function_t *scope, int arraysize, unsigned int *fieldofs, unsigned int saved) +static QCC_def_t *QCC_PR_DummyFieldDef(QCC_type_t *type, QCC_function_t *scope, int arraysize, unsigned int *fieldofs, unsigned int saved) { char array[64]; char newname[256]; @@ -14046,7 +14108,7 @@ QCC_def_t *QCC_PR_DummyFieldDef(QCC_type_t *type, QCC_function_t *scope, int arr else QC_snprintfz(array, sizeof(array), "[%i]", a); -// printf("Emited %s\n", newname); +// externs->Printf("Emited %s\n", newname); if ((type)->type == ev_struct||(type)->type == ev_union) { @@ -14072,6 +14134,7 @@ QCC_def_t *QCC_PR_DummyFieldDef(QCC_type_t *type, QCC_function_t *scope, int arr case ev_enum: case ev_accessor: case ev_float: + case ev_boolean: case ev_string: case ev_vector: case ev_entity: @@ -14125,12 +14188,173 @@ QCC_def_t *QCC_PR_DummyFieldDef(QCC_type_t *type, QCC_function_t *scope, int arr -void QCC_PR_ExpandUnionToFields(QCC_type_t *type, unsigned int *fields) +static void QCC_PR_ExpandUnionToFields(QCC_type_t *type, unsigned int *fields) { QCC_type_t *pass = type->aux_type; QCC_PR_DummyFieldDef(pass, pr_scope, 1, fields, GDF_SAVED|GDF_CONST); } +//copies tmp into def +//FIXME: is basedef redundant? +//FIXME: is type redundant? +static pbool QCC_PR_GenerateInitializerType(QCC_def_t *basedef, QCC_sref_t tmp, QCC_sref_t def, QCC_type_t *type, unsigned int flags) +{ + pbool ret = true; + unsigned i; + if (basedef && (!basedef->scope || basedef->constant || basedef->isstatic)) + { + if (!tmp.sym->constant) + { + if (basedef->scope && !basedef->isstatic && !basedef->initialized) + { +// QCC_PR_ParseWarning(WARN_GMQCC_SPECIFIC, "initializer for '%s' is not constant", basedef->name); +// QCC_PR_ParsePrintSRef(WARN_GMQCC_SPECIFIC, tmp); +// basedef->constant = false; + goto finalnotconst; + } + QCC_PR_ParseWarning(ERR_BADIMMEDIATETYPE, "initializer for '%s' is not constant", basedef->name); + QCC_PR_ParsePrintSRef(ERR_BADIMMEDIATETYPE, tmp); + } + else + { + tmp.sym->referenced = true; + if (!tmp.sym->initialized) + { + //FIXME: we NEED to support relocs somehow + QCC_PR_ParseWarning(WARN_UNINITIALIZED, "initializer is not initialised, %s will be treated as 0", QCC_GetSRefName(tmp)); + QCC_PR_ParsePrintSRef(WARN_UNINITIALIZED, tmp); + } + + if (basedef->initialized && !basedef->unused && !(flags & PIF_STRONGER)) + { + for (i = 0; (unsigned)i < type->size; i++) + if (def.sym->symboldata[def.ofs+i]._int != tmp.sym->symboldata[tmp.ofs+i]._int) + { + if (!def.sym->arraysize && def.cast->type == ev_function && !strcmp(def.sym->name, "parseentitydata") && (functions[def.sym->symboldata[def.ofs+i]._int].builtin == 608 || functions[def.sym->symboldata[def.ofs+i]._int].builtin == 613)) + { //dpextensions is WRONG, and claims it to be 608. its also too common, so lets try working around that. + if (functions[def.sym->symboldata[def.ofs+i]._int].builtin == 608) + functions[def.sym->symboldata[def.ofs+i]._int].builtin = 613; + QCC_PR_ParseWarning (WARN_COMPATIBILITYHACK, "incompatible redeclaration. Please validate builtin numbers. parseentitydata is #613"); + QCC_PR_ParsePrintSRef(WARN_COMPATIBILITYHACK, tmp); + } + else if (!def.sym->arraysize && def.cast->type == ev_function && functions[def.sym->symboldata[def.ofs+i]._int].code>-1 && functions[tmp.sym->symboldata[tmp.ofs+i]._int].code==-1) + { + QCC_PR_ParseWarning (WARN_COMPATIBILITYHACK, "incompatible redeclaration. Ignoring replacement of qc function with builtin."); + QCC_PR_ParsePrintSRef(WARN_COMPATIBILITYHACK, tmp); + } + else + QCC_PR_ParseErrorPrintSRef (ERR_REDECLARATION, def, "incompatible redeclaration"); + } + } + else + { + for (i = 0; (unsigned)i < type->size; i++) + def.sym->symboldata[def.ofs+i]._int = tmp.sym->symboldata[tmp.ofs+i]._int; + } + } + } + else + { + QCC_sref_t rhs; +finalnotconst: + rhs = tmp; + if (def.sym->initialized) + QCC_PR_ParseErrorPrintSRef (ERR_REDECLARATION, def, "%s initialised twice", basedef->name); + + ret = 0; + for (i = 0; (unsigned)i < type->size; ) + { + if (type->size - i >= 3) + { + rhs.cast = def.cast = type_vector; + if (type->size - i == 3) + { + QCC_FreeTemp(QCC_PR_StatementFlags(&pr_opcodes[OP_STORE_V], rhs, def, NULL, STFL_PRESERVEB)); + return ret; + } + else + QCC_FreeTemp(QCC_PR_StatementFlags(&pr_opcodes[OP_STORE_V], rhs, def, NULL, STFL_PRESERVEA|STFL_PRESERVEB)); + i+=3; + def.ofs += 3; + rhs.ofs += 3; + } + else + { + if (def.cast->type == ev_function) + { + rhs.cast = def.cast = type_function; + if (type->size - i == 1) + { + QCC_FreeTemp(QCC_PR_StatementFlags(&pr_opcodes[OP_STORE_FNC], rhs, def, NULL, STFL_PRESERVEB)); + return ret; + } + else + QCC_FreeTemp(QCC_PR_StatementFlags(&pr_opcodes[OP_STORE_FNC], rhs, def, NULL, STFL_PRESERVEA|STFL_PRESERVEB)); + } + else if (def.cast->type == ev_string) + { + rhs.cast = def.cast = type_string; + if (type->size - i == 1) + { + QCC_FreeTemp(QCC_PR_StatementFlags(&pr_opcodes[OP_STORE_S], rhs, def, NULL, STFL_PRESERVEB)); + return ret; + } + else + QCC_FreeTemp(QCC_PR_StatementFlags(&pr_opcodes[OP_STORE_S], rhs, def, NULL, STFL_PRESERVEA|STFL_PRESERVEB)); + } + else if (def.cast->type == ev_entity) + { + rhs.cast = def.cast = type_entity; + if (type->size - i == 1) + { + QCC_FreeTemp(QCC_PR_StatementFlags(&pr_opcodes[OP_STORE_ENT], rhs, def, NULL, STFL_PRESERVEB)); + return ret; + } + else + QCC_FreeTemp(QCC_PR_StatementFlags(&pr_opcodes[OP_STORE_ENT], rhs, def, NULL, STFL_PRESERVEA|STFL_PRESERVEB)); + } + else if (def.cast->type == ev_field) + { + rhs.cast = def.cast = type_field; + if (type->size - i == 1) + { + QCC_FreeTemp(QCC_PR_StatementFlags(&pr_opcodes[OP_STORE_FLD], rhs, def, NULL, STFL_PRESERVEB)); + return ret; + } + else + QCC_FreeTemp(QCC_PR_StatementFlags(&pr_opcodes[OP_STORE_FLD], rhs, def, NULL, STFL_PRESERVEA|STFL_PRESERVEB)); + } + else if (def.cast->type == ev_integer) + { + rhs.cast = def.cast = type_integer; + if (type->size - i == 1) + { + QCC_FreeTemp(QCC_PR_StatementFlags(&pr_opcodes[OP_STORE_I], rhs, def, NULL, STFL_PRESERVEB)); + return ret; + } + else + QCC_FreeTemp(QCC_PR_StatementFlags(&pr_opcodes[OP_STORE_I], rhs, def, NULL, STFL_PRESERVEA|STFL_PRESERVEB)); + } + else + { + rhs.cast = def.cast = type_float; + if (type->size - i == 1) + { + QCC_FreeTemp(QCC_PR_StatementFlags(&pr_opcodes[OP_STORE_F], rhs, def, NULL, STFL_PRESERVEB)); + return ret; + } + else + QCC_FreeTemp(QCC_PR_StatementFlags(&pr_opcodes[OP_STORE_F], rhs, def, NULL, STFL_PRESERVEA|STFL_PRESERVEB)); + } + i++; + def.ofs++; + rhs.ofs++; + } + } + } + QCC_FreeTemp(tmp); + return ret; +} //basedef can be null, meaning its initialising a temp //returns true where its a const/static initialiser. false if non-const/final initialiser pbool QCC_PR_ParseInitializerType(int arraysize, QCC_def_t *basedef, QCC_sref_t def, unsigned int flags) @@ -14358,23 +14582,85 @@ pbool QCC_PR_ParseInitializerType(int arraysize, QCC_def_t *basedef, QCC_sref_t unsigned int partnum; pbool isunion; gofs_t offset = def.ofs; + pbool *isinited = alloca(sizeof(pbool)*type->size); + const char *mname; + struct QCC_typeparam_s *tp; + memset(isinited, 0, sizeof(pbool)*type->size); - isunion = ((type)->type == ev_union); - for (partnum = 0; partnum < (type)->num_parms; partnum++) + if (QCC_PR_PeekToken(".")) //won't be a float (.0 won't match) { - if (QCC_PR_CheckToken("}")) - break; - - def.cast = (type)->params[partnum].type; - def.ofs = offset + (type)->params[partnum].ofs; - - ret &= QCC_PR_ParseInitializerType((type)->params[partnum].arraysize, basedef, def, flags); - if (isunion || !QCC_PR_CheckToken(",")) + for(;;) { - if (isunion && (type->num_parms == 1 && !type->params->paramname)) + if (QCC_PR_CheckToken(".")) + { + mname = QCC_PR_ParseName(); + QCC_PR_Expect("="); + tp = QCC_PR_FindStructMember(type, mname, &def.ofs); + if (isinited[def.ofs]) + QCC_PR_ParseError (ERR_EXPECTED, "%s.%s was already ininitialised", type->name, mname); + isinited[def.ofs] = true; + def.ofs += offset; + def.cast = tp->type; + + ret &= QCC_PR_ParseInitializerType(tp->arraysize, basedef, def, flags); + } + else + QCC_PR_ParseError (ERR_EXPECTED, "designated initialisers require all members to be initialised the same way"); + + if (QCC_PR_CheckToken("}")) break; - QCC_PR_Expect("}"); - break; + QCC_PR_Expect(","); + } + partnum = 0; + } + else if (type->parentclass) + { + if (!QCC_PR_CheckToken("}")) + QCC_PR_ParseError (ERR_EXPECTED, "inherited structs must use designated initialisers"); + } + else + { + //FIXME: inheritance makes stuff weird + isunion = ((type)->type == ev_union); + for (partnum = 0; partnum < (type)->num_parms; partnum++) + { + if (QCC_PR_CheckToken("}")) + break; + if ((type)->params[partnum].isvirtual) + continue; //these are pre-initialised.... + + def.cast = (type)->params[partnum].type; + def.ofs = (type)->params[partnum].ofs; + isinited[def.ofs] = true; + def.ofs += offset; + + ret &= QCC_PR_ParseInitializerType((type)->params[partnum].arraysize, basedef, def, flags); + if (isunion || !QCC_PR_CheckToken(",")) + { + if (isunion && (type->num_parms == 1 && !type->params->paramname)) + break; + QCC_PR_Expect("}"); + break; + } + } + } + for (; type; type = type->parentclass) + { + for (partnum = 0; partnum < (type)->num_parms; partnum++) + { + //copy into the def. should be from a const. + def.cast = (type)->params[partnum].type; + def.ofs = (type)->params[partnum].ofs; + if (isinited[def.ofs]) + continue; + isinited[def.ofs] = true; + def.ofs += offset; + if ((type)->params[partnum].defltvalue.cast) + tmp = (type)->params[partnum].defltvalue; + else + tmp = QCC_MakeIntConst(0); + QCC_ForceUnFreeDef(tmp.sym); + QCC_PR_GenerateInitializerType(basedef, tmp, def, def.cast, flags); } } return ret; @@ -14432,158 +14718,7 @@ pbool QCC_PR_ParseInitializerType(int arraysize, QCC_def_t *basedef, QCC_sref_t tmp = QCC_EvaluateCast(tmp, type, true); } - if (basedef && (!basedef->scope || basedef->constant || basedef->isstatic)) - { - if (!tmp.sym->constant) - { - if (basedef->scope && !basedef->isstatic && !basedef->initialized) - { -// QCC_PR_ParseWarning(WARN_GMQCC_SPECIFIC, "initializer for '%s' is not constant", basedef->name); -// QCC_PR_ParsePrintSRef(WARN_GMQCC_SPECIFIC, tmp); -// basedef->constant = false; - goto finalnotconst; - } - QCC_PR_ParseWarning(ERR_BADIMMEDIATETYPE, "initializer for '%s' is not constant", basedef->name); - QCC_PR_ParsePrintSRef(ERR_BADIMMEDIATETYPE, tmp); - } - else - { - tmp.sym->referenced = true; - if (!tmp.sym->initialized) - { - //FIXME: we NEED to support relocs somehow - QCC_PR_ParseWarning(WARN_UNINITIALIZED, "initializer is not initialised, %s will be treated as 0", QCC_GetSRefName(tmp)); - QCC_PR_ParsePrintSRef(WARN_UNINITIALIZED, tmp); - } - - if (basedef->initialized && !basedef->unused && !(flags & PIF_STRONGER)) - { - for (i = 0; (unsigned)i < type->size; i++) - if (def.sym->symboldata[def.ofs+i]._int != tmp.sym->symboldata[tmp.ofs+i]._int) - { - if (!def.sym->arraysize && def.cast->type == ev_function && !strcmp(def.sym->name, "parseentitydata") && (functions[def.sym->symboldata[def.ofs+i]._int].builtin == 608 || functions[def.sym->symboldata[def.ofs+i]._int].builtin == 613)) - { //dpextensions is WRONG, and claims it to be 608. its also too common, so lets try working around that. - if (functions[def.sym->symboldata[def.ofs+i]._int].builtin == 608) - functions[def.sym->symboldata[def.ofs+i]._int].builtin = 613; - QCC_PR_ParseWarning (WARN_COMPATIBILITYHACK, "incompatible redeclaration. Please validate builtin numbers. parseentitydata is #613"); - QCC_PR_ParsePrintSRef(WARN_COMPATIBILITYHACK, tmp); - } - else if (!def.sym->arraysize && def.cast->type == ev_function && functions[def.sym->symboldata[def.ofs+i]._int].code>-1 && functions[tmp.sym->symboldata[tmp.ofs+i]._int].code==-1) - { - QCC_PR_ParseWarning (WARN_COMPATIBILITYHACK, "incompatible redeclaration. Ignoring replacement of qc function with builtin."); - QCC_PR_ParsePrintSRef(WARN_COMPATIBILITYHACK, tmp); - } - else - QCC_PR_ParseErrorPrintSRef (ERR_REDECLARATION, def, "incompatible redeclaration"); - } - } - else - { - for (i = 0; (unsigned)i < type->size; i++) - def.sym->symboldata[def.ofs+i]._int = tmp.sym->symboldata[tmp.ofs+i]._int; - } - } - } - else - { - QCC_sref_t rhs; -finalnotconst: - rhs = tmp; - if (def.sym->initialized) - QCC_PR_ParseErrorPrintSRef (ERR_REDECLARATION, def, "%s initialised twice", basedef->name); - - ret = 0; - for (i = 0; (unsigned)i < type->size; ) - { - if (type->size - i >= 3) - { - rhs.cast = def.cast = type_vector; - if (type->size - i == 3) - { - QCC_FreeTemp(QCC_PR_StatementFlags(&pr_opcodes[OP_STORE_V], rhs, def, NULL, STFL_PRESERVEB)); - return ret; - } - else - QCC_FreeTemp(QCC_PR_StatementFlags(&pr_opcodes[OP_STORE_V], rhs, def, NULL, STFL_PRESERVEA|STFL_PRESERVEB)); - i+=3; - def.ofs += 3; - rhs.ofs += 3; - } - else - { - if (def.cast->type == ev_function) - { - rhs.cast = def.cast = type_function; - if (type->size - i == 1) - { - QCC_FreeTemp(QCC_PR_StatementFlags(&pr_opcodes[OP_STORE_FNC], rhs, def, NULL, STFL_PRESERVEB)); - return ret; - } - else - QCC_FreeTemp(QCC_PR_StatementFlags(&pr_opcodes[OP_STORE_FNC], rhs, def, NULL, STFL_PRESERVEA|STFL_PRESERVEB)); - } - else if (def.cast->type == ev_string) - { - rhs.cast = def.cast = type_string; - if (type->size - i == 1) - { - QCC_FreeTemp(QCC_PR_StatementFlags(&pr_opcodes[OP_STORE_S], rhs, def, NULL, STFL_PRESERVEB)); - return ret; - } - else - QCC_FreeTemp(QCC_PR_StatementFlags(&pr_opcodes[OP_STORE_S], rhs, def, NULL, STFL_PRESERVEA|STFL_PRESERVEB)); - } - else if (def.cast->type == ev_entity) - { - rhs.cast = def.cast = type_entity; - if (type->size - i == 1) - { - QCC_FreeTemp(QCC_PR_StatementFlags(&pr_opcodes[OP_STORE_ENT], rhs, def, NULL, STFL_PRESERVEB)); - return ret; - } - else - QCC_FreeTemp(QCC_PR_StatementFlags(&pr_opcodes[OP_STORE_ENT], rhs, def, NULL, STFL_PRESERVEA|STFL_PRESERVEB)); - } - else if (def.cast->type == ev_field) - { - rhs.cast = def.cast = type_field; - if (type->size - i == 1) - { - QCC_FreeTemp(QCC_PR_StatementFlags(&pr_opcodes[OP_STORE_FLD], rhs, def, NULL, STFL_PRESERVEB)); - return ret; - } - else - QCC_FreeTemp(QCC_PR_StatementFlags(&pr_opcodes[OP_STORE_FLD], rhs, def, NULL, STFL_PRESERVEA|STFL_PRESERVEB)); - } - else if (def.cast->type == ev_integer) - { - rhs.cast = def.cast = type_integer; - if (type->size - i == 1) - { - QCC_FreeTemp(QCC_PR_StatementFlags(&pr_opcodes[OP_STORE_I], rhs, def, NULL, STFL_PRESERVEB)); - return ret; - } - else - QCC_FreeTemp(QCC_PR_StatementFlags(&pr_opcodes[OP_STORE_I], rhs, def, NULL, STFL_PRESERVEA|STFL_PRESERVEB)); - } - else - { - rhs.cast = def.cast = type_float; - if (type->size - i == 1) - { - QCC_FreeTemp(QCC_PR_StatementFlags(&pr_opcodes[OP_STORE_F], rhs, def, NULL, STFL_PRESERVEB)); - return ret; - } - else - QCC_FreeTemp(QCC_PR_StatementFlags(&pr_opcodes[OP_STORE_F], rhs, def, NULL, STFL_PRESERVEA|STFL_PRESERVEB)); - } - i++; - def.ofs++; - rhs.ofs++; - } - } - } - QCC_FreeTemp(tmp); + ret = QCC_PR_GenerateInitializerType(basedef, tmp, def, type, flags); } return ret; } @@ -15105,9 +15240,9 @@ void QCC_PR_ParseDefs (char *classname, pbool fatal) inlinefunction = type_inlinefunction; - if (externfnc && basetype->type != ev_function) + if (externfnc && !pr_scope && basetype->type != ev_function) { - printf ("Only functions may be defined as external (yet)\n"); + externs->Printf ("Only global functions may be defined as external (yet)\n"); externfnc=false; } @@ -15306,13 +15441,16 @@ void QCC_PR_ParseDefs (char *classname, pbool fatal) type = QCC_PR_ParseFunctionType(false, type); } + allocatenew = true; if (classname) { char *membername = name; name = qccHunkAlloc(strlen(classname) + strlen(name) + 3); sprintf(name, "%s::%s", classname, membername); defclass = QCC_TypeForName(classname); - if (!defclass || !defclass->parentclass) + if (defclass && defclass->type == ev_struct) + allocatenew = false; + else if (!defclass || !defclass->parentclass) QCC_PR_ParseError(ERR_NOTANAME, "%s is not a class\n", classname); } else @@ -15382,7 +15520,10 @@ void QCC_PR_ParseDefs (char *classname, pbool fatal) def->nofold = true; } if (externfnc) - def->initialized = 2; + { + def->initialized = true; + def->isextern = true; + } if (isstatic) { @@ -15627,6 +15768,7 @@ PR_CompileFile compiles the 0 terminated text, adding defintions to the pr structure ============ */ +void QCC_PR_LexWhitespace (pbool inhibitpreprocessor); pbool QCC_PR_CompileFile (char *string, char *filename) { char *tmp; @@ -15664,7 +15806,79 @@ pbool QCC_PR_CompileFile (char *string, char *filename) QCC_PR_Lex (); // read first token } - while (pr_token_type != tt_eof) + if (preprocessonly) + { + pbool white = false; + static int line = 1;//pr_source_line; + static const char *fname = NULL; + static QCC_string_t fnamed = 0; + while(pr_token_type != tt_eof) + { +// white = (qcc_iswhite(*pr_file_p) || (*pr_file_p == '/' && (pr_file_p[1] == '/' || pr_file_p[1] == '*'))); +// QCC_PR_LexWhitespace (false); + + if (fnamed != s_filed) + { + line = pr_token_line; + fname = s_filen; + fnamed = s_filed; + externs->Printf("\n#pragma file(%s)\n",fname); + externs->Printf("#pragma line(%i)\n",line); + } + else + { + //if there's whitespace next, make sure we represent that + while(line < pr_token_line) + { //keep line numbers correct by splurging multiple newlines. + externs->Printf("\n"); + white = false; + line++; + } + if (white) + externs->Printf(" "); + } + + if (pr_token_type == tt_immediate && pr_immediate_type == type_string) + { + const char *s = pr_token; + externs->Printf("\""); + while (*s) + { + switch(*s) + { + case 0: + externs->Printf("%c", 0); + break; + case '\\': + externs->Printf("\\\\"); + break; + case '\"': + externs->Printf("\\\""); + break; + case '\r': + externs->Printf("\\r"); + break; + case '\n': + externs->Printf("\\n"); + break; + case '\t': + externs->Printf("\\t"); + break; + default: + externs->Printf("%c", *s); + break; + } + s++; + } + externs->Printf("\""); + } + else + externs->Printf("%s", pr_token); + white = (qcc_iswhite(*pr_file_p) || (*pr_file_p == '/' && (pr_file_p[1] == '/' || pr_file_p[1] == '*'))); + QCC_PR_Lex(); + } + } + else while (pr_token_type != tt_eof) { if (setjmp(pr_parse_abort)) { diff --git a/engine/qclib/qcc_pr_lex.c b/engine/qclib/qcc_pr_lex.c index 3a74074ca..b9d2aba0f 100644 --- a/engine/qclib/qcc_pr_lex.c +++ b/engine/qclib/qcc_pr_lex.c @@ -1,9 +1,6 @@ #if !defined(MINIMAL) && !defined(OMIT_QCC) #include "qcc.h" -#ifdef QCC -#define print printf -#endif #include "time.h" #define MEMBERFIELDNAME "__m%s" @@ -302,16 +299,16 @@ void QCC_FindBestInclude(char *newfile, char *currentfile, pbool verbose) if (verbose == 2) { if (autoprototype) - printf("prototyping %s\n", fullname); + externs->Printf("prototyping %s\n", fullname); else - printf("compiling %s\n", fullname); + externs->Printf("compiling %s\n", fullname); } else { if (autoprototype) - printf("prototyping include %s\n", fullname); + externs->Printf("prototyping include %s\n", fullname); else - printf("including %s\n", fullname); + externs->Printf("including %s\n", fullname); } } QCC_Include(fullname); @@ -333,7 +330,7 @@ pbool QCC_PR_SimpleGetString(void); #define PPI_COMPARISON 3 #define PPI_LOGICAL 4 #define PPI_TOPLEVEL 5 -int ParsePrecompilerIf(int level) +static int ParsePrecompilerIf(int level) { CompilerConstant_t *c; int eval = 0; @@ -602,7 +599,7 @@ static void QCC_PR_SkipToEndOfLine(pbool errorifnonwhite) } //if hadtrue, then we allow elses, otherwise we skip them. -pbool QCC_PR_FalsePreProcessorIf(pbool hadtrue, int originalline) +static pbool QCC_PR_FalsePreProcessorIf(pbool hadtrue, int originalline) { int eval; int level = 1; @@ -688,7 +685,7 @@ static void QCC_PR_PackagerMessage(void *userctx, char *message, ...) QC_vsnprintf (string,sizeof(string)-1,message,argptr); va_end (argptr); - printf ("%s", string); + externs->Printf ("%s", string); } #endif @@ -699,7 +696,7 @@ QCC_PR_Precompiler Runs precompiler stage */ -pbool QCC_PR_Precompiler(void) +static pbool QCC_PR_Precompiler(void) { char msg[1024]; int ifmode; @@ -856,9 +853,9 @@ pbool QCC_PR_Precompiler(void) msg[a] = '\0'; if (flag_msvcstyle) - printf ("%s(%i) : #message: %s\n", s_filen, pr_source_line, msg); + externs->Printf ("%s(%i) : #message: %s\n", s_filen, pr_source_line, msg); else - printf ("%s:%i: #message: %s\n", s_filen, pr_source_line, msg); + externs->Printf ("%s:%i: #message: %s\n", s_filen, pr_source_line, msg); QCC_PR_SkipToEndOfLine(false); } else if (!strncmp(directive, "copyright", 9)) @@ -935,12 +932,12 @@ pbool QCC_PR_Precompiler(void) pr_file_p++; QCC_PR_SimpleGetString(); - printf("Merging to %s\n", pr_token); + externs->Printf("Merging to %s\n", pr_token); QCC_ImportProgs(pr_token); if (!*destfile) { QCC_Canonicalize(destfile, sizeof(destfile), pr_token, compilingfile); - printf("Outputfile: %s\n", destfile); + externs->Printf("Outputfile: %s\n", destfile); } QCC_PR_SkipToEndOfLine(true); @@ -1039,7 +1036,7 @@ pbool QCC_PR_Precompiler(void) pr_file_p++; QCC_PR_SimpleGetString(); - printf("Including datafile: %s\n", pr_token); + externs->Printf("Including datafile: %s\n", pr_token); QCC_AddFile(pr_token); pr_file_p++; @@ -1064,7 +1061,7 @@ pbool QCC_PR_Precompiler(void) QCC_PR_SimpleGetString(); QCC_Canonicalize(destfile, sizeof(destfile), pr_token, compilingfile); - printf("Outputfile: %s\n", pr_token); + externs->Printf("Outputfile: %s\n", pr_token); QCC_PR_SkipToEndOfLine(true); } @@ -1360,7 +1357,7 @@ pbool QCC_PR_Precompiler(void) QCC_Canonicalize(destfile, sizeof(destfile), qcc_token, compilingfile); if (strcmp(destfile, olddest)) - printf("Outputfile: %s\n", destfile); + externs->Printf("Outputfile: %s\n", destfile); } else if (!QC_strcasecmp(qcc_token, "keyword") || !QC_strcasecmp(qcc_token, "flag")) { @@ -1577,9 +1574,10 @@ void QCC_PR_LexString (void) char *end, *cnst; int raw; char rawdelim[64]; - int stringtype = flag_utf8strings?2:0; //0 - quake output, input is 8bit. warnings when its not ascii. \u will still give utf-8 text, other chars as-is. Expect \s to screw everything up with utf-8 output. - //1 - quake output, input is utf-8. due to editors not supporting it, that generally means the input (ab)uses markup. - //2 - utf-8 output, input is utf-8. welcome to the future! unfortunately not the present. + int stringtype; + //0 - quake output, input is 8bit. warnings when its not ascii. \u will still give utf-8 text, other chars as-is. Expect \s to screw everything up with utf-8 output. + //1 - quake output, input is utf-8. due to editors not supporting it, that generally means the input (ab)uses markup. + //2 - utf-8 output, input is utf-8. welcome to the future! unfortunately not the present. int texttype; pbool first = true; @@ -1632,6 +1630,7 @@ void QCC_PR_LexString (void) pr_file_p += 2; pr_source_line++; } + stringtype = 0; } else if (*pr_file_p == 'Q' && pr_file_p[1] == '\"') { //quake output with utf-8 input (expect to need markup). @@ -1650,9 +1649,15 @@ void QCC_PR_LexString (void) pr_file_p+=3; } else if (*pr_file_p == '\"') + { + stringtype = flag_utf8strings?2:0; pr_file_p++; + } else if (first) + { + stringtype = 0; QCC_PR_ParseError(ERR_BADCHARACTERCODE, "Expected string constant"); + } else break; first = false; @@ -1663,40 +1668,6 @@ void QCC_PR_LexString (void) if (!c) QCC_PR_ParseError (ERR_EOF, "EOF inside quote"); - /* - if (!qccwarningaction[WARN_NOTUTF8] && (c&0x80)) - { - //convert 0xe000 private-use area to quake's charset (if they don't have the utf-8 warning enabled) - //note: this may have a small false-positive risk. - if (utf8_check(pr_file_p-1, &code)) - { - if (code >= 0xe000 && code <= 0xe0ff) - { - pr_file_p += utf8_check(pr_file_p-1, &code)-1; - c = code & 0xff; - } - else - QCC_PR_ParseWarning(WARN_DODGYCHARSET, "non-ascii chars outside of quake-mapped private-use area", sizeof(pr_token)-1); - } - else - QCC_PR_ParseWarning(WARN_DODGYCHARSET, "source file is not unicode", sizeof(pr_token)-1); - } - */ - -/* //these two conditions are generally part of the C preprocessor. - if (c == '\\' && *pr_file_p == '\r' && pr_file_p[1] == '\n') - { //dos format - pr_file_p += 2; - pr_source_line++; - continue; - } - if (c == '\\' && (*pr_file_p == '\r' || pr_file_p[1] == '\n')) - { //mac + unix format - pr_file_p += 1; - pr_source_line++; - continue; - } -*/ if (raw) { //raw strings contain very little parsing. just delimiter and initial \NL support. @@ -1740,7 +1711,7 @@ void QCC_PR_LexString (void) c = '\f'; //form feed else if (c == 's' || c == 'b') { - texttype ^= 128; + texttype ^= 0xe080; continue; } //else if (c == 'b') @@ -1908,20 +1879,22 @@ void QCC_PR_LexString (void) c = '\n'; else { - unsigned int cp; + unsigned int cp = c; unsigned int len = stringtype?utf8_check(pr_file_p-1, &cp):0; if (!len) { //invalid utf-8 encoding? don't treat it as utf-8! if (stringtype) QCC_PR_ParseWarning(ERR_BADCHARACTERCODE, "Input string is not valid utf-8"); - c |= texttype; - goto forcequake; + if (c >= ' ') + c |= texttype; + goto forcebyte; } if (texttype) { - c = cp; - if (cp < 128) - c |= 0xe080; //FIXME: technically invalid for C0 chars. + if (cp < ' ') + c = cp; //don't mask C0 chars like \t or \n + else if (cp < 0x80) + c = cp|0xe080; //DO mask other ascii chars (and map to the private-use range at the same time, because this isn't standard unicode any more) else { QCC_PR_ParseWarning(ERR_BADCHARACTERCODE, "Unable to mask non-ascii chars. Attempting to mask bytes"); @@ -1935,6 +1908,8 @@ void QCC_PR_LexString (void) } } +// if (c >= 0x20 && c < 0x80) +// c |= 0xe000; //TEST if (stringtype == 2) { //we're outputting a utf-8 string. forceutf8: @@ -1943,11 +1918,16 @@ forceutf8: //figure out the count of bytes required to encode this char bytecount = 1; - t = 0x7f; - while (c > t) + t = 0x80; + while (c >= t) { + if (bytecount == 1) + t <<= 4; + else if (bytecount < 7) + t <<= 5; + else + t <<= 6; bytecount++; - t = (t<<5) | 0x1f; } //error if needed @@ -1960,6 +1940,7 @@ forceutf8: else { t = bytecount*6; + t = t-6; pr_token[len++] = (unsigned char)((c>>t)&(0x0000007f>>bytecount)) | (0xffffff00 >> bytecount); do { @@ -1976,8 +1957,11 @@ forcequake: c = c & 0xff; //this private use range is commonly used for quake's glyphs. else if (c >= 0 && c <= 0x7f) ; //FIXME: SOME c0 codes are known to quake, but many got reused for random glyphs. however I'm going to treat quake as full ascii. - else if (c > 0xff) + else if (c >= 0x80) + { + //FIXME: spit it out as ^{xxxxxx} instead QCC_PR_ParseWarning(WARN_NOTUTF8, "Cannot convert character to quake's charset"); + } forcebyte: if (len >= sizeof(pr_token)-1) @@ -2053,7 +2037,7 @@ int QCC_PR_LexInteger (void) #define LL(x) x##ll #endif -void QCC_PR_LexNumber (void) +static void QCC_PR_LexNumber (void) { int tokenlen = 0; longlong num=0; @@ -2205,7 +2189,7 @@ qccxhex: } -float QCC_PR_LexFloat (void) +static float QCC_PR_LexFloat (void) { int c; int len; @@ -2232,7 +2216,7 @@ PR_LexVector Parses a single quoted vector ============== */ -void QCC_PR_LexVector (void) +static void QCC_PR_LexVector (void) { int i; @@ -2316,7 +2300,7 @@ PR_LexName Parses an identifier ============== */ -void QCC_PR_LexName (void) +static void QCC_PR_LexName (void) { unsigned int c; int len; @@ -2369,7 +2353,7 @@ void QCC_PR_LexName (void) PR_LexPunctuation ============== */ -void QCC_PR_LexPunctuation (void) +static void QCC_PR_LexPunctuation (void) { int i; int len; @@ -2515,7 +2499,7 @@ void QCC_PR_ClearGrabMacros (pbool newfile) pr_savedmacro = -1; } -int QCC_PR_FindMacro (char *name) +static int QCC_PR_FindMacro (char *name) { int i; @@ -2541,7 +2525,7 @@ int QCC_PR_FindMacro (char *name) return -1; } -void QCC_PR_ExpandMacro(void) +static void QCC_PR_ExpandMacro(void) { int i = QCC_PR_FindMacro(pr_token); @@ -2673,7 +2657,7 @@ pbool QCC_PR_SimpleGetToken (void) return i!=0; } -pbool QCC_PR_LexMacroName(void) +static pbool QCC_PR_LexMacroName(void) { int c; int i; @@ -2714,7 +2698,7 @@ pbool QCC_PR_LexMacroName(void) return i!=0; } -void QCC_PR_MacroFrame(char *name, int value, pbool force) +static void QCC_PR_MacroFrame(char *name, int value, pbool force) { int i; for (i=pr_nummacros-1 ; i>=0 ; i--) @@ -2748,7 +2732,7 @@ void QCC_PR_MacroFrame(char *name, int value, pbool force) } } -void QCC_PR_ParseFrame (void) +static void QCC_PR_ParseFrame (void) { while (QCC_PR_LexMacroName ()) { @@ -2763,7 +2747,7 @@ PR_LexGrab Deals with counting sequence numbers and replacing frame macros ============== */ -void QCC_PR_LexGrab (void) +static void QCC_PR_LexGrab (void) { pr_file_p++; // skip the $ // if (!QCC_PR_SimpleGetToken ()) @@ -2886,14 +2870,6 @@ CompilerConstant_t *QCC_PR_DefineName(char *name) return cnst; } -void QCC_PR_Undefine(void) -{ - QCC_PR_SimpleGetToken (); - - QCC_PR_UndefineName(pr_token); -// QCC_PR_ParseError("%s was not defined.", pr_token); -} - void QCC_PR_PreProcessor_Define(pbool append) { char *d; @@ -3033,13 +3009,10 @@ void QCC_PR_PreProcessor_Define(pbool append) if( s[1] == '\n' || s[1] == '\r' ) { char *exploitcheck; - s++; + s++; //skip the \ char + if (*s == '\r' && s[1] == '\n') + s++; //skip the \r. the \n will become part of the macro. QCC_PR_NewLine(true); - s++; - if( s[-1] == '\r' && s[0] == '\n' ) - { - s++; - } /* This began as a bug. It is still evil, but its oh so useful. @@ -3234,7 +3207,7 @@ static void QCC_PR_ExpandStrCatMarkup(char **buffer, size_t *bufferlen, size_t * /*no null terminator, remember to cat one if required*/ } -const struct tm *QCC_CurrentTime(void) +static const struct tm *QCC_CurrentTime(void) { //if SOURCE_DATE_EPOCH environment is defined, use that as seconds from epoch (and show utc) //this helps give reproducable builds (which is for some debian project, demonstrating that noone is hacking binaries). @@ -3280,7 +3253,14 @@ static char *QCC_PR_CheckBuiltinCompConst(char *constname, char *retbuf, size_t } if (!strcmp(constname, "__FILE__")) { + char *erk; QC_snprintfz(retbuf, retbufsize, "\"%s\"", s_filen); + erk = strchr(retbuf, ':'); + if (erk) + { + erk[0] = '\"'; + erk[1] = 0; + } return retbuf; } if (!strcmp(constname, "__LINE__")) @@ -3305,26 +3285,267 @@ static char *QCC_PR_CheckBuiltinCompConst(char *constname, char *retbuf, size_t return NULL; //didn't match } -#define PASTE2(a,b) a##b -#define PASTE(a,b) PASTE2(a,b) -#define STRINGIFY2(a) #a -#define STRINGIFY(a) STRINGIFY2(a) -#define spam(x) /*static float PASTE(spam,__LINE__);*/ if (PASTE2(spam,__LINE__) != x) {dprint(#x " chaned in " __FILE__ " on line " STRINGIFY2(__LINE__) "\n"); PASTE2(spam,__LINE__) = x;} -#define dprint printf +static pbool QCC_PR_ExpandPreProcessorMacro(CompilerConstant_t *c, char **buffer, size_t *bufferlen, size_t *buffermax) +{ + int p; + char *start; + char *starttok; + char *argsend; + int argsendline; + size_t whitestart; + char *paramoffset[MAXCONSTANTPARAMS+1]; + int param=0, extraparam=0; + int plevel=0; + pbool noargexpand; + + char *end; + char retbuf[256]; + + pr_file_p++; + QCC_PR_LexWhitespace(false); + start = pr_file_p; + while(1) + { + // handle strings correctly by ignoring them + if (*pr_file_p == '\"') + { + do { + pr_file_p++; + } while( (pr_file_p[-1] == '\\' || pr_file_p[0] != '\"') && *pr_file_p && *pr_file_p != '\n' ); + } + if (*pr_file_p == '(') + plevel++; + else if (!plevel && (*pr_file_p == ',' || *pr_file_p == ')')) + { + if (*pr_file_p == ',' && c->varg && param >= c->numparams) + extraparam++; //skip extra trailing , arguments if we're varging. + else + { + paramoffset[param++] = start; + start = pr_file_p+1; + if (*pr_file_p == ')') + { + *pr_file_p = '\0'; + pr_file_p++; + break; + } + *pr_file_p = '\0'; + pr_file_p++; + QCC_PR_LexWhitespace(false); + start = pr_file_p; + // move back by one char because we move forward by one at the end of the loop + pr_file_p--; + if (param == MAXCONSTANTPARAMS || param > c->numparams) + QCC_PR_ParseError(ERR_TOOMANYPARAMS, "Too many parameters in macro call"); + } + } else if (*pr_file_p == ')' ) + plevel--; + else if(*pr_file_p == '\n') + QCC_PR_NewLine(false); + + // see that *pr_file_p = '\0' up there? Must ++ BEFORE checking for !*pr_file_p + pr_file_p++; + if (!*pr_file_p) + QCC_PR_ParseError(ERR_EOF, "EOF on macro call"); + } + if (param < c->numparams) + QCC_PR_ParseError(ERR_TOOFEWPARAMS, "Not enough macro parameters"); + paramoffset[param] = start; + + *buffer = NULL; + *bufferlen = 0; + *buffermax = 0; + +// QCC_PR_LexWhitespace(false); + argsend = pr_file_p; + argsendline = pr_source_line; + pr_file_p = c->value; + for(;;) + { + noargexpand = false; + whitestart = *bufferlen; + starttok = pr_file_p; + /*while(qcc_iswhite(*pr_file_p)) //copy across whitespace + { + if (!*pr_file_p) + break; + pr_file_p++; + }*/ + QCC_PR_LexWhitespace(true); + if (starttok != pr_file_p) + { + QCC_PR_ExpandStrCat(buffer,bufferlen,buffermax, starttok, pr_file_p - starttok); + } + + if(*pr_file_p == '\"') + { + starttok = pr_file_p; + do + { + pr_file_p++; + } while( (pr_file_p[-1] == '\\' || pr_file_p[0] != '\"') && *pr_file_p && *pr_file_p != '\n' ); + if(*pr_file_p == '\"') + pr_file_p++; + + QCC_PR_ExpandStrCat(buffer,bufferlen,buffermax, starttok, pr_file_p - starttok); + continue; + } + else if (*pr_file_p == '#') //if you ask for #a##b you will be shot. use #a #b instead, or chain macros. + { + if (pr_file_p[1] == '#') + { //concatinate (strip out whitespace before the token) + *bufferlen = whitestart; + pr_file_p+=2; + noargexpand = true; + } + else + { //stringify + pr_file_p++; + pr_file_p = QCC_COM_Parse2(pr_file_p); + if (!pr_file_p) + break; + + for (p = 0; p < param; p++) + { + if (!STRCMP(qcc_token, c->params[p])) + { + QCC_PR_ExpandStrCat(buffer,bufferlen,buffermax, "\"", 1); + QCC_PR_ExpandStrCatMarkup(buffer,bufferlen,buffermax, paramoffset[p], strlen(paramoffset[p])); + QCC_PR_ExpandStrCat(buffer,bufferlen,buffermax, "\"", 1); + break; + } + } + if (p == param) + { + QCC_PR_ExpandStrCat(buffer,bufferlen,buffermax, "#", 1); + QCC_PR_ExpandStrCat(buffer,bufferlen,buffermax, qcc_token, strlen(qcc_token)); + if (!c->evil) + QCC_PR_ParseWarning(0, "'#' is not followed by a macro parameter in %s", c->name); + } + continue; //already did this one + } + } + + end = qcc_token; + pr_file_p = QCC_COM_Parse2(pr_file_p); + if (!pr_file_p) + break; + + for (p = 0; p < c->numparams; p++) + { + if (!STRCMP(qcc_token, c->params[p])) + { + char *argstart, *argend; + + for (start = pr_file_p; qcc_iswhite(*start); start++) + ; + if (noargexpand || (start[0] == '#' && start[1] == '#')) + QCC_PR_ExpandStrCat(buffer,bufferlen,buffermax, paramoffset[p], strlen(paramoffset[p])); + else + { + for (argstart = paramoffset[p]; *argstart; argstart = argend) + { + argend = argstart; + while (qcc_iswhite(*argend)) + argend++; + if (*argend == '\"') + { + do + { + argend++; + } while( (argend[-1] == '\\' || argend[0] != '\"') && *argend && *argend != '\n' ); + if(*argend == '\"') + argend++; + end = NULL; + } + else + { + argend = QCC_COM_Parse2(argend); + if (!argend) + break; + end = QCC_PR_CheckBuiltinCompConst(qcc_token, retbuf, sizeof(retbuf)); + } + //FIXME: we should be testing all defines instead of just built-in ones. + if (end) + QCC_PR_ExpandStrCat(buffer,bufferlen,buffermax, end, strlen(end)); + else + QCC_PR_ExpandStrCat(buffer,bufferlen,buffermax, argstart, argend-argstart); + } + } + break; + } + } + if (c->varg && !STRCMP(qcc_token, "__VA_ARGS__")) + { //c99 + if (param-1 == c->numparams) + QCC_PR_ExpandStrCat(buffer,bufferlen,buffermax, paramoffset[c->numparams], strlen(paramoffset[c->numparams])); + else if (noargexpand) + { + if(*bufferlen>0 && (*buffer)[*bufferlen-1] == ',') + *bufferlen-=1; + } + } + else if (c->varg && !STRCMP(qcc_token, "__VA_COUNT__")) + { //not c99 + char tmp[64]; + if (param < c->numparams) + QCC_PR_ParseError(ERR_TOOFEWPARAMS, "__VA_COUNT__ without any variable args"); + QC_snprintfz(tmp, sizeof(tmp), "%i", param-1+extraparam); + QCC_PR_ExpandStrCat(buffer,bufferlen,buffermax, tmp, strlen(tmp)); + } + else if (p == c->numparams) + { + /*CompilerConstant_t *c2 = pHash_Get(&compconstantstable, qcc_token); + if (c2 && c2->numparams >= 0 && *pr_file_p == '(') + { //oh dear god this is vile bullshit + char *sub = NULL; + size_t sublen; + size_t submax; + pr_file_p++; + if (QCC_PR_ExpandPreProcessorMacro(c, &sub,&sublen,&submax)) + { + QCC_PR_ExpandStrCat(buffer,bufferlen,buffermax, sub, sublen); + } + free(sub); + } + else*/ + QCC_PR_ExpandStrCat(buffer,bufferlen,buffermax, qcc_token, strlen(qcc_token)); + } + } + + for (p = 0; p < param-1; p++) + paramoffset[p][strlen(paramoffset[p])] = ','; + paramoffset[p][strlen(paramoffset[p])] = ')'; + + if (c->inside>8) + return false; + + pr_file_p = argsend; + pr_source_line = argsendline; + + if (flag_debugmacros) + { + if (flag_msvcstyle) + externs->Printf ("%s(%i) : macro %s: %s\n", s_filen, pr_source_line, c->name, pr_file_p); + else + externs->Printf ("%s:%i: macro %s: %s\n", s_filen, pr_source_line, c->name, pr_file_p); + } + return true; +} int QCC_PR_CheckCompConst(void) { + //FIXME: FOO(SPLAT(FOO(BAR))) + //the above should expand the inner foo before expanding the outer foo + char *initial_file_p = pr_file_p; int initial_line = pr_source_line; - int whitestart = 5; CompilerConstant_t *c; char *end, *tok; char retbuf[256]; -// spam(whitestart); - for (end = pr_file_p; ; end++) { if (!*end || qcc_iswhite(*end)) @@ -3355,7 +3576,7 @@ int QCC_PR_CheckCompConst(void) } QC_strnlcpy(pr_token, pr_file_p, end-pr_file_p, sizeof(pr_token)); -// printf("%s\n", pr_token); +// externs->Printf("%s\n", pr_token); c = pHash_Get(&compconstantstable, pr_token); if (c && (!currentchunk || currentchunk->cnst != c)) //macros don't expand themselves @@ -3367,229 +3588,16 @@ int QCC_PR_CheckCompConst(void) { if (*pr_file_p == '(') { - int p; - char *start; - char *starttok; - char *buffer; - char *argsend; - int argsendline; - size_t buffermax; - size_t bufferlen; - char *paramoffset[MAXCONSTANTPARAMS+1]; - int param=0, extraparam=0; - int plevel=0; - pbool noargexpand; - - pr_file_p++; - QCC_PR_LexWhitespace(false); - start = pr_file_p; - while(1) - { - // handle strings correctly by ignoring them - if (*pr_file_p == '\"') - { - do { - pr_file_p++; - } while( (pr_file_p[-1] == '\\' || pr_file_p[0] != '\"') && *pr_file_p && *pr_file_p != '\n' ); - } - if (*pr_file_p == '(') - plevel++; - else if (!plevel && (*pr_file_p == ',' || *pr_file_p == ')')) - { - if (*pr_file_p == ',' && c->varg && param >= c->numparams) - extraparam++; //skip extra trailing , arguments if we're varging. - else - { - paramoffset[param++] = start; - start = pr_file_p+1; - if (*pr_file_p == ')') - { - *pr_file_p = '\0'; - pr_file_p++; - break; - } - *pr_file_p = '\0'; - pr_file_p++; - QCC_PR_LexWhitespace(false); - start = pr_file_p; - // move back by one char because we move forward by one at the end of the loop - pr_file_p--; - if (param == MAXCONSTANTPARAMS || param > c->numparams) - QCC_PR_ParseError(ERR_TOOMANYPARAMS, "Too many parameters in macro call"); - } - } else if (*pr_file_p == ')' ) - plevel--; - else if(*pr_file_p == '\n') - QCC_PR_NewLine(false); - - // see that *pr_file_p = '\0' up there? Must ++ BEFORE checking for !*pr_file_p - pr_file_p++; - if (!*pr_file_p) - QCC_PR_ParseError(ERR_EOF, "EOF on macro call"); - } - if (param < c->numparams) - QCC_PR_ParseError(ERR_TOOFEWPARAMS, "Not enough macro parameters"); - paramoffset[param] = start; - - buffer = NULL; - bufferlen = 0; - buffermax = 0; - -// QCC_PR_LexWhitespace(false); - argsend = pr_file_p; - argsendline = pr_source_line; - pr_file_p = c->value; - for(;;) - { - noargexpand = false; - whitestart = bufferlen; - starttok = pr_file_p; - /*while(qcc_iswhite(*pr_file_p)) //copy across whitespace - { - if (!*pr_file_p) - break; - pr_file_p++; - }*/ - QCC_PR_LexWhitespace(true); - if (starttok != pr_file_p) - { - QCC_PR_ExpandStrCat(&buffer, &bufferlen, &buffermax, starttok, pr_file_p - starttok); - } - - if(*pr_file_p == '\"') - { - starttok = pr_file_p; - do - { - pr_file_p++; - } while( (pr_file_p[-1] == '\\' || pr_file_p[0] != '\"') && *pr_file_p && *pr_file_p != '\n' ); - if(*pr_file_p == '\"') - pr_file_p++; - - QCC_PR_ExpandStrCat(&buffer, &bufferlen, &buffermax, starttok, pr_file_p - starttok); - continue; - } - else if (*pr_file_p == '#') //if you ask for #a##b you will be shot. use #a #b instead, or chain macros. - { - if (pr_file_p[1] == '#') - { //concatinate (strip out whitespace before the token) - bufferlen = whitestart; - pr_file_p+=2; - noargexpand = true; - } - else - { //stringify - pr_file_p++; - pr_file_p = QCC_COM_Parse2(pr_file_p); - if (!pr_file_p) - break; - - for (p = 0; p < param; p++) - { - if (!STRCMP(qcc_token, c->params[p])) - { - QCC_PR_ExpandStrCat(&buffer, &bufferlen, &buffermax, "\"", 1); - QCC_PR_ExpandStrCatMarkup(&buffer, &bufferlen, &buffermax, paramoffset[p], strlen(paramoffset[p])); - QCC_PR_ExpandStrCat(&buffer, &bufferlen, &buffermax, "\"", 1); - break; - } - } - if (p == param) - { - QCC_PR_ExpandStrCat(&buffer, &bufferlen, &buffermax, "#", 1); - QCC_PR_ExpandStrCat(&buffer, &bufferlen, &buffermax, qcc_token, strlen(qcc_token)); - if (!c->evil) - QCC_PR_ParseWarning(0, "'#' is not followed by a macro parameter in %s", c->name); - } - continue; //already did this one - } - } - - end = qcc_token; - pr_file_p = QCC_COM_Parse2(pr_file_p); - if (!pr_file_p) - break; - - for (p = 0; p < c->numparams; p++) - { - if (!STRCMP(qcc_token, c->params[p])) - { - char *argstart, *argend; - - for (start = pr_file_p; qcc_iswhite(*start); start++) - ; - if (noargexpand || (start[0] == '#' && start[1] == '#')) - QCC_PR_ExpandStrCat(&buffer, &bufferlen, &buffermax, paramoffset[p], strlen(paramoffset[p])); - else - { - for (argstart = paramoffset[p]; *argstart; argstart = argend) - { - argend = argstart; - while (qcc_iswhite(*argend)) - argend++; - if (*argend == '\"') - { - do - { - argend++; - } while( (argend[-1] == '\\' || argend[0] != '\"') && *argend && *argend != '\n' ); - if(*argend == '\"') - argend++; - end = NULL; - } - else - { - argend = QCC_COM_Parse2(argend); - if (!argend) - break; - end = QCC_PR_CheckBuiltinCompConst(qcc_token, retbuf, sizeof(retbuf)); - } - //FIXME: we should be testing all defines instead of just built-in ones. - if (end) - QCC_PR_ExpandStrCat(&buffer, &bufferlen, &buffermax, end, strlen(end)); - else - QCC_PR_ExpandStrCat(&buffer, &bufferlen, &buffermax, argstart, argend-argstart); - } - } - break; - } - } - if (c->varg && !STRCMP(qcc_token, "__VA_ARGS__")) - { - if (param-1 == c->numparams) - QCC_PR_ExpandStrCat(&buffer, &bufferlen, &buffermax, paramoffset[c->numparams], strlen(paramoffset[c->numparams])); - else if (noargexpand) - { - if(bufferlen>0 && buffer[bufferlen-1] == ',') - bufferlen--; - } - } - else if (c->varg && !STRCMP(qcc_token, "__VA_COUNT__")) - { - char tmp[64]; - if (param < c->numparams) - QCC_PR_ParseError(ERR_TOOFEWPARAMS, "__VA_COUNT__ without any variable args"); - QC_snprintfz(tmp, sizeof(tmp), "%i", param-1+extraparam); - QCC_PR_ExpandStrCat(&buffer, &bufferlen, &buffermax, tmp, strlen(tmp)); - } - else if (p == c->numparams) - QCC_PR_ExpandStrCat(&buffer, &bufferlen, &buffermax, qcc_token, strlen(qcc_token)); - } - - for (p = 0; p < param-1; p++) - paramoffset[p][strlen(paramoffset[p])] = ','; - paramoffset[p][strlen(paramoffset[p])] = ')'; - - if (c->inside>8) + char *buffer = NULL; + size_t bufferlen, buffermax; + if (!QCC_PR_ExpandPreProcessorMacro(c, &buffer, &bufferlen, &buffermax)) { + free(buffer); pr_file_p = initial_file_p; pr_source_line = initial_line; - free(buffer); return false; } - pr_file_p = argsend; - pr_source_line = argsendline; if (!bufferlen) expandedemptymacro = true; else @@ -3599,18 +3607,11 @@ int QCC_PR_CheckCompConst(void) } expandedemptymacro = true; free(buffer); - - if (flag_debugmacros) - { - if (flag_msvcstyle) - printf ("%s(%i) : macro %s: %s\n", s_filen, pr_source_line, c->name, pr_file_p); - else - printf ("%s:%i: macro %s: %s\n", s_filen, pr_source_line, c->name, pr_file_p); - } } else { //QCC_PR_ParseError(ERR_TOOFEWPARAMS, "Macro without argument list"); + //such macros don't get expanded. pr_file_p = initial_file_p; pr_source_line = initial_line; return false; @@ -3858,7 +3859,7 @@ void QCC_PR_ParsePrintDef (int type, QCC_def_t *def) char *modifiers; if (QCC_Temp_Describe(def, tmbuffer, sizeof(tmbuffer))) { - printf ("%s:%i: (%s)(%s)\n", def->filen, def->s_line, TypeName(def->type, tybuffer, sizeof(tybuffer)), tmbuffer); + externs->Printf ("%s:%i: (%s)(%s)\n", def->filen, def->s_line, TypeName(def->type, tybuffer, sizeof(tybuffer)), tmbuffer); } else { @@ -3868,9 +3869,9 @@ void QCC_PR_ParsePrintDef (int type, QCC_def_t *def) else if (def->isstatic) modifiers = "static "; if (flag_msvcstyle) - printf ("%s%s(%i) : %s%s%s %s%s%s is defined here\n", col_location, def->filen, def->s_line, col_none, modifiers, TypeName(def->type, tybuffer, sizeof(tybuffer)), col_symbol, def->name, col_none); + externs->Printf ("%s%s(%i) : %s%s%s %s%s%s is defined here\n", col_location, def->filen, def->s_line, col_none, modifiers, TypeName(def->type, tybuffer, sizeof(tybuffer)), col_symbol, def->name, col_none); else - printf ("%s%s:%i: %s%s%s %s%s%s is defined here\n", col_location, def->filen, def->s_line, col_none, modifiers, TypeName(def->type, tybuffer, sizeof(tybuffer)), col_symbol, def->name, col_none); + externs->Printf ("%s%s:%i: %s%s%s %s%s%s is defined here\n", col_location, def->filen, def->s_line, col_none, modifiers, TypeName(def->type, tybuffer, sizeof(tybuffer)), col_symbol, def->name, col_none); } } } @@ -3889,30 +3890,30 @@ static void QCC_PR_PrintMacro (qcc_includechunk_t *chunk) if (chunk->cnst) { #if 1 - printf ("%s%s:%i: %s%s%s is defined here\n", col_location, chunk->cnst->fromfile, chunk->cnst->fromline, col_symbol, chunk->cnst->name, col_none); + externs->Printf ("%s%s:%i: macro %s%s%s is defined here\n", col_location, chunk->cnst->fromfile, chunk->cnst->fromline, col_symbol, chunk->cnst->name, col_none); #else - printf ("%s:%i: expanding %s\n", chunk->currentfilename, chunk->currentlinenumber, chunk->cnst->name); + externs->Printf ("%s:%i: expanding %s\n", chunk->currentfilename, chunk->currentlinenumber, chunk->cnst->name); #endif if (verbose) - printf ("%s\n", chunk->datastart); + externs->Printf ("%s\n", chunk->datastart); } else - printf ("%s:%i:\n", chunk->currentfilename, chunk->currentlinenumber); + externs->Printf ("%s:%i:\n", chunk->currentfilename, chunk->currentlinenumber); } } -void QCC_PR_PrintScope (void) +static void QCC_PR_PrintScope (void) { QCC_PR_PrintMacro(currentchunk); if (pr_scope) { if (errorscope != pr_scope) - printf ("in function %s%s%s (line %i),\n", col_symbol, pr_scope->name, col_none, pr_scope->line); + externs->Printf ("in function %s%s%s (line %i),\n", col_symbol, pr_scope->name, col_none, pr_scope->line); errorscope = pr_scope; } else { if (errorscope) - printf ("at global scope,\n"); + externs->Printf ("at global scope,\n"); errorscope = NULL; } } @@ -3946,9 +3947,9 @@ void VARGS QCC_PR_ParseError (int errortype, const char *error, ...) QCC_PR_PrintScope(); if (flag_msvcstyle) - printf ("%s%s(%i) : %serror%s: %s\n", col_location, s_filen, pr_source_line, col_error, col_none, string); + externs->Printf ("%s%s(%i) : %serror%s: %s\n", col_location, s_filen, pr_source_line, col_error, col_none, string); else - printf ("%s%s:%i: %serror%s: %s\n", col_location, s_filen, pr_source_line, col_error, col_none, string); + externs->Printf ("%s%s:%i: %serror%s: %s\n", col_location, s_filen, pr_source_line, col_error, col_none, string); longjmp (pr_parse_abort, 1); } @@ -3967,9 +3968,9 @@ void VARGS QCC_PR_ParseErrorPrintDef (int errortype, QCC_def_t *def, const char #endif QCC_PR_PrintScope(); if (flag_msvcstyle) - printf ("%s%s(%i) : %serror%s: %s\n", col_location, s_filen, pr_source_line, col_error, col_none, string); + externs->Printf ("%s%s(%i) : %serror%s: %s\n", col_location, s_filen, pr_source_line, col_error, col_none, string); else - printf ("%s%s:%i: %serror%s: %s\n", col_location, s_filen, pr_source_line, col_error, col_none, string); + externs->Printf ("%s%s:%i: %serror%s: %s\n", col_location, s_filen, pr_source_line, col_error, col_none, string); QCC_PR_ParsePrintDef(WARN_ERROR, def); @@ -3990,16 +3991,16 @@ void VARGS QCC_PR_ParseErrorPrintSRef (int errortype, QCC_sref_t def, const char #endif QCC_PR_PrintScope(); if (flag_msvcstyle) - printf ("%s%s(%i) : %serror%s: %s\n", col_location, s_filen, pr_source_line, col_error, col_none, string); + externs->Printf ("%s%s(%i) : %serror%s: %s\n", col_location, s_filen, pr_source_line, col_error, col_none, string); else - printf ("%s%s:%i: %serror%s: %s\n", col_location, s_filen, pr_source_line, col_error, col_none, string); + externs->Printf ("%s%s:%i: %serror%s: %s\n", col_location, s_filen, pr_source_line, col_error, col_none, string); QCC_PR_ParsePrintSRef(WARN_ERROR, def); longjmp (pr_parse_abort, 1); } -pbool VARGS QCC_PR_PrintWarning (int type, const char *file, int line, const char *string) +static pbool VARGS QCC_PR_PrintWarning (int type, const char *file, int line, const char *string) { char *wnam = QCC_NameForWarning(type); if (!wnam) @@ -4013,11 +4014,11 @@ pbool VARGS QCC_PR_PrintWarning (int type, const char *file, int line, const cha if (!string) ; else if (!file || !*file) - printf (":: %serror%s%s: %s\n", col_error, wnam, col_none, string); + externs->Printf (":: %serror%s%s: %s\n", col_error, wnam, col_none, string); else if (flag_msvcstyle) - printf ("%s%s(%i) : %serror%s%s: %s\n", col_location, file, line, col_error, wnam, col_none, string); + externs->Printf ("%s%s(%i) : %serror%s%s: %s\n", col_location, file, line, col_error, wnam, col_none, string); else - printf ("%s%s:%i: %serror%s%s: %s\n", col_location, file, line, col_error, wnam, col_none, string); + externs->Printf ("%s%s:%i: %serror%s%s: %s\n", col_location, file, line, col_error, wnam, col_none, string); pr_error_count++; } else if (qccwarningaction[type] == 2) @@ -4025,11 +4026,11 @@ pbool VARGS QCC_PR_PrintWarning (int type, const char *file, int line, const cha if (!string) ; else if (!file || !*file) - printf (":: %swerror%s%s: %s\n", col_error, wnam, col_none, string); + externs->Printf (":: %swerror%s%s: %s\n", col_error, wnam, col_none, string); else if (flag_msvcstyle) - printf ("%s%s(%i) : %swerror%s%s: %s\n", col_location, file, line, col_error, wnam, col_none, string); + externs->Printf ("%s%s(%i) : %swerror%s%s: %s\n", col_location, file, line, col_error, wnam, col_none, string); else - printf ("%s%s:%i: %swerror%s%s: %s\n", col_location, file, line, col_error, wnam, col_none, string); + externs->Printf ("%s%s:%i: %swerror%s%s: %s\n", col_location, file, line, col_error, wnam, col_none, string); pr_error_count++; } else @@ -4037,11 +4038,11 @@ pbool VARGS QCC_PR_PrintWarning (int type, const char *file, int line, const cha if (!string) ; else if (!file || !*file) - printf (":: %swarning%s%s: %s\n", col_warning, wnam, col_none, string); + externs->Printf (":: %swarning%s%s: %s\n", col_warning, wnam, col_none, string); else if (flag_msvcstyle) - printf ("%s%s(%i) : %swarning%s%s: %s\n", col_location, file, line, col_warning, wnam, col_none, string); + externs->Printf ("%s%s(%i) : %swarning%s%s: %s\n", col_location, file, line, col_warning, wnam, col_none, string); else - printf ("%s%s:%i: %swarning%s%s: %s\n", col_location, file, line, col_warning, wnam, col_none, string); + externs->Printf ("%s%s:%i: %swarning%s%s: %s\n", col_location, file, line, col_warning, wnam, col_none, string); pr_warning_count++; } return true; @@ -4094,11 +4095,11 @@ void VARGS QCC_PR_Note (int type, const char *file, int line, const char *error, QCC_PR_PrintScope(); if (!file) - printf ("note: %s\n", string); + externs->Printf ("note: %s\n", string); else if (flag_msvcstyle) - printf ("%s(%i) : note: %s\n", file, line, string); + externs->Printf ("%s(%i) : note: %s\n", file, line, string); else - printf ("%s:%i: note: %s\n", file, line, string); + externs->Printf ("%s:%i: note: %s\n", file, line, string); } @@ -4682,7 +4683,7 @@ char *TypeName(QCC_type_t *type, char *buffer, int buffersize) } //#define typecmp(a, b) (a && ((a)->type==(b)->type) && !STRCMP((a)->name, (b)->name)) -QCC_type_t *QCC_PR_FindType (QCC_type_t *type) +static QCC_type_t *QCC_PR_FindType (QCC_type_t *type) { int t; for (t = 0; t < numtypeinfos; t++) @@ -4706,8 +4707,8 @@ QCC_type_t *QCC_PR_FindType (QCC_type_t *type) return &qcc_typeinfo[t]; } } -QCC_Error(ERR_INTERNAL, "Error with type"); + type = QCC_PR_DuplicateType(type, false); return type; } /* @@ -4786,6 +4787,28 @@ char *pr_parm_argcount_name; int recursivefunctiontype; +static QCC_type_t *QCC_PR_MakeThiscall(QCC_type_t *orig, QCC_type_t *thistype) +{ + QCC_type_t ftype = *orig; + + ftype.ptrto = NULL; + ftype.typedefed = false; + ftype.num_parms++; + ftype.params = qccHunkAlloc(sizeof(*ftype.params) * ftype.num_parms); + memcpy(ftype.params+1, orig->params, sizeof(*ftype.params) * orig->num_parms); + ftype.params[0].paramname = "this"; + ftype.params[0].type = QCC_PointerTypeTo(thistype); + ftype.params[0].isvirtual = true; + + orig = QCC_PR_FindType (&ftype); + if (!orig) + { + orig = QCC_PR_NewType(ftype.name, ftype.type, false); + *orig = ftype; + } + return orig; +} + //expects a ( to have already been parsed. QCC_type_t *QCC_PR_ParseFunctionType (int newtype, QCC_type_t *returntype) { @@ -4821,6 +4844,7 @@ QCC_type_t *QCC_PR_ParseFunctionType (int newtype, QCC_type_t *returntype) foundinout = false; paramlist[numparms].optional = false; + paramlist[numparms].isvirtual = false; paramlist[numparms].out = false; while(1) @@ -4985,6 +5009,7 @@ QCC_type_t *QCC_PR_ParseFunctionTypeReacc (int newtype, QCC_type_t *returntype) paramlist[numparms].out = false; paramlist[numparms].optional = false; + paramlist[numparms].isvirtual = false; paramlist[numparms].ofs = 0; paramlist[numparms].arraysize = 0; paramlist[numparms].type = nptype; @@ -5063,6 +5088,7 @@ QCC_type_t *QCC_PR_GenFunctionType (QCC_type_t *rettype, struct QCC_typeparam_s p->type = args[i].type; p->out = args[i].out; p->optional = args[i].optional; + p->isvirtual = args[i].isvirtual; p->ofs = args[i].ofs; p->arraysize = args[i].arraysize; p->defltvalue.cast = NULL; @@ -5638,6 +5664,7 @@ QCC_type_t *QCC_PR_ParseType (int newtype, pbool silentfail) parms[numparms].ofs = 0; parms[numparms].out = false; parms[numparms].optional = false; + parms[numparms].isvirtual = isvirt; parms[numparms].paramname = parmname; parms[numparms].arraysize = arraysize; parms[numparms].type = newparm; @@ -5733,7 +5760,7 @@ QCC_type_t *QCC_PR_ParseType (int newtype, pbool silentfail) //and make sure we can do member::__fname //actually, that seems pointless. QC_snprintfz(membername, sizeof(membername), "%s::"MEMBERFIELDNAME, classname, parmname); -// printf("define %s -> %s\n", membername, d->name); +// externs->Printf("define %s -> %s\n", membername, d->name); d = QCC_PR_DummyDef(fieldtype, membername, pr_scope, arraysize, d, basicindex, true, (isnull?0:GDF_CONST)|(opt_classfields?GDF_STRIP:0)); d->referenced = true; //always referenced, so you can inherit safely. } @@ -5799,7 +5826,7 @@ QCC_type_t *QCC_PR_ParseType (int newtype, pbool silentfail) structtype = ev_struct; if (structtype != ev_void) { - struct QCC_typeparam_s *parms = NULL; + struct QCC_typeparam_s *parms = NULL, *oldparm; int numparms = 0; unsigned int arraysize; char *parmname; @@ -5811,10 +5838,30 @@ QCC_type_t *QCC_PR_ParseType (int newtype, pbool silentfail) } else { - newt = QCC_TypeForName(pr_token); + QCC_type_t *parenttype; + char *tname = QCC_PR_ParseName(); + + if (structtype == ev_struct && QCC_PR_CheckToken(":")) + { + char *parentname = QCC_PR_ParseName(); + parenttype = QCC_TypeForName(parentname); + if (!parenttype) + QCC_PR_ParseError(ERR_NOTANAME, "Parent type %s was not yet defined", parentname); + if (parenttype->type != ev_struct) + QCC_PR_ParseError(ERR_NOTANAME, "Parent type %s is not a struct", parentname); + } + else + parenttype = NULL; + + newt = QCC_TypeForName(tname); if (!newt) - newt = QCC_PR_NewType(QCC_CopyString(pr_token)+strings, ev_struct, true); - QCC_PR_Lex(); + { + newt = QCC_PR_NewType(tname, ev_struct, true); + newt->parentclass = parenttype; + } + else if (parenttype && newt->parentclass != parenttype) + QCC_PR_ParseError(ERR_NOTANAME, "Redeclaration of struct with different parent type", tname, parenttype->name); + if (newt->size) { if (QCC_PR_CheckToken("{")) @@ -5823,33 +5870,82 @@ QCC_type_t *QCC_PR_ParseType (int newtype, pbool silentfail) } //struct declaration only, not definition. - if (!QCC_PR_CheckToken("{")) + if (parenttype) + QCC_PR_Expect("{"); + else if (!QCC_PR_CheckToken("{")) return newt; } - newt->size=0; + if (newt->parentclass) + newt->size = newt->parentclass->size; + else + newt->size=0; type = NULL; - if (QCC_PR_CheckToken(",")) - QCC_PR_ParseError(ERR_NOTANAME, "element missing name"); newparm = NULL; - while (!QCC_PR_CheckToken("}")) + for (;;) { - if (QCC_PR_CheckToken(",")) + //in qc, functions are assignable references like anything else, so no modifiers means the qc will need to assign to it somewhere. + //virtual functions are still references, but we initialise them somewhere + //nonvirtual functions and static functions are kinda the same thing + pbool isnonvirt = false; + pbool isstatic = false; + pbool isvirt = false; + QCC_sref_t defaultval; + if (QCC_PR_CheckToken("}")) { + if (newparm) + QCC_PR_ParseError(ERR_EXPECTED, "missing semi-colon"); + break; + } + else if (QCC_PR_CheckToken(";")) + { + newparm = NULL; + continue; + } + else if (QCC_PR_CheckToken(",")) + { //same as last type, unless initial/after-semicolon if (!newparm) - QCC_PR_ParseError(ERR_NOTANAME, "element missing type"); + QCC_PR_ParseError(ERR_EXPECTED, "element missing type"); newparm = QCC_PR_NewType(newparm->name, newparm->type, false); } else - newparm = QCC_PR_ParseType(false, false); + { //new type! + if (newparm) + QCC_PR_ParseError(ERR_EXPECTED, "missing semi-colon"); //allow a missing semi-colon on functions, for mixed-style functions. - arraysize = 0; + if (QCC_PR_CheckKeyword(1, "public")) + /*ispublic = true*/; + else if (QCC_PR_CheckKeyword(1, "private")) + /*isprivate = true*/; + else if (QCC_PR_CheckKeyword(1, "protected")) + /*isprotected = true*/; + + if (QCC_PR_CheckKeyword(1, "nonvirtual")) + isnonvirt = true; + else if (QCC_PR_CheckKeyword(1, "static")) + isstatic = true; + else if (QCC_PR_CheckKeyword(1, "virtual")) + isvirt = true; +// else if (QCC_PR_CheckKeyword(1, "ignore")) +// isignored = true; +// else if (QCC_PR_CheckKeyword(1, "strip")) +// isignored = true; + + newparm = QCC_PR_ParseType(false, false); + } + type = newparm; while (QCC_PR_CheckToken("*")) - newparm = QCC_PointerTypeTo(newparm); + type = QCC_PointerTypeTo(type); - if (!QCC_PR_CheckToken(";")) + arraysize = 0; + if (QCC_PR_CheckToken(";")) + { //annonymous structs do weird scope stuff. + newparm = NULL; + parmname = ""; + } + else { parmname = qccHunkAlloc(strlen(pr_token)+1); strcpy(parmname, pr_token); @@ -5861,36 +5957,81 @@ QCC_type_t *QCC_PR_ParseType (int newtype, pbool silentfail) QCC_PR_ParseError(ERR_NOTANAME, "cannot cope with 0-sized arrays"); QCC_PR_Expect("]"); } - QCC_PR_CheckToken(";"); - } - else - parmname = ""; - if (newparm == newt || ((newparm->type == ev_struct || newparm->type == ev_union) && !newparm->size)) + if (QCC_PR_CheckToken("(")) + type = QCC_PR_ParseFunctionType(false, type); + } + + if (type == newt || ((type->type == ev_struct || type->type == ev_union) && !type->size)) { - QCC_PR_ParseWarning(ERR_NOTANAME, "type %s not fully defined yet", newparm->name); + QCC_PR_ParseWarning(ERR_NOTANAME, "type %s not fully defined yet", type->name); continue; } + if ((isnonvirt || isvirt) && type->type != ev_function) + QCC_PR_ParseWarning(ERR_INTERNAL, "[non]virtual members must be functions", type->name); + + //static members are technically just funny-named globals, and do not generate fields. + if (isnonvirt || isstatic || isvirt) + { //either way its a regular global. the difference being static has no implicit this/self argument. + QCC_def_t *d; + char membername[2048]; + if (!isstatic) + type = QCC_PR_MakeThiscall(type, newt); + + QC_snprintfz(membername, sizeof(membername), "%s::%s", newt->name, parmname); + d = QCC_PR_GetDef(type, membername, NULL, true, 0, (type->type==ev_function)?GDF_CONST:0); + if (QCC_PR_CheckToken("=") || (type->type == ev_function && QCC_PR_PeekToken("{"))) + QCC_PR_ParseInitializerDef(d, 0); + QCC_FreeDef(d); + if (!QCC_PR_PeekToken(",")) + newparm = NULL; + + if (isvirt) + { + defaultval.ofs = 0; + defaultval.cast = d->type; + defaultval.sym = d; + } + else + continue; + } + else + { + defaultval.cast = NULL; + if (QCC_PR_CheckToken("=")) + { + defaultval = QCC_PR_ParseDefaultInitialiser(type); + QCC_PR_ParseWarning(ERR_INTERNAL, "TODO: initialised struct members are not implemented yet", type->name); + } + } parms = realloc(parms, sizeof(*parms) * (numparms+1)); - if (structtype == ev_union) + oldparm = QCC_PR_FindStructMember(newt, parmname, &parms[numparms].ofs); + if (oldparm && oldparm->arraysize == arraysize && !typecmp_lax(oldparm->type, type)) + { + if (!isvirt) + continue; + } + else if (structtype == ev_union) { parms[numparms].ofs = 0; - if (newparm->size*(arraysize?arraysize:1) > newt->size) - newt->size = newparm->size*(arraysize?arraysize:1); + if (type->size*(arraysize?arraysize:1) > newt->size) + newt->size = type->size*(arraysize?arraysize:1); } else { parms[numparms].ofs = newt->size; - newt->size += newparm->size*(arraysize?arraysize:1); + newt->size += type->size*(arraysize?arraysize:1); } + parms[numparms].arraysize = arraysize; parms[numparms].out = false; parms[numparms].optional = false; + parms[numparms].isvirtual = isvirt; parms[numparms].paramname = parmname; - parms[numparms].type = newparm; - parms[numparms].defltvalue.cast = NULL; + parms[numparms].type = type; + parms[numparms].defltvalue = defaultval; numparms++; } if (!numparms) diff --git a/engine/qclib/qccmain.c b/engine/qclib/qccmain.c index 066839c7f..c0742d249 100644 --- a/engine/qclib/qccmain.c +++ b/engine/qclib/qccmain.c @@ -70,6 +70,7 @@ char compilingrootfile[1024]; //the .src file we started from (the current one, char qccmsourcedir[1024]; //the -src path, for #includes void QCC_PR_ResetErrorScope(void); +static void StartNewStyleCompile(void); pbool compressoutput; @@ -134,6 +135,8 @@ QCC_type_t *qcc_typeinfo; int numtypeinfos; int maxtypeinfos; +pbool preprocessonly; + struct { char *name; @@ -418,7 +421,7 @@ struct { }; -const char *QCC_VersionString(void) +static const char *QCC_VersionString(void) { #ifdef SVNVERSION if (strcmp(SVNVERSION, "-")) @@ -434,10 +437,8 @@ BspModels Runs qbsp and light on all of the models with a .bsp extension ================= */ -int QCC_CheckParm (char *check); -const char *QCC_ReadParm (char *check); -void QCC_BspModels (void) +static void QCC_BspModels (void) { /* int p; @@ -549,7 +550,7 @@ int QCC_CopyStringLength (const char *str, size_t length) return old; } -int QCC_CopyDupBackString (const char *str) +/*static int QCC_CopyDupBackString (const char *str) { size_t length; int old; @@ -568,14 +569,14 @@ int QCC_CopyDupBackString (const char *str) return old; } -void QCC_PrintStrings (void) +static void QCC_PrintStrings (void) { int i, l, j; for (i=0 ; iPrintf ("%5i : ",i); for (j=0 ; jPrintf ("\n"); } } -/*void QCC_PrintFunctions (void) +void QCC_PrintFunctions (void) { int i,j; QCC_dfunction_t *d; @@ -599,14 +600,14 @@ void QCC_PrintStrings (void) for (i=0 ; is_file, strings + d->s_name, d->first_statement, d->parm_start); + externs->Printf ("%s : %s : %i %i (", strings + d->s_file, strings + d->s_name, d->first_statement, d->parm_start); for (j=0 ; jnumparms ; j++) - printf ("%i ",d->parm_size[j]); - printf (")\n"); + externs->Printf ("%i ",d->parm_size[j]); + externs->Printf (")\n"); } }*/ -void QCC_SortFields (void) +static void QCC_SortFields (void) { int i, j; QCC_ddef32_t t; @@ -632,42 +633,42 @@ void QCC_SortFields (void) } } -void QCC_PrintFields (void) +static void QCC_PrintFields (void) { extern char *basictypenames[]; int i; QCC_ddef_t *d; - printf("Fields Listing:\n"); + externs->Printf("Fields Listing:\n"); for (i=0 ; iofs, basictypenames[d->type], strings + d->s_name); + externs->Printf ("%5i : (%s) %s\n", d->ofs, basictypenames[d->type], strings + d->s_name); } } - -void QCC_PrintGlobals (void) +/* +static void QCC_PrintGlobals (void) { int i; QCC_ddef_t *d; - printf("Globals Listing:\n"); + externs->Printf("Globals Listing:\n"); for (i=0 ; iofs, d->type, strings + d->s_name); + externs->Printf ("%5i : (%i) %s\n", d->ofs, d->type, strings + d->s_name); } -} +}*/ -void QCC_PrintAutoCvars (void) +static void QCC_PrintAutoCvars (void) { int i; QCC_ddef_t *d; char *n; - printf("Auto Cvars:\n"); + externs->Printf("Auto Cvars:\n"); for (i=0 ; itype & ~(DEF_SAVEGLOBAL|DEF_SHARED)) { case ev_float: - printf ("set %s\t%g%s%s\n", n, val->_float, desc?"\t//":"", desc?desc:""); + externs->Printf ("set %s\t%g%s%s\n", n, val->_float, desc?"\t//":"", desc?desc:""); break; case ev_vector: - printf ("set %s\t\"%g %g %g\"%s%s\n", n, val->vector[0], val->vector[1], val->vector[2], desc?"\t//":"", desc?desc:""); + externs->Printf ("set %s\t\"%g %g %g\"%s%s\n", n, val->vector[0], val->vector[1], val->vector[2], desc?"\t//":"", desc?desc:""); break; case ev_integer: - printf ("set %s\t%i%s%s\n", n, val->_int, desc?"\t//":"", desc?desc:""); + externs->Printf ("set %s\t%i%s%s\n", n, val->_int, desc?"\t//":"", desc?desc:""); break; case ev_string: - printf ("set %s\t\"%s\"%s%s\n", n, strings + val->_int, desc?"\t//":"", desc?desc:""); + externs->Printf ("set %s\t\"%s\"%s%s\n", n, strings + val->_int, desc?"\t//":"", desc?desc:""); break; default: - printf ("//set %s\t ?%s%s\n", n, desc?"\t//":"", desc?desc:""); + externs->Printf ("//set %s\t ?%s%s\n", n, desc?"\t//":"", desc?desc:""); break; } } } - printf("\n"); + externs->Printf("\n"); } -void QCC_PrintFiles (void) +static void QCC_PrintFiles (void) { struct { @@ -724,7 +725,7 @@ void QCC_PrintFiles (void) int g, i, b; pbool header; - printf("\nFile lists:\n"); + externs->Printf("\nFile lists:\n"); for (b = 0; b < 64; b++) { for (header = false, g = 0; g < sizeof(precaches)/sizeof(precaches[0]); g++) @@ -737,15 +738,15 @@ void QCC_PrintFiles (void) continue; //*-prefixed models are not real, and shouldn't be included in file lists. if (!header) { - printf("pak%i:\n", b-1); + externs->Printf("pak%i:\n", b-1); header=true; } - printf("%s\n", precaches[g].list[i].name); + externs->Printf("%s\n", precaches[g].list[i].name); } } } if (header) - printf("\n"); + externs->Printf("\n"); } } @@ -908,12 +909,12 @@ int WriteSourceFiles(qcc_cachedsourcefile_t *filelist, int h, pbool sourceaswell else ofs = 0; - printf("Embedded files take %u bytes\n", SafeSeek(h, 0, SEEK_CUR) - startofs); + externs->Printf("Embedded files take %u bytes\n", SafeSeek(h, 0, SEEK_CUR) - startofs); return ofs; } -void QCC_InitData (void) +static void QCC_InitData (void) { static char parmname[12][MAX_PARMS]; int i; @@ -949,7 +950,7 @@ void QCC_InitData (void) } } -int WriteBodylessFuncs (int handle) +static int WriteBodylessFuncs (int handle) { QCC_def_t *d; int ret=0; @@ -960,7 +961,7 @@ int WriteBodylessFuncs (int handle) if (d->type->type == ev_function && !d->scope)// function parms are ok { - if (d->initialized == 2) + if (d->isextern) { SafeWrite(handle, d->name, strlen(d->name)+1); ret++; @@ -976,7 +977,7 @@ int WriteBodylessFuncs (int handle) return ret; } -void QCC_DetermineNeededSymbols(QCC_def_t *endsyssym) +static void QCC_DetermineNeededSymbols(QCC_def_t *endsyssym) { QCC_def_t *sym = pr.def_head.next; size_t i; @@ -1023,7 +1024,7 @@ void QCC_DetermineNeededSymbols(QCC_def_t *endsyssym) const QCC_eval_t *QCC_SRef_EvalConst(QCC_sref_t ref); //allocates final space for the def, making it a true def -void QCC_FinaliseDef(QCC_def_t *def) +static void QCC_FinaliseDef(QCC_def_t *def) { //#define DEBUG_DUMP_GLOBALMAP #if defined(DEBUG_DUMP) || defined(DEBUG_DUMP_GLOBALMAP) @@ -1122,7 +1123,7 @@ void QCC_FinaliseDef(QCC_def_t *def) if (!def->symbolheader->used) { if (verbose >= VERBOSE_DEBUG) - printf("not needed: %s\n", def->name); + externs->Printf("not needed: %s\n", def->name); return; } @@ -1177,31 +1178,31 @@ void QCC_FinaliseDef(QCC_def_t *def) #ifdef DEBUG_DUMP_GLOBALMAP if (!def->referenced) - printf("Unreferenced "); + externs->Printf("Unreferenced "); sr.sym = def; sr.ofs = 0; sr.cast = def->type; v = QCC_SRef_EvalConst(sr); if (v && def->type->type == ev_float) - printf("Finalise %s(%f) @ %i+%i\n", def->name, v->_float, def->ofs, ssize); + externs->Printf("Finalise %s(%f) @ %i+%i\n", def->name, v->_float, def->ofs, ssize); else if (v && def->type->type == ev_vector) - printf("Finalise %s(%f %f %f) @ %i+%i\n", def->name, v->vector[0], v->vector[1], v->vector[2], def->ofs, ssize); + externs->Printf("Finalise %s(%f %f %f) @ %i+%i\n", def->name, v->vector[0], v->vector[1], v->vector[2], def->ofs, ssize); else if (v && def->type->type == ev_integer) - printf("Finalise %s(%i) @ %i+%i\n", def->name, v->_int, def->ofs, ssize); + externs->Printf("Finalise %s(%i) @ %i+%i\n", def->name, v->_int, def->ofs, ssize); else if (v && def->type->type == ev_function) - printf("Finalise %s(@%i) @ %i+%i\n", def->name, v->_int, def->ofs, ssize); + externs->Printf("Finalise %s(@%i) @ %i+%i\n", def->name, v->_int, def->ofs, ssize); else if (v && def->type->type == ev_field) - printf("Finalise %s(.%i) @ %i+%i\n", def->name, v->_int, def->ofs, ssize); + externs->Printf("Finalise %s(.%i) @ %i+%i\n", def->name, v->_int, def->ofs, ssize); else if (v && def->type->type == ev_string) - printf("Finalise %s(%s) @ %i+%i\n", def->name, strings+v->_int, def->ofs, ssize); + externs->Printf("Finalise %s(%s) @ %i+%i\n", def->name, strings+v->_int, def->ofs, ssize); else - printf("Finalise %s @ %i+%i\n", def->name, def->ofs, ssize); + externs->Printf("Finalise %s @ %i+%i\n", def->name, def->ofs, ssize); #endif } //marshalled locals still point to the FIRST_LOCAL range. //this function remaps all the locals back into actual usable defs. -void QCC_UnmarshalLocals(void) +static void QCC_UnmarshalLocals(void) { QCC_def_t *d; unsigned int onum, biggest, eog; @@ -1233,7 +1234,7 @@ void QCC_UnmarshalLocals(void) { onum = numpr_globals; #ifdef DEBUG_DUMP - printf("function %s locals:\n", functions[i].name); + externs->Printf("function %s locals:\n", functions[i].name); #endif for (d = functions[i].firstlocal; d; d = d->nextlocal) if (!d->isstatic && !(d->constant && d->initialized)) @@ -1241,9 +1242,9 @@ void QCC_UnmarshalLocals(void) if (verbose >= VERBOSE_DEBUG) { if (onum == numpr_globals) - printf("code: %s:%i: function %s no private locals\n", functions[i].filen, functions[i].line, functions[i].name); + externs->Printf("code: %s:%i: function %s no private locals\n", functions[i].filen, functions[i].line, functions[i].name); else - printf("code: %s:%i: function %s private locals %i-%i\n", functions[i].filen, functions[i].line, functions[i].name, onum, numpr_globals); + externs->Printf("code: %s:%i: function %s private locals %i-%i\n", functions[i].filen, functions[i].line, functions[i].name, onum, numpr_globals); } } } @@ -1264,14 +1265,14 @@ void QCC_UnmarshalLocals(void) if (verbose >= VERBOSE_DEBUG) { if (onum == numpr_globals) - printf("code: %s:%i: function %s no locals\n", functions[i].filen, functions[i].line, functions[i].name); + externs->Printf("code: %s:%i: function %s no locals\n", functions[i].filen, functions[i].line, functions[i].name); else { - printf("code: %s:%i: function %s overlapped locals %i-%i\n", functions[i].filen, functions[i].line, functions[i].name, onum, numpr_globals); + externs->Printf("code: %s:%i: function %s overlapped locals %i-%i\n", functions[i].filen, functions[i].line, functions[i].name, onum, numpr_globals); for (d = functions[i].firstlocal; d; d = d->nextlocal) { - printf("code: %s:%i: %s @%i\n", functions[i].filen, functions[i].line, d->name, d->ofs); + externs->Printf("code: %s:%i: %s @%i\n", functions[i].filen, functions[i].line, d->name, d->ofs); } } } @@ -1279,7 +1280,7 @@ void QCC_UnmarshalLocals(void) } numpr_globals = biggest; if (verbose) - printf("%i shared locals, %i private, %i total\n", biggest - onum, onum - eog, numpr_globals-eog); + externs->Printf("%i shared locals, %i private, %i total\n", biggest - onum, onum - eog, numpr_globals-eog); } static void QCC_GenerateFieldDefs(QCC_def_t *def, char *fieldname, int ofs, QCC_type_t *type) { @@ -1328,7 +1329,7 @@ static void QCC_GenerateFieldDefs(QCC_def_t *def, char *fieldname, int ofs, QCC_ dd->s_name = sname; } -const char *QCC_FileForStatement(int st) +static const char *QCC_FileForStatement(int st) { const char *ret = "???"; int i; @@ -1343,7 +1344,7 @@ const char *QCC_FileForStatement(int st) } return ret; } -const char *QCC_FunctionForStatement(int st) +static const char *QCC_FunctionForStatement(int st) { const char *ret = "???"; int i; @@ -1362,7 +1363,7 @@ const char *QCC_FunctionForStatement(int st) CompilerConstant_t *QCC_PR_CheckCompConstDefined(char *def); -pbool QCC_WriteData (int crc) +static pbool QCC_WriteData (int crc) { QCC_def_t *def; QCC_ddef_t *dd; @@ -1385,7 +1386,7 @@ pbool QCC_WriteData (int crc) if (numstatements==1 && numfunctions==1 && numglobaldefs==1 && numfielddefs==1) { - printf("nothing to write\n"); + externs->Printf("nothing to write\n"); return false; } @@ -1429,34 +1430,34 @@ pbool QCC_WriteData (int crc) case QCF_HEXEN2: case QCF_STANDARD: if (bodylessfuncs) - printf("Warning: There are some functions without bodies.\n"); + externs->Printf("Warning: There are some functions without bodies.\n"); if (bigjumps) { - printf("Forcing target to FTE32 due to large function %s\n", bigjumps); + externs->Printf("Forcing target to FTE32 due to large function %s\n", bigjumps); outputsttype = PST_FTE32; } else if (numpr_globals > 65530) { - printf("Forcing target to FTE32 due to numpr_globals\n"); + externs->Printf("Forcing target to FTE32 due to numpr_globals\n"); outputsttype = PST_FTE32; } else if (qcc_targetformat == QCF_FTEH2) { - printf("Progs execution will require FTE\n"); + externs->Printf("Progs execution will require FTE\n"); break; } else if (qcc_targetformat == QCF_HEXEN2) { - printf("Progs execution requires a Hexen2 compatible HCVM\n"); + externs->Printf("Progs execution requires a Hexen2 compatible HCVM\n"); break; } else { if (numpr_globals >= 32768) //not much of a different format. Rewrite output to get it working on original executors? - printf("Globals exceeds 32k - an enhanced QCVM will be required\n"); + externs->Printf("Globals exceeds 32k - an enhanced QCVM will be required\n"); else if (verbose) - printf("Progs should run on any QuakeC VM\n"); + externs->Printf("Progs should run on any QuakeC VM\n"); break; } qcc_targetformat = (qcc_targetformat==QCF_HEXEN2)?QCF_FTEH2:QCF_FTE; @@ -1472,12 +1473,12 @@ pbool QCC_WriteData (int crc) { if (bigjumps) { - printf("Using 32 bit target due to large function %s\n", bigjumps); + externs->Printf("Using 32 bit target due to large function %s\n", bigjumps); outputsttype = PST_FTE32; } else if (numpr_globals > 65530) { - printf("Using 32 bit target due to numpr_globals\n"); + externs->Printf("Using 32 bit target due to numpr_globals\n"); outputsttype = PST_FTE32; } } @@ -1500,29 +1501,29 @@ pbool QCC_WriteData (int crc) if (types && sizeof(char *) != sizeof(string_t)) { //qcc_typeinfo_t has a char* inside it, which changes size - printf("AMD64 builds cannot write typeinfo structures\n"); + externs->Printf("AMD64 builds cannot write typeinfo structures\n"); types = false; } if (verbose) { if (qcc_targetformat == QCF_DARKPLACES) - printf("DarkPlaces or FTE will be required\n"); + externs->Printf("DarkPlaces or FTE will be required\n"); else - printf("FTE's QCLib will be required\n"); + externs->Printf("FTE's QCLib will be required\n"); } break; case QCF_KK7: if (bodylessfuncs) - printf("Warning: There are some functions without bodies.\n"); + externs->Printf("Warning: There are some functions without bodies.\n"); if (numpr_globals > 65530) - printf("Warning: Saving is not fully supported. Ensure all engine read fields and globals are defined early on.\n"); + externs->Printf("Warning: Saving is not fully supported. Ensure all engine read fields and globals are defined early on.\n"); - printf("A KK compatible executor will be required (FTE/KK)\n"); + externs->Printf("A KK compatible executor will be required (FTE/KK)\n"); outputsttype = PST_KKQWSV; break; case QCF_QTEST: - printf("Compiled QTest progs will most likely not work at all. YOU'VE BEEN WARNED!\n"); + externs->Printf("Compiled QTest progs will most likely not work at all. YOU'VE BEEN WARNED!\n"); outputsttype = PST_QTEST; break; default: @@ -1660,8 +1661,8 @@ pbool QCC_WriteData (int crc) if (verbose >= VERBOSE_DEBUG) { - printf("code: %s:%i: func %s @%i locals@%i+%i, %i parms\n", functions[i].filen, functions[i].line, strings+funcs[i].s_name, funcs[i].first_statement, funcs[i].parm_start, funcs[i].locals, funcs[i].numparms); - printf("code: %s:%i: (%i,%i,%i,%i,%i,%i,%i,%i)\n", functions[i].filen, functions[i].line, funcs[i].parm_size[0], funcs[i].parm_size[1], funcs[i].parm_size[2], funcs[i].parm_size[3], funcs[i].parm_size[4], funcs[i].parm_size[5], funcs[i].parm_size[6], funcs[i].parm_size[7]); + externs->Printf("code: %s:%i: func %s @%i locals@%i+%i, %i parms\n", functions[i].filen, functions[i].line, strings+funcs[i].s_name, funcs[i].first_statement, funcs[i].parm_start, funcs[i].locals, funcs[i].numparms); + externs->Printf("code: %s:%i: (%i,%i,%i,%i,%i,%i,%i,%i)\n", functions[i].filen, functions[i].line, funcs[i].parm_size[0], funcs[i].parm_size[1], funcs[i].parm_size[2], funcs[i].parm_size[3], funcs[i].parm_size[4], funcs[i].parm_size[5], funcs[i].parm_size[6], funcs[i].parm_size[7]); } } funcdata = funcs; @@ -1764,7 +1765,7 @@ pbool QCC_WriteData (int crc) { optres_unreferenced++; #ifdef DEBUG_DUMP - printf("code: %s:%i: strip noref %s %s@%i;\n", def->filen, def->s_line, def->type->name, def->name, def->ofs); + externs->Printf("code: %s:%i: strip noref %s %s@%i;\n", def->filen, def->s_line, def->type->name, def->name, def->ofs); #endif continue; }*/ @@ -1772,7 +1773,7 @@ pbool QCC_WriteData (int crc) if ((def->type->type == ev_struct || def->type->type == ev_union || def->arraysize) && def->deftail) { #ifdef DEBUG_DUMP - printf("code: %s:%i: strip struct %s %s@%i;\n", def->filen, def->s_line, def->type->name, def->name, def->ofs); + externs->Printf("code: %s:%i: strip struct %s %s@%i;\n", def->filen, def->s_line, def->type->name, def->name, def->ofs); #endif //the head of an array/struct is never written. only, its member fields are. continue; @@ -1782,7 +1783,7 @@ pbool QCC_WriteData (int crc) { optres_unreferenced++; #ifdef DEBUG_DUMP - printf("code: %s:%i: strip %s %s@%i;\n", def->filen, def->s_line, def->type->name, def->name, def->ofs); + externs->Printf("code: %s:%i: strip %s %s@%i;\n", def->filen, def->s_line, def->type->name, def->name, def->ofs); #endif continue; } @@ -1806,7 +1807,7 @@ pbool QCC_WriteData (int crc) { //if it ever does self.think then it could be needed for saves. optres_stripfunctions++; //if it's only ever called explicitly, the engine doesn't need to know. #ifdef DEBUG_DUMP - printf("code: %s:%i: strip const %s %s@%i;\n", strings+def->s_file, def->s_line, def->type->name, def->name, def->ofs); + externs->Printf("code: %s:%i: strip const %s %s@%i;\n", strings+def->s_file, def->s_line, def->type->name, def->name, def->ofs); #endif continue; } @@ -1828,9 +1829,9 @@ pbool QCC_WriteData (int crc) #ifdef DEBUG_DUMP if (def->scope) - printf("code: %s:%i: strip local %s %s@%i;\n", def->filen, def->s_line, def->type->name, def->name, def->ofs); + externs->Printf("code: %s:%i: strip local %s %s@%i;\n", def->filen, def->s_line, def->type->name, def->name, def->ofs); else if (def->constant) - printf("code: %s:%i: strip const %s %s@%i;\n", def->filen, def->s_line, def->type->name, def->name, def->ofs); + externs->Printf("code: %s:%i: strip const %s %s@%i;\n", def->filen, def->s_line, def->type->name, def->name, def->ofs); #endif continue; } @@ -1868,19 +1869,19 @@ pbool QCC_WriteData (int crc) #ifdef DEBUG_DUMP if ((dd->type&~(DEF_SHARED|DEF_SAVEGLOBAL)) == ev_string) - printf("code: %s:%i: %s%s%s %s@%i = \"%s\"\n", def->filen, def->s_line, dd->type&DEF_SAVEGLOBAL?"save ":"nosave ", dd->type&DEF_SHARED?"shared ":"", basictypenames[dd->type&~(DEF_SHARED|DEF_SAVEGLOBAL)], strings+dd->s_name, dd->ofs, ((unsigned)def->symboldata[0].string>=(unsigned)strofs)?"???":(strings + def->symboldata[0].string)); + externs->Printf("code: %s:%i: %s%s%s %s@%i = \"%s\"\n", def->filen, def->s_line, dd->type&DEF_SAVEGLOBAL?"save ":"nosave ", dd->type&DEF_SHARED?"shared ":"", basictypenames[dd->type&~(DEF_SHARED|DEF_SAVEGLOBAL)], strings+dd->s_name, dd->ofs, ((unsigned)def->symboldata[0].string>=(unsigned)strofs)?"???":(strings + def->symboldata[0].string)); else if ((dd->type&~(DEF_SHARED|DEF_SAVEGLOBAL)) == ev_float) - printf("code: %s:%i: %s%s%s %s@%i = %g\n", def->filen, def->s_line, dd->type&DEF_SAVEGLOBAL?"save ":"nosave ", dd->type&DEF_SHARED?"shared ":"", basictypenames[dd->type&~(DEF_SHARED|DEF_SAVEGLOBAL)], strings+dd->s_name, dd->ofs, def->symboldata[0]._float); + externs->Printf("code: %s:%i: %s%s%s %s@%i = %g\n", def->filen, def->s_line, dd->type&DEF_SAVEGLOBAL?"save ":"nosave ", dd->type&DEF_SHARED?"shared ":"", basictypenames[dd->type&~(DEF_SHARED|DEF_SAVEGLOBAL)], strings+dd->s_name, dd->ofs, def->symboldata[0]._float); else if ((dd->type&~(DEF_SHARED|DEF_SAVEGLOBAL)) == ev_integer) - printf("code: %s:%i: %s%s%s %s@%i = %i\n", def->filen, def->s_line, dd->type&DEF_SAVEGLOBAL?"save ":"nosave ", dd->type&DEF_SHARED?"shared ":"", basictypenames[dd->type&~(DEF_SHARED|DEF_SAVEGLOBAL)], strings+dd->s_name, dd->ofs, def->symboldata[0]._int); + externs->Printf("code: %s:%i: %s%s%s %s@%i = %i\n", def->filen, def->s_line, dd->type&DEF_SAVEGLOBAL?"save ":"nosave ", dd->type&DEF_SHARED?"shared ":"", basictypenames[dd->type&~(DEF_SHARED|DEF_SAVEGLOBAL)], strings+dd->s_name, dd->ofs, def->symboldata[0]._int); else if ((dd->type&~(DEF_SHARED|DEF_SAVEGLOBAL)) == ev_vector) - printf("code: %s:%i: %s%s%s %s@%i = '%g %g %g'\n", def->filen, def->s_line, dd->type&DEF_SAVEGLOBAL?"save ":"nosave ", dd->type&DEF_SHARED?"shared ":"", basictypenames[dd->type&~(DEF_SHARED|DEF_SAVEGLOBAL)], strings+dd->s_name, dd->ofs, def->symboldata[0].vector[0], def->symboldata[0].vector[1], def->symboldata[0].vector[2]); + externs->Printf("code: %s:%i: %s%s%s %s@%i = '%g %g %g'\n", def->filen, def->s_line, dd->type&DEF_SAVEGLOBAL?"save ":"nosave ", dd->type&DEF_SHARED?"shared ":"", basictypenames[dd->type&~(DEF_SHARED|DEF_SAVEGLOBAL)], strings+dd->s_name, dd->ofs, def->symboldata[0].vector[0], def->symboldata[0].vector[1], def->symboldata[0].vector[2]); else if ((dd->type&~(DEF_SHARED|DEF_SAVEGLOBAL)) == ev_function) - printf("code: %s:%i: %s%s%s %s@%i = %i(%s)\n", def->filen, def->s_line, dd->type&DEF_SAVEGLOBAL?"save ":"nosave ", dd->type&DEF_SHARED?"shared ":"", basictypenames[dd->type&~(DEF_SHARED|DEF_SAVEGLOBAL)], strings+dd->s_name, dd->ofs, def->symboldata[0].function, def->symboldata[0].function >= numfunctions?"???":functions[def->symboldata[0].function].name); + externs->Printf("code: %s:%i: %s%s%s %s@%i = %i(%s)\n", def->filen, def->s_line, dd->type&DEF_SAVEGLOBAL?"save ":"nosave ", dd->type&DEF_SHARED?"shared ":"", basictypenames[dd->type&~(DEF_SHARED|DEF_SAVEGLOBAL)], strings+dd->s_name, dd->ofs, def->symboldata[0].function, def->symboldata[0].function >= numfunctions?"???":functions[def->symboldata[0].function].name); else if ((dd->type&~(DEF_SHARED|DEF_SAVEGLOBAL)) == ev_field) - printf("code: %s:%i: %s%s%s %s@%i = @%i\n", def->filen, def->s_line, dd->type&DEF_SAVEGLOBAL?"save ":"nosave ", dd->type&DEF_SHARED?"shared ":"", basictypenames[dd->type&~(DEF_SHARED|DEF_SAVEGLOBAL)], strings+dd->s_name, dd->ofs, def->symboldata[0]._int); + externs->Printf("code: %s:%i: %s%s%s %s@%i = @%i\n", def->filen, def->s_line, dd->type&DEF_SAVEGLOBAL?"save ":"nosave ", dd->type&DEF_SHARED?"shared ":"", basictypenames[dd->type&~(DEF_SHARED|DEF_SAVEGLOBAL)], strings+dd->s_name, dd->ofs, def->symboldata[0]._int); else - printf("code: %s:%i: %s%s%s %s@%i\n", def->filen, def->s_line, dd->type&DEF_SAVEGLOBAL?"save ":"nosave ", dd->type&DEF_SHARED?"shared ":"", basictypenames[dd->type&~(DEF_SHARED|DEF_SAVEGLOBAL)], strings+dd->s_name, dd->ofs); + externs->Printf("code: %s:%i: %s%s%s %s@%i\n", def->filen, def->s_line, dd->type&DEF_SAVEGLOBAL?"save ":"nosave ", dd->type&DEF_SHARED?"shared ":"", basictypenames[dd->type&~(DEF_SHARED|DEF_SAVEGLOBAL)], strings+dd->s_name, dd->ofs); #endif } QCC_SortFields(); @@ -1969,20 +1970,20 @@ strofs = (strofs+3)&~3; if (verbose) { - printf ("%6i strofs (of %i)\n", strofs, MAX_STRINGS); - printf ("%6i numstatements (of %i)\n", numstatements, MAX_STATEMENTS); - printf ("%6i numfunctions (of %i)\n", numfunctions, MAX_FUNCTIONS); - printf ("%6i numglobaldefs (of %i)\n", numglobaldefs, MAX_GLOBALS); - printf ("%6i numfielddefs (%i unique) (of %i)\n", numfielddefs, pr.size_fields, MAX_FIELDS); - printf ("%6i numpr_globals (of %i)\n", numpr_globals, MAX_REGS); - printf ("%6i nummodels\n", nummodels); - printf ("%6i numsounds\n", numsounds); + externs->Printf ("%6i strofs (of %i)\n", strofs, MAX_STRINGS); + externs->Printf ("%6i numstatements (of %i)\n", numstatements, MAX_STATEMENTS); + externs->Printf ("%6i numfunctions (of %i)\n", numfunctions, MAX_FUNCTIONS); + externs->Printf ("%6i numglobaldefs (of %i)\n", numglobaldefs, MAX_GLOBALS); + externs->Printf ("%6i numfielddefs (%i unique) (of %i)\n", numfielddefs, pr.size_fields, MAX_FIELDS); + externs->Printf ("%6i numpr_globals (of %i)\n", numpr_globals, MAX_REGS); + externs->Printf ("%6i nummodels\n", nummodels); + externs->Printf ("%6i numsounds\n", numsounds); } if (!*destfile) strcpy(destfile, "progs.dat"); if (verbose) - printf("Writing %s\n", destfile); + externs->Printf("Writing %s\n", destfile); h = SafeOpenWrite (destfile, 2*1024*1024); SafeWrite (h, &progs, sizeof(progs)); SafeWrite (h, "\r\n\r\n", 4); @@ -2047,7 +2048,7 @@ strofs = (strofs+3)&~3; statements32[i].c = PRLittleLong((statements[i].c.sym?statements[i].c.sym->ofs:0) + statements[i].c.ofs); if (verbose >= VERBOSE_DEBUGSTATEMENTS) - printf("code: %s:%i: @%i %s %i %i %i\n", QCC_FileForStatement(i), statements[i].linenum, i, pr_opcodes[statements[i].op].name, statements32[i].a, statements32[i].b, statements32[i].c); + externs->Printf("code: %s:%i: @%i %s %i %i %i\n", QCC_FileForStatement(i), statements[i].linenum, i, pr_opcodes[statements[i].op].name, statements32[i].a, statements32[i].b, statements32[i].c); } if (progs.blockscompressed&1) @@ -2116,11 +2117,11 @@ strofs = (strofs+3)&~3; QC_snprintfz(line, sizeof(line), "code: %s:%i: @%i %s %i %i %i (%s", QCC_FileForStatement(i), statements[i].linenum, i, pr_opcodes[statements[i].op].opname, a, b, c, QCC_VarAtOffset(statements[i].a)); QC_snprintfz(line+strlen(line), sizeof(line)-strlen(line), " %s", QCC_VarAtOffset(statements[i].b)); QC_snprintfz(line+strlen(line), sizeof(line)-strlen(line), " %s)\n", QCC_VarAtOffset(statements[i].c)); - printf("%s", line); + externs->Printf("%s", line); } #ifdef _DEBUG if (((signed)a >= (signed)numpr_globals && statements[i].a.sym) || ((signed)b >= (signed)numpr_globals && statements[i].b.sym) || ((signed)c >= (signed)numpr_globals && statements[i].c.sym)) - printf("invalid offset on %s instruction\n", pr_opcodes[statements[i].op].opname); + externs->Printf("invalid offset on %s instruction\n", pr_opcodes[statements[i].op].opname); #endif //truncate to 16bit. should probably warn if the high bits are not 0x0000 or 0xffff statements16[i].a = (unsigned short)PRLittleShort((unsigned short)a); @@ -2269,7 +2270,7 @@ strofs = (strofs+3)&~3; fields16[i].type = (unsigned short)PRLittleShort ((unsigned short)fields[i].type); if (fields[i].ofs > 0xffff) { - printf("Offset for field %s overflowed 16 bits.\n", strings+fields[i].s_name); + externs->Printf("Offset for field %s overflowed 16 bits.\n", strings+fields[i].s_name); fields16[i].ofs = 0; } else @@ -2412,11 +2413,11 @@ strofs = (strofs+3)&~3; qcc_sourcefile = NULL; if (progs.version != PROG_EXTENDEDVERSION && progs.numbodylessfuncs) - printf ("WARNING: progs format cannot handle extern functions\n"); + externs->Printf ("WARNING: progs format cannot handle extern functions\n"); if (verbose) - printf ("%6i TOTAL SIZE\n", (int)SafeSeek (h, 0, SEEK_CUR)); + externs->Printf ("%6i TOTAL SIZE\n", (int)SafeSeek (h, 0, SEEK_CUR)); progs.entityfields = pr.size_fields; @@ -2433,7 +2434,7 @@ strofs = (strofs+3)&~3; //this is a negative index due to allocation ordering with the assumption that the progs.dat was loaded on the heap directly followed by the entities. //this will NOT work in FTE, DP, QuakeForge due to entity indexes. Various other engines will likely mess up too, if they change the allocation order or sizes etc. 64bit is screwed. if (progs.blockscompressed&32) - printf("unable to write value for 'entity progs'\n"); //would not work anyway + externs->Printf("unable to write value for 'entity progs'\n"); //would not work anyway else { QCC_PR_Warning(WARN_DENORMAL, def->filen, def->s_line, "'entity progs' is non-portable and will not work across engines nor cpus."); @@ -2443,7 +2444,7 @@ strofs = (strofs+3)&~3; else { //entsize(=96)+hunk header size(=32) if (verbose) - printf("qccx hack - 'entity progs' uninitialised. Assuming 112.\n"); + externs->Printf("qccx hack - 'entity progs' uninitialised. Assuming 112.\n"); i = 112; //match qccx. } i = -(size + i); @@ -2462,7 +2463,7 @@ strofs = (strofs+3)&~3; if (!SafeClose (h)) { - printf("%sError%s while writing output %s\n", col_error, col_none, destfile); + externs->Printf("%sError%s while writing output %s\n", col_error, col_none, destfile); return false; } @@ -2473,31 +2474,31 @@ strofs = (strofs+3)&~3; switch(qcc_targetformat) { case QCF_QTEST: - printf("Compile finished: %s (qtest format)\n", destfile); + externs->Printf("Compile finished: %s (qtest format)\n", destfile); break; case QCF_KK7: - printf("Compile finished: %s (kk7 format)\n", destfile); + externs->Printf("Compile finished: %s (kk7 format)\n", destfile); break; case QCF_STANDARD: - printf("Compile finished: %s (id format)\n", destfile); + externs->Printf("Compile finished: %s (id format)\n", destfile); break; case QCF_HEXEN2: - printf("Compile finished: %s (hexen2 format)\n", destfile); + externs->Printf("Compile finished: %s (hexen2 format)\n", destfile); break; case QCF_DARKPLACES: - printf("Compile finished: %s (dp format)\n", destfile); + externs->Printf("Compile finished: %s (dp format)\n", destfile); break; case QCF_FTE: - printf("Compile finished: %s (fte format)\n", destfile); + externs->Printf("Compile finished: %s (fte format)\n", destfile); break; case QCF_FTEH2: - printf("Compile finished: %s (fteh2 format)\n", destfile); + externs->Printf("Compile finished: %s (fteh2 format)\n", destfile); break; case QCF_FTEDEBUG: - printf("Compile finished: %s (ftedbg format)\n", destfile); + externs->Printf("Compile finished: %s (ftedbg format)\n", destfile); break; default: - printf("Compile finished: %s\n", destfile); + externs->Printf("Compile finished: %s\n", destfile); break; } @@ -2527,7 +2528,7 @@ strofs = (strofs+3)&~3; if (gz) strcat(destfile, ".gz"); if (verbose) - printf("Writing %s for debugging\n", destfile); + externs->Printf("Writing %s for debugging\n", destfile); h = SafeOpenWrite (destfile, 2*1024*1024); SafeWrite (h, &lnotype, sizeof(int)); SafeWrite (h, &version, sizeof(int)); @@ -2559,7 +2560,7 @@ static void QCC_MergeStrings(char *in, unsigned int num) memcpy(strings, in, num); strofs = num; } -int QCC_MergeValidateString(int str) +static int QCC_MergeValidateString(int str) { if (str < 0 || str >= strofs) str = 0; @@ -2788,7 +2789,7 @@ void QCC_ImportProgs(const char *filename) if (numpr_globals != RESERVED_OFS) //not normally changed until after compiling QCC_Error(ERR_BADEXTENSION, "#merge used too late. It must be used before any other definitions (regs)."); - printf ("\nnote: The #merge feature is still experimental\n\n"); + externs->Printf ("\nnote: The #merge feature is still experimental\n\n"); //FIXME: find overlapped locals. strip them. merge with new ones. //FIXME: find temps. strip them. you get the idea. //FIXME: find immediates. set up hash tables for them for reuse. HAH! @@ -2835,7 +2836,7 @@ PR_String Returns a string suitable for printing (no newlines, max 60 chars length) =============== */ -char *QCC_PR_String (char *string) +static char *QCC_PR_String (char *string) { static char buf[80]; char *s; @@ -2874,7 +2875,7 @@ char *QCC_PR_String (char *string) -QCC_def_t *QCC_PR_DefForFieldOfs (gofs_t ofs) +static QCC_def_t *QCC_PR_DefForFieldOfs (gofs_t ofs) { QCC_def_t *d; @@ -3010,7 +3011,7 @@ PR_PrintOfs */ /*void QCC_PR_PrintOfs (gofs_t ofs) { - printf ("%s\n",QCC_PR_GlobalString(ofs)); + externs->Printf ("%s\n",QCC_PR_GlobalString(ofs)); }*/ /* @@ -3022,32 +3023,32 @@ PR_PrintStatement { int i; - printf ("%4i : %4i : %s ", (int)(s - statements), statement_linenums[s-statements], pr_opcodes[s->op].opname); + externs->Printf ("%4i : %4i : %s ", (int)(s - statements), statement_linenums[s-statements], pr_opcodes[s->op].opname); i = strlen(pr_opcodes[s->op].opname); for ( ; i<10 ; i++) - printf (" "); + externs->Printf (" "); if (s->op == OP_IF || s->op == OP_IFNOT) - printf ("%sbranch %i",QCC_PR_GlobalString(s->a),s->b); + externs->Printf ("%sbranch %i",QCC_PR_GlobalString(s->a),s->b); else if (s->op == OP_GOTO) { - printf ("branch %i",s->a); + externs->Printf ("branch %i",s->a); } else if ( (unsigned)(s->op - OP_STORE_F) < 6) { - printf ("%s",QCC_PR_GlobalString(s->a)); - printf ("%s", QCC_PR_GlobalStringNoContents(s->b)); + externs->Printf ("%s",QCC_PR_GlobalString(s->a)); + externs->Printf ("%s", QCC_PR_GlobalStringNoContents(s->b)); } else { if (s->a) - printf ("%s",QCC_PR_GlobalString(s->a)); + externs->Printf ("%s",QCC_PR_GlobalString(s->a)); if (s->b) - printf ("%s",QCC_PR_GlobalString(s->b)); + externs->Printf ("%s",QCC_PR_GlobalString(s->b)); if (s->c) - printf ("%s", QCC_PR_GlobalStringNoContents(s->c)); + externs->Printf ("%s", QCC_PR_GlobalStringNoContents(s->c)); } - printf ("\n"); + externs->Printf ("\n"); }*/ @@ -3091,7 +3092,7 @@ PR_BeginCompilation called before compiling a batch of files, clears the pr struct ============== */ -void QCC_PR_BeginCompilation (void *memory, int memsize) +static void QCC_PR_BeginCompilation (void *memory, int memsize) { extern int recursivefunctiontype; int i; @@ -3122,12 +3123,11 @@ void QCC_PR_BeginCompilation (void *memory, int memsize) type_function->aux_type = type_void; type_pointer = QCC_PR_NewType("__pointer", ev_pointer, false); type_integer = QCC_PR_NewType("__integer", ev_integer, true); - type_variant = QCC_PR_NewType("variant", ev_variant, true); type_variant = QCC_PR_NewType("__variant", ev_variant, true); - type_floatfield = QCC_PR_NewType("fieldfloat", ev_field, false); + type_floatfield = QCC_PR_NewType("__fieldfloat", ev_field, false); type_floatfield->aux_type = type_float; - type_pointer->aux_type = QCC_PR_NewType("pointeraux", ev_float, false); + type_pointer->aux_type = QCC_PR_NewType("__pointeraux", ev_float, false); type_intpointer = QCC_PR_NewType("__intpointer", ev_pointer, false); type_intpointer->aux_type = type_integer; @@ -3138,8 +3138,13 @@ void QCC_PR_BeginCompilation (void *memory, int memsize) //type_field->aux_type = type_float; - type_integer = QCC_PR_NewType("integer", ev_integer, keyword_integer?true:false); - type_integer = QCC_PR_NewType("int", ev_integer, keyword_integer?true:false); +// QCC_PR_NewType("_Bool", ev_boolean, true); +// QCC_PR_NewType("bool", ev_boolean, true); +// QCC_PR_NewType("__int", ev_integer, keyword_integer?true:false); + + QCC_PR_NewType("variant", ev_variant, true); + QCC_PR_NewType("integer", ev_integer, keyword_integer?true:false); + QCC_PR_NewType("int", ev_integer, keyword_integer?true:false); @@ -3170,7 +3175,7 @@ void QCC_PR_BeginCompilation (void *memory, int memsize) QCC_PrioritiseOpcodes(); } -void QCC_PR_FinishFieldDef(QCC_def_t *d) +static void QCC_PR_FinishFieldDef(QCC_def_t *d) { int i; if (d->symboldata) @@ -3199,7 +3204,7 @@ called after all files are compiled to check for errors Returns false if errors were detected. ============== */ -int QCC_PR_FinishCompilation (void) +static int QCC_PR_FinishCompilation (void) { QCC_def_t *d; QCC_type_t *t; @@ -3222,9 +3227,17 @@ int QCC_PR_FinishCompilation (void) QCC_PR_FinishFieldDef(d); if (d->type->type == ev_function && d->constant)// function parms are ok { -// f = G_FUNCTION(d->ofs); -// if (!f || (!f->code && !f->builtin) ) - if (d->initialized==0) + if (d->isextern) + { + if (!externokay) + { + QCC_PR_Warning(ERR_NOFUNC, d->filen, d->s_line, "extern is not supported with this target format",d->name); + QCC_PR_ParsePrintDef(ERR_NOFUNC, d); + errors = true; + } + bodylessfuncs = true; + } + if (!d->initialized) { if (!strncmp(d->name, "ArrayGet*", 9)) { @@ -3259,16 +3272,6 @@ int QCC_PR_FinishCompilation (void) bodylessfuncs = true; errors = true; } - else if (d->initialized==2) - { - if (!externokay) - { - QCC_PR_Warning(ERR_NOFUNC, d->filen, d->s_line, "extern is not supported with this target format",d->name); - QCC_PR_ParsePrintDef(ERR_NOFUNC, d); - errors = true; - } - bodylessfuncs = true; - } } } pr_scope = NULL; @@ -3324,20 +3327,20 @@ static unsigned short QCC_crctable[256] = 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0 }; -void QCC_CRC_Init(unsigned short *crcvalue) +static void QCC_CRC_Init(unsigned short *crcvalue) { *crcvalue = CRC_INIT_VALUE; } -void QCC_CRC_ProcessByte(unsigned short *crcvalue, qbyte data) +static void QCC_CRC_ProcessByte(unsigned short *crcvalue, qbyte data) { *crcvalue = ((*crcvalue << 8) ^ QCC_crctable[(*crcvalue >> 8) ^ data]) & 0xffff; } -unsigned short QCC_CRC_Value(unsigned short crcvalue) +/*static unsigned short QCC_CRC_Value(unsigned short crcvalue) { return crcvalue ^ CRC_XOR_VALUE; -} +}*/ //============================================================================= @@ -3390,7 +3393,7 @@ static void Add_CrcOnly(char *p, unsigned short *crc, char *file) } #define EAT_CRC(p) Add_CrcOnly(p, &crc, file) -unsigned short QCC_PR_WriteProgdefs (char *filename) +static unsigned short QCC_PR_WriteProgdefs (char *filename) { #define ADD_ONLY(p) QC_strlcat(file, p, sizeof(file)) //no crc (later changes) char file[PROGDEFS_MAX_SIZE]; @@ -3528,7 +3531,7 @@ unsigned short QCC_PR_WriteProgdefs (char *filename) if (QCC_CheckParm("-progdefs")) { - printf ("writing %s\n", filename); + externs->Printf ("writing %s\n", filename); f = SafeOpenWrite(filename, 16384); SafeWrite(f, file, strlen(file)); SafeClose(f); @@ -3544,45 +3547,45 @@ unsigned short QCC_PR_WriteProgdefs (char *filename) break; case 54730: if (verbose) - printf("Recognised progs as QuakeWorld\n"); + externs->Printf("Recognised progs as QuakeWorld\n"); break; case 5927: if (verbose) - printf("Recognised progs as NetQuake server gamecode\n"); + externs->Printf("Recognised progs as NetQuake server gamecode\n"); break; case 26940: if (verbose) - printf("Recognised progs as Quake pre-release...\n"); + externs->Printf("Recognised progs as Quake pre-release...\n"); break; case 38488: if (verbose) - printf("Recognised progs as original Hexen2\n"); + externs->Printf("Recognised progs as original Hexen2\n"); break; case 26905: if (verbose) - printf("Recognised progs as Hexen2 Mission Pack\n"); + externs->Printf("Recognised progs as Hexen2 Mission Pack\n"); break; case 14046: if (verbose) - printf("Recognised progs as Hexen2 (demo)\n"); + externs->Printf("Recognised progs as Hexen2 (demo)\n"); break; case 22390: //EXT_CSQC_1 if (verbose) - printf("Recognised progs as an EXT_CSQC_1 module\n"); + externs->Printf("Recognised progs as an EXT_CSQC_1 module\n"); break; case 17105: case 32199: //outdated ext_csqc QCC_PR_Warning(WARN_SYSTEMCRC2, NULL, 0, "Recognised progs as outdated CSQC module\n"); break; case 52195: //this is what DP requires. don't print it as the warning that it is as that would royally piss off xonotic and their use of -Werror. - printf("Recognised progs as DP-specific CSQC module\n"); + externs->Printf("Recognised progs as DP-specific CSQC module\n"); break; case 10020: if (verbose) - printf("Recognised progs as a DP/FTE Menu module\n"); + externs->Printf("Recognised progs as a DP/FTE Menu module\n"); break; case 32401: @@ -3611,7 +3614,7 @@ unsigned short QCC_PR_WriteProgdefs (char *filename) QCC_Error (ERR_NOFUNC, "No function named \"%s\"", name); df = functions + i; - printf ("Statements for function %s:\n", name); + externs->Printf ("Statements for function %s:\n", name); ds = statements + df->first_statement; while (1) { @@ -3648,7 +3651,7 @@ void QCC_PrintOfs(unsigned int ofs) if (printfunc) { QCC_PrintFunction(strings + functions[i].s_name); - printf(" \n \n"); + externs->Printf(" \n \n"); } } @@ -3662,37 +3665,9 @@ DIRECTORY COPYING / PACKFILE CREATION ============================================================================== */ -packfile_t pfiles[4096], *pf; -int packhandle; -int packbytes; - - -/* -============ -CreatePath -============ -*/ -void QCC_CreatePath (char *path) -{ - /* - char *ofs; - - for (ofs = path+1 ; *ofs ; ofs++) - { - if (*ofs == '/') - { // create the directory - *ofs = 0; -#ifdef QCC - mkdir(path); -#else - QCC_mkdir (path); -#endif - *ofs = '/'; - } - } - */ -} - +static packfile_t pfiles[4096], *pf; +static int packhandle; +static int packbytes; /* =========== @@ -3701,7 +3676,7 @@ PackFile Copy a file into the pak file =========== */ -void QCC_PackFile (char *src, char *name) +static void QCC_PackFile (char *src, char *name) { size_t remaining; #if 1 @@ -3720,7 +3695,7 @@ void QCC_PackFile (char *src, char *name) f = FS_ReadToMem(src, &remaining); if (!f) { - printf ("%64s : %7s\n", name, ""); + externs->Printf ("%64s : %7s\n", name, ""); // QCC_Error("Failed to open file %s", src); return; } @@ -3728,7 +3703,7 @@ void QCC_PackFile (char *src, char *name) pf->filepos = PRLittleLong (SafeSeek (packhandle, 0, SEEK_CUR)); pf->filelen = PRLittleLong (remaining); strcpy (pf->name, name); - printf ("%64s : %7u\n", pf->name, (unsigned int)remaining); + externs->Printf ("%64s : %7u\n", pf->name, (unsigned int)remaining); packbytes += remaining; @@ -3742,7 +3717,7 @@ void QCC_PackFile (char *src, char *name) pf->filepos = PRLittleLong (lseek (packhandle, 0, SEEK_CUR)); pf->filelen = PRLittleLong (remaining); strcpy (pf->name, name); - printf ("%64s : %7u\n", pf->name, (unsigned int)remaining); + externs->Printf ("%64s : %7u\n", pf->name, (unsigned int)remaining); packbytes += remaining; @@ -3770,7 +3745,7 @@ CopyFile Copies a file, creating any directories needed =========== */ -void QCC_CopyFile (char *src, char *dest) +static void QCC_CopyFile (char *src, char *dest) { /* int in, out; @@ -3808,7 +3783,7 @@ CopyFiles =========== */ -void _QCC_CopyFiles (int blocknum, int copytype, char *srcdir, char *destdir) +static void _QCC_CopyFiles (int blocknum, int copytype, char *srcdir, char *destdir) { int i; int dirlen; @@ -3915,11 +3890,11 @@ void _QCC_CopyFiles (int blocknum, int copytype, char *srcdir, char *destdir) QCC_CRC_ProcessByte (&crc, ((qbyte *)pfiles)[i]); i = pf - pfiles; - printf ("%i files packed in %i bytes (%i crc)\n",i, packbytes, crc); + externs->Printf ("%i files packed in %i bytes (%i crc)\n",i, packbytes, crc); } } -void QCC_CopyFiles (void) +static void QCC_CopyFiles (void) { char *s; char srcdir[1024], destdir[1024]; @@ -3928,13 +3903,13 @@ void QCC_CopyFiles (void) if (verbose) { if (numsounds > 0) - printf ("%3i unique precache_sounds\n", numsounds); + externs->Printf ("%3i unique precache_sounds\n", numsounds); if (nummodels > 0) - printf ("%3i unique precache_models\n", nummodels); + externs->Printf ("%3i unique precache_models\n", nummodels); if (numtextures > 0) - printf ("%3i unique precache_textures\n", numtextures); + externs->Printf ("%3i unique precache_textures\n", numtextures); if (numfiles > 0) - printf ("%3i unique precache_files\n", numfiles); + externs->Printf ("%3i unique precache_files\n", numfiles); } p = QCC_CheckParm ("-copy"); @@ -3994,7 +3969,7 @@ void QCC_CopyFiles (void) #define WINDOWSARG(x) false #endif -void QCC_PR_CommandLinePrecompilerOptions (void) +static void QCC_PR_CommandLinePrecompilerOptions (void) { CompilerConstant_t *cnst; int i, j, p; @@ -4040,6 +4015,8 @@ void QCC_PR_CommandLinePrecompilerOptions (void) } else if ( !strcmp(myargv[i], "-qc") ) QCC_PR_Warning(0, NULL, WARN_BADPARAMS, "Argument %s is experimental", myargv[i]); //compile without linking. output cannot be read by engines. + else if ( !strcmp(myargv[i], "-E") ) + QCC_PR_Warning(0, NULL, WARN_BADPARAMS, "Argument %s is experimental", myargv[i]); //preprocess only else if ( !strcmp(myargv[i], "-progdefs") ) ; //write progdefs.h else if ( !strcmp(myargv[i], "-copy") ) @@ -4374,7 +4351,7 @@ void QCC_PR_CommandLinePrecompilerOptions (void) } else if ( !strcmp(myargv[i], "--version") ) { - printf("%s\n", QCC_VersionString()); + externs->Printf("%s\n", QCC_VersionString()); exit(EXIT_SUCCESS); } else if (*myargv[i] == '-' || WINDOWSARG(*myargv[i] == '/')) @@ -4413,7 +4390,7 @@ void SetEndian(void); -void QCC_SetDefaultProperties (void) +static void QCC_SetDefaultProperties (void) { int level; int i; @@ -4532,7 +4509,7 @@ void QCC_SetDefaultProperties (void) //builds a list of files, pretends that they came from a progs.src //FIXME: use sourcedir! -int QCC_FindQCFiles(const char *sourcedir) +static int QCC_FindQCFiles(const char *sourcedir) { #ifdef _WIN32 WIN32_FIND_DATA fd; @@ -4559,7 +4536,7 @@ int QCC_FindQCFiles(const char *sourcedir) } while(FindNextFile(h, &fd)!=0); FindClose(h); #else - printf("-Facc is not supported on this platform. Please make a progs.src file instead\n"); + externs->Printf("-Facc is not supported on this platform. Please make a progs.src file instead\n"); #endif //Sort alphabetically. @@ -4590,7 +4567,7 @@ int QCC_FindQCFiles(const char *sourcedir) } -void QCC_GenerateRelativePath(char *dest, size_t destsize, char *base, char *relative) +static void QCC_GenerateRelativePath(char *dest, size_t destsize, char *base, char *relative) { int p; char *s1, *s2; @@ -4777,7 +4754,7 @@ pbool QCC_main (int argc, char **argv) //as part of the quake engine else if (!s) break; else - printf("Bad token in qcc.cfg file\n"); + externs->Printf("Bad token in qcc.cfg file\n"); } } /* don't try to be clever @@ -4893,24 +4870,24 @@ memset(pr_immediate_string, 0, sizeof(pr_immediate_string)); if ( QCC_CheckParm ("/?") || QCC_CheckParm ("?") || QCC_CheckParm ("-?") || QCC_CheckParm ("-help") || QCC_CheckParm ("--help")) { - printf ("qcc looks for progs.src in the current directory.\n"); - printf ("to look in a different directory: qcc -src \n"); -// printf ("to build a clean data tree: qcc -copy \n"); -// printf ("to build a clean pak file: qcc -pak \n"); -// printf ("to bsp all bmodels: qcc -bspmodels \n"); - printf ("-Fwasm causes FTEQCC to dump all asm to qc.asm\n"); - printf ("-O0 to disable optimisations\n"); - printf ("-O1 to optimise for size\n"); - printf ("-O2 to optimise more - some behaviours may change\n"); - printf ("-O3 to optimise lots - experimental or non-future-proof\n"); - printf ("-Oname to enable an optimisation\n"); - printf ("-Ono-name to disable optimisations\n"); - printf ("-Kkeyword to activate keyword\n"); - printf ("-Kno-keyword to disable keyword\n"); - printf ("-Wall to give a stupid number of warnings\n"); - printf ("-Ttarget to set a output format\n"); - printf ("-Fautoproto to enable automatic prototyping\n"); - printf ("-Fsubscope to make locals specific to their subscope\n"); + externs->Printf ("qcc looks for progs.src in the current directory.\n"); + externs->Printf ("to look in a different directory: qcc -src \n"); +// externs->Printf ("to build a clean data tree: qcc -copy \n"); +// externs->Printf ("to build a clean pak file: qcc -pak \n"); +// externs->Printf ("to bsp all bmodels: qcc -bspmodels \n"); + externs->Printf ("-Fwasm causes FTEQCC to dump all asm to qc.asm\n"); + externs->Printf ("-O0 to disable optimisations\n"); + externs->Printf ("-O1 to optimise for size\n"); + externs->Printf ("-O2 to optimise more - some behaviours may change\n"); + externs->Printf ("-O3 to optimise lots - experimental or non-future-proof\n"); + externs->Printf ("-Oname to enable an optimisation\n"); + externs->Printf ("-Ono-name to disable optimisations\n"); + externs->Printf ("-Kkeyword to activate keyword\n"); + externs->Printf ("-Kno-keyword to disable keyword\n"); + externs->Printf ("-Wall to give a stupid number of warnings\n"); + externs->Printf ("-Ttarget to set a output format\n"); + externs->Printf ("-Fautoproto to enable automatic prototyping\n"); + externs->Printf ("-Fsubscope to make locals specific to their subscope\n"); qcc_compileactive = false; return true; @@ -4918,7 +4895,7 @@ memset(pr_immediate_string, 0, sizeof(pr_immediate_string)); if (flag_caseinsensitive) { - printf("Compiling without case sensitivity\n"); + externs->Printf("Compiling without case sensitivity\n"); pHash_Get = &Hash_GetInsensitive; pHash_GetNext = &Hash_GetNextInsensitive; pHash_Add = &Hash_AddInsensitive; @@ -4926,7 +4903,7 @@ memset(pr_immediate_string, 0, sizeof(pr_immediate_string)); } if (*qccmsourcedir) - printf ("Source directory: %s\n", qccmsourcedir); + externs->Printf ("Source directory: %s\n", qccmsourcedir); QCC_InitData (); @@ -4991,12 +4968,12 @@ memset(pr_immediate_string, 0, sizeof(pr_immediate_string)); } if (currentsourcefile) - printf("-------------------------------------\n"); + externs->Printf("-------------------------------------\n"); else - printf("%s\n", QCC_VersionString()); + externs->Printf("%s\n", QCC_VersionString()); QC_snprintfz (qccmprogsdat, sizeof(qccmprogsdat), "%s%s", qccmsourcedir, sourcefileslist[currentsourcefile++]); - printf ("Source file: %s\n", qccmprogsdat); + externs->Printf ("Source file: %s\n", qccmprogsdat); QC_strlcpy(compilingrootfile, qccmprogsdat, sizeof(compilingrootfile)); if (QCC_LoadFile (qccmprogsdat, (void *)&qccmsrc) == -1) @@ -5016,8 +4993,19 @@ memset(pr_immediate_string, 0, sizeof(pr_immediate_string)); #endif newstylesource = false; - pr_file_p = QCC_COM_Parse(qccmsrc); + if (qccmsrc[0] == '#' && qccmsrc[1] == '!') + qccmsrc = strchr(qccmsrc, '\n'); //ignore the first line if it starts with a #! for unix scripts. because we can. + compilingfile = qccmprogsdat; + preprocessonly = false; + if (QCC_CheckParm ("-E")) + { + pr_file_p = qccmsrc; + preprocessonly = true; + goto newstyle; + } + + pr_file_p = QCC_COM_Parse(qccmsrc); if (QCC_CheckParm ("-qc")) { strcpy(destfile, qccmprogsdat); @@ -5031,10 +5019,8 @@ memset(pr_immediate_string, 0, sizeof(pr_immediate_string)); goto newstyle; } - compilingfile = qccmprogsdat; if (*qcc_token == '#') { - void StartNewStyleCompile(void); newstyle: if (flag_filetimes) QCC_PR_Warning(0, qccmsrc, 0, "-ffiletimes unsupported with this input"); @@ -5077,14 +5063,14 @@ newstyle: { if (stat(qcc_token, &s) == -1 || s.st_mtime > os.st_mtime) { - printf("%s changed\n", qcc_token); + externs->Printf("%s changed\n", qcc_token); modified = true; break; } } if (!modified) { - printf("No changes\n"); + externs->Printf("No changes\n"); qcc_compileactive = false; return true; } @@ -5095,7 +5081,7 @@ newstyle: } } - printf ("outputfile: %s\n", destfile); + externs->Printf ("outputfile: %s\n", destfile); pr_dumpasm = false; @@ -5109,7 +5095,6 @@ void new_QCC_ContinueCompile(void); //called between exe frames - won't loose net connection (is the theory)... void QCC_ContinueCompile(void) { - currentchunk = NULL; if (!qcc_compileactive) //HEY! return; @@ -5212,10 +5197,10 @@ void QCC_ContinueCompile(void) QCC_GenerateRelativePath(qccmfilename, sizeof(qccmfilename), compilingrootfile, qcc_token); if (autoprototype) - printf ("prototyping %s\n", qccmfilename); + externs->Printf ("prototyping %s\n", qccmfilename); else { - printf ("compiling %s\n", qccmfilename); + externs->Printf ("compiling %s\n", qccmfilename); } QCC_LoadFile (qccmfilename, (void *)&qccmsrc2); @@ -5287,61 +5272,61 @@ void QCC_FinishCompile(void) { if (verbose) { - printf ("Compile Complete\n\n"); + externs->Printf ("Compile Complete\n\n"); if (optres_shortenifnots) - printf("optres_shortenifnots %i\n", optres_shortenifnots); + externs->Printf("optres_shortenifnots %i\n", optres_shortenifnots); if (optres_overlaptemps) - printf("optres_overlaptemps %i\n", optres_overlaptemps); + externs->Printf("optres_overlaptemps %i\n", optres_overlaptemps); if (optres_noduplicatestrings) - printf("optres_noduplicatestrings %i\n", optres_noduplicatestrings); + externs->Printf("optres_noduplicatestrings %i\n", optres_noduplicatestrings); if (optres_constantarithmatic) - printf("optres_constantarithmatic %i\n", optres_constantarithmatic); + externs->Printf("optres_constantarithmatic %i\n", optres_constantarithmatic); if (optres_nonvec_parms) - printf("optres_nonvec_parms %i\n", optres_nonvec_parms); + externs->Printf("optres_nonvec_parms %i\n", optres_nonvec_parms); if (optres_constant_names) - printf("optres_constant_names %i\n", optres_constant_names); + externs->Printf("optres_constant_names %i\n", optres_constant_names); if (optres_constant_names_strings) - printf("optres_constant_names_strings %i\n", optres_constant_names_strings); + externs->Printf("optres_constant_names_strings %i\n", optres_constant_names_strings); if (optres_precache_file) - printf("optres_precache_file %i\n", optres_precache_file); + externs->Printf("optres_precache_file %i\n", optres_precache_file); if (optres_filenames) - printf("optres_filenames %i\n", optres_filenames); + externs->Printf("optres_filenames %i\n", optres_filenames); if (optres_assignments) - printf("optres_assignments %i\n", optres_assignments); + externs->Printf("optres_assignments %i\n", optres_assignments); if (optres_unreferenced) - printf("optres_unreferenced %i\n", optres_unreferenced); + externs->Printf("optres_unreferenced %i\n", optres_unreferenced); if (optres_locals) - printf("optres_locals %i\n", optres_locals); + externs->Printf("optres_locals %i\n", optres_locals); if (optres_function_names) - printf("optres_function_names %i\n", optres_function_names); + externs->Printf("optres_function_names %i\n", optres_function_names); if (optres_dupconstdefs) - printf("optres_dupconstdefs %i\n", optres_dupconstdefs); + externs->Printf("optres_dupconstdefs %i\n", optres_dupconstdefs); if (optres_return_only) - printf("optres_return_only %i\n", optres_return_only); + externs->Printf("optres_return_only %i\n", optres_return_only); if (optres_compound_jumps) - printf("optres_compound_jumps %i\n", optres_compound_jumps); + externs->Printf("optres_compound_jumps %i\n", optres_compound_jumps); // if (optres_comexprremoval) - // printf("optres_comexprremoval %i\n", optres_comexprremoval); + // externs->Printf("optres_comexprremoval %i\n", optres_comexprremoval); if (optres_stripfunctions) - printf("optres_stripfunctions %i\n", optres_stripfunctions); + externs->Printf("optres_stripfunctions %i\n", optres_stripfunctions); if (optres_locals_overlapping) - printf("optres_locals_overlapping %i\n", optres_locals_overlapping); + externs->Printf("optres_locals_overlapping %i\n", optres_locals_overlapping); if (optres_logicops) - printf("optres_logicops %i\n", optres_logicops); + externs->Printf("optres_logicops %i\n", optres_logicops); if (optres_inlines) - printf("optres_inlines %i\n", optres_inlines); + externs->Printf("optres_inlines %i\n", optres_inlines); if (optres_test1) - printf("optres_test1 %i\n", optres_test1); + externs->Printf("optres_test1 %i\n", optres_test1); if (optres_test2) - printf("optres_test2 %i\n", optres_test2); + externs->Printf("optres_test2 %i\n", optres_test2); - printf("numtemps %u\n", (unsigned)tempsused); + externs->Printf("numtemps %u\n", (unsigned)tempsused); } if (!flag_msvcstyle) - printf("Done. %i warnings\n", pr_warning_count); + externs->Printf("Done. %i warnings\n", pr_warning_count); } qcc_compileactive = false; @@ -5357,7 +5342,7 @@ extern int pr_source_line; -void StartNewStyleCompile(void) +static void StartNewStyleCompile(void) { char *tmp; if (setjmp(pr_parse_abort)) @@ -5455,6 +5440,29 @@ void new_QCC_ContinueCompile(void) pr_scope = NULL; // outside all functions + if (preprocessonly) + { + pbool white = false; + static int line = 1; + while(pr_token_type != tt_eof) + { + //if there's whitespace next, make sure we represent that + if (line < pr_token_line) + { //keep line numbers correct by splurging multiple newlines. + while(line++ < pr_source_line) + externs->Printf("\n"); + } + else if (white) + externs->Printf(" "); + + externs->Printf("%s", pr_token); + white = (qcc_iswhite(*pr_file_p) || (*pr_file_p == '/' && (pr_file_p[1] == '/' || pr_file_p[1] == '*'))); + QCC_PR_Lex(); + } + QCC_PR_Lex(); + return; + } + QCC_PR_ParseDefs (NULL, false); } @@ -5502,7 +5510,7 @@ void new_QCC_ContinueCompile(void) break; } // strcat (qccmfilename, s); -// printf ("compiling %s\n", qccmfilename); +// externs->Printf ("compiling %s\n", qccmfilename); // QCC_LoadFile (qccmfilename, (void *)&qccmsrc2); // if (!new_QCC_PR_CompileFile (qccmsrc2, qccmfilename) ) diff --git a/engine/server/pr_cmds.c b/engine/server/pr_cmds.c index c1a3dc1a2..f39d29c9d 100644 --- a/engine/server/pr_cmds.c +++ b/engine/server/pr_cmds.c @@ -187,6 +187,51 @@ progparms_t svprogparms; progstype_t progstype; +static struct +{ + const char *fieldname; + unsigned int bit; + int offset; //((float*)ent->v)[offset] = buttonpressed; or -1 +} buttonfields[] = +{ + //0,1,2 are handled specially, because they're always defined in qc (and button1 is hacky). + {"button3", 2}, + {"button4", 3}, + {"button5", 4}, + {"button6", 5}, + {"button7", 6}, + {"button8", 7}, + + //and for dp compat (these names are fucked, yes) + {"buttonuse", 8}, + {"buttonchat", 9}, + {"cursor_active", 10}, + {"button9", 11}, + {"button10", 12}, + {"button11", 13}, + {"button12", 14}, + {"button13", 15}, + + {"button14", 16}, + {"button15", 17}, + {"button16", 18}, +/* {"button17", 19}, + {"button18", 20}, + {"button19", 21}, + {"button20", 22}, + {"button21", 23}, + + {"button22", 24}, + {"button23", 25}, + {"button24", 26}, + {"button25", 27}, + {"button26", 28}, + {"button27", 29}, + {"button28", 30}, + {"button29", 31}, +*/ +}; + void PR_RegisterFields(void); void PR_ResetBuiltins(progstype_t type); @@ -492,6 +537,9 @@ static pbool PDECL SV_BadField(pubprogfuncs_t *inst, edict_t *foo, const char *k void PR_SV_FillWorldGlobals(world_t *w) { + unsigned int i; + for (i = 0; i < countof(buttonfields); i++) + buttonfields[i].offset = -1; w->g.self = pr_global_ptrs->self; w->g.other = pr_global_ptrs->other; w->g.force_retouch = pr_global_ptrs->force_retouch; @@ -1198,6 +1246,15 @@ static progsnum_t AddProgs(const char *name) PR_ResetBuiltins(progstype); } + for (i = 0; i < countof(buttonfields); i++) + { + eval_t *val = svprogfuncs->GetEdictFieldValue(svprogfuncs, (edict_t*)sv.world.edicts, buttonfields[i].fieldname, ev_float, NULL); + if (val) + buttonfields[i].offset = (float*)val - (float*)sv.world.edicts->v; + else + buttonfields[i].offset = -1; + } + if ((f = PR_FindFunction (svprogfuncs, "VersionChat", num ))) { pr_globals = PR_globals(svprogfuncs, num); @@ -5586,14 +5643,14 @@ void SV_point_tempentity (vec3_t o, int type, int count) //count (usually 1) is case TE_BULLET: qwtype[1] = TE_SPIKE; #ifdef NQPROT - qwtype[1] = qwtype[0] = TE_SPIKE; + nqtype[1] = nqtype[0] = TE_SPIKE; #endif split = PEXT_TE_BULLET; break; case TEQW_SUPERBULLET: qwtype[1] = TE_SUPERSPIKE; #ifdef NQPROT - qwtype[1] = qwtype[0] = TE_SUPERSPIKE; + nqtype[1] = nqtype[0] = TE_SUPERSPIKE; #endif split = PEXT_TE_BULLET; break; @@ -5618,8 +5675,8 @@ void SV_point_tempentity (vec3_t o, int type, int count) //count (usually 1) is #ifdef NQPROT nqtype[0] = TENQ_QWEXPLOSION; nqtype[1] = TENQ_NQEXPLOSION; -#endif split = PEXT_TE_BULLET; +#endif break; case TEQW_NQEXPLOSION: qwtype[0] = TEQW_NQEXPLOSION; @@ -5662,7 +5719,7 @@ void SV_point_tempentity (vec3_t o, int type, int count) //count (usually 1) is MSG_WriteChar (&sv.nqmulticast, 0); MSG_WriteChar (&sv.nqmulticast, 0); MSG_WriteChar (&sv.nqmulticast, 0); - MSG_WriteByte (&sv.nqmulticast, count*20); + MSG_WriteByte (&sv.nqmulticast, bound(0, count*20, 254)); //255=explosion. MSG_WriteByte (&sv.nqmulticast, nqtype[i]&0xff); } else if (nqtype[i] >= 0) @@ -5678,8 +5735,8 @@ void SV_point_tempentity (vec3_t o, int type, int count) //count (usually 1) is MSG_WriteChar(&sv.nqmulticast, 0); MSG_WriteChar(&sv.nqmulticast, 0); } - if (/*nqtype == TENQ_QWBLOOD ||*/ nqtype[i] == TENQ_QWGUNSHOT) - MSG_WriteByte (&sv.multicast, count); + else if (/*nqtype == TENQ_QWBLOOD ||*/ nqtype[i] == TENQ_QWGUNSHOT) + MSG_WriteByte (&sv.nqmulticast, count); MSG_WriteCoord (&sv.nqmulticast, o[0]); MSG_WriteCoord (&sv.nqmulticast, o[1]); MSG_WriteCoord (&sv.nqmulticast, o[2]); @@ -9774,6 +9831,24 @@ static void QCBUILTIN PF_runclientphys(pubprogfuncs_t *prinst, struct globalvars } } +void SV_SetEntityButtons(edict_t *ent, unsigned int buttonbits) +{ + unsigned int i; + extern cvar_t pr_allowbutton1; + + //set vanilla buttons + ent->v->button0 = buttonbits & 1; + ent->v->button2 = (buttonbits >> 1) & 1; + if (pr_allowbutton1.ival && progstype == PROG_QW) //many mods use button1 - it's just a wasted field to many mods. So only work it if the cvar allows. + ent->v->button1 = ((buttonbits >> 2) & 1); + + //set extended buttons + for (i = 0; i < countof(buttonfields); i++) + { + if (buttonfields[i].offset >= 0) + ((float*)ent->v)[buttonfields[i].offset] = ((buttonbits >> buttonfields[i].bit)&1); + } +} //EXT_CSQC_1 (called when a movement command is received. runs full acceleration + movement) qboolean SV_RunFullQCMovement(client_t *client, usercmd_t *ucmd) @@ -9803,15 +9878,7 @@ qboolean SV_RunFullQCMovement(client_t *client, usercmd_t *ucmd) sv_player->xv->light_level = 128; //hmm... HACK!!! #endif - sv_player->v->button0 = ucmd->buttons & 1; - sv_player->v->button2 = (ucmd->buttons >> 1) & 1; - // DP_INPUTBUTTONS - sv_player->xv->button3 = ((ucmd->buttons >> 2) & 1); - sv_player->xv->button4 = ((ucmd->buttons >> 3) & 1); - sv_player->xv->button5 = ((ucmd->buttons >> 4) & 1); - sv_player->xv->button6 = ((ucmd->buttons >> 5) & 1); - sv_player->xv->button7 = ((ucmd->buttons >> 6) & 1); - sv_player->xv->button8 = ((ucmd->buttons >> 7) & 1); + SV_SetEntityButtons(sv_player, ucmd->buttons); if (ucmd->impulse && SV_FilterImpulse(ucmd->impulse, host_client->trustlevel)) sv_player->v->impulse = ucmd->impulse; diff --git a/engine/server/pr_q1qvm.c b/engine/server/pr_q1qvm.c index 8b25de434..4b0cf9708 100755 --- a/engine/server/pr_q1qvm.c +++ b/engine/server/pr_q1qvm.c @@ -529,7 +529,7 @@ static int QDECL Q1QVMPF_LoadEnts(pubprogfuncs_t *pf, const char *mapstring, voi return sv.world.edict_size; } -static int QDECL Q1QVMPF_QueryField(pubprogfuncs_t *prinst, unsigned int fieldoffset, etype_t *type, char **name, evalc_t *fieldcache) +static int QDECL Q1QVMPF_QueryField(pubprogfuncs_t *prinst, unsigned int fieldoffset, etype_t *type, char const**name, evalc_t *fieldcache) { *type = ev_void; *name = "?"; @@ -539,7 +539,7 @@ static int QDECL Q1QVMPF_QueryField(pubprogfuncs_t *prinst, unsigned int fieldof return true; } -static eval_t *QDECL Q1QVMPF_GetEdictFieldValue(pubprogfuncs_t *pf, edict_t *e, char *fieldname, etype_t type, evalc_t *cache) +static eval_t *QDECL Q1QVMPF_GetEdictFieldValue(pubprogfuncs_t *pf, edict_t *e, const char *fieldname, etype_t type, evalc_t *cache) { if (cache && !cache->varname) { diff --git a/engine/server/progdefs.h b/engine/server/progdefs.h index 13f20c5c9..ebec1e082 100644 --- a/engine/server/progdefs.h +++ b/engine/server/progdefs.h @@ -283,12 +283,6 @@ and the extension fields are added on the end and can have extra vm-specific stu comfieldentity(drawonlytoclient,"This entity will be sent *only* to the player named by this field. To other players they will be invisible and not emit dlights/particles. Does not work in MVD-recorded game.")\ comfieldentity(viewmodelforclient,"This entity will be sent only to the player named by this field, and this entity will be attached to the player's view as an additional weapon model.")/*DP_ENT_VIEWMODEL*/\ comfieldentity(exteriormodeltoclient,"This entity will be invisible to the player named by this field, except in mirrors or mirror-like surfaces, where it will be visible as normal. It may still cast shadows as normal, and generate lights+particles, depending on client settings. Does not affect how other players see the entity.")\ - comfieldfloat(button3,"DP_INPUTBUTTONS (note in qw, we set 1 to equal 3, to match zquake/fuhquake/mvdsv)")\ - comfieldfloat(button4,NULL)\ - comfieldfloat(button5,NULL)\ - comfieldfloat(button6,NULL)\ - comfieldfloat(button7,NULL)\ - comfieldfloat(button8,NULL)\ comfieldfloat(glow_size,NULL)\ comfieldfloat(glow_color,NULL)\ comfieldfloat(glow_trail,NULL)\ @@ -436,7 +430,6 @@ comextqcfields } comentvars_t; #endif - #ifdef USEAREAGRID #define AREAGRIDPERENT 16 #endif diff --git a/engine/server/progs.h b/engine/server/progs.h index 3dbb52648..b6a54e085 100644 --- a/engine/server/progs.h +++ b/engine/server/progs.h @@ -36,6 +36,7 @@ void PR_RegisterFields(void); void PR_Init(void); void QDECL ED_Spawned (struct edict_s *ent, int loading); void SSQC_MapEntityEdited(int modelidx, int idx, const char *newdata); +void SV_SetEntityButtons(struct edict_s *ent, unsigned int buttonbits); qboolean SV_RunFullQCMovement(struct client_s *client, usercmd_t *ucmd); qboolean PR_KrimzonParseCommand(const char *s); qboolean PR_ParseClusterEvent(const char *dest, const char *source, const char *cmd, const char *info); diff --git a/engine/server/savegame.c b/engine/server/savegame.c index b777b2dd0..7af08a47c 100644 --- a/engine/server/savegame.c +++ b/engine/server/savegame.c @@ -151,13 +151,17 @@ pbool SV_ExtendedSaveData(pubprogfuncs_t *progfuncs, void *loadctx, const char * l = COM_ParseTokenOut(l, NULL, token, sizeof(token), &tt);if (tt != TTP_STRING)return false; sv.strings.particle_precache[idx] = PR_AddString(svprogfuncs, token, 0, false); } + else if (PR_Common_LoadGame(svprogfuncs, token, &l)) + ; + /* else if (!strcmp(token, "buffer")) { l = COM_ParseTokenOut(l, NULL, token, sizeof(token), &tt);if (tt != TTP_RAWTOKEN)return false; //buffer = atoi(token); l = COM_ParseTokenOut(l, NULL, token, sizeof(token), &tt);if (tt != TTP_RAWTOKEN)return false; - //count = atoi(token); + //flags = atoi(token); l = COM_ParseTokenOut(l, NULL, token, sizeof(token), &tt);if (tt != TTP_STRING)return false; + //"string" == token return false; } else if (!strcmp(token, "bufstr")) @@ -168,7 +172,7 @@ pbool SV_ExtendedSaveData(pubprogfuncs_t *progfuncs, void *loadctx, const char * //idx = atoi(token); l = COM_ParseTokenOut(l, NULL, token, sizeof(token), &tt);if (tt != TTP_STRING)return false; return false; - } + }*/ else return false; *ptr = l; diff --git a/engine/server/sv_ccmds.c b/engine/server/sv_ccmds.c index a5791d104..41ddb47fb 100644 --- a/engine/server/sv_ccmds.c +++ b/engine/server/sv_ccmds.c @@ -529,8 +529,12 @@ void SV_Map_f (void) if (!Q_strcasecmp(Cmd_Argv(0), "map_restart")) { - float delay = atof(Cmd_Argv(1)); - if (delay) + const char *arg = Cmd_Argv(1); + if (!strcmp(arg, "restore")) //hexen2 reload-saved-game + ; + else if (!strcmp(arg, "initial")) //force initial, even if it breaks saved games. + *sv.loadgame_on_restart = 0; + else if (atof(arg)) //q3's restart-after-delay Con_DPrintf ("map_restart delay not implemented yet\n"); Q_strncpyz (level, ".", sizeof(level)); startspot = NULL; @@ -539,7 +543,6 @@ void SV_Map_f (void) } else { - if (Cmd_Argc() != 2 && Cmd_Argc() != 3) { if (Cmd_IsInsecure()) diff --git a/engine/server/sv_main.c b/engine/server/sv_main.c index f9e2b399b..456451b66 100644 --- a/engine/server/sv_main.c +++ b/engine/server/sv_main.c @@ -191,7 +191,7 @@ void SV_AcceptClient (netadr_t *adr, int userid, char *userinfo); void PRH2_SetPlayerClass(client_t *cl, int classnum, qboolean fromqc); #ifdef SQL -void PR_SQLCycle(); +void PR_SQLCycle(void); #endif int nextuserid; diff --git a/engine/server/sv_mvd.c b/engine/server/sv_mvd.c index 81e9caa1e..658c3f029 100644 --- a/engine/server/sv_mvd.c +++ b/engine/server/sv_mvd.c @@ -2204,7 +2204,7 @@ easyrecord [demoname] ==================== */ -int Dem_CountPlayers () +int Dem_CountPlayers (void) { int i, count; diff --git a/engine/server/sv_send.c b/engine/server/sv_send.c index e09182a08..92680be44 100644 --- a/engine/server/sv_send.c +++ b/engine/server/sv_send.c @@ -2215,7 +2215,7 @@ void SV_QCStatName(int type, char *name, int statnum) void SV_QCStatFieldIdx(int type, unsigned int fieldindex, int statnum) { evalc_t cache; - char *name; + const char *name; etype_t ftype; if (type < 0) diff --git a/engine/server/sv_sys_unix.c b/engine/server/sv_sys_unix.c index f500fff36..da06d0812 100644 --- a/engine/server/sv_sys_unix.c +++ b/engine/server/sv_sys_unix.c @@ -74,24 +74,6 @@ struct termios orig, changes; =============================================================================== */ -/* -============ -Sys_FileTime - -returns -1 if not present -============ -*/ -int Sys_FileTime (char *path) -{ - struct stat buf; - - if (stat (path,&buf) == -1) - return -1; - - return buf.st_mtime; -} - - /* ============ Sys_mkdir @@ -221,7 +203,7 @@ void Sys_Error (const char *error, ...) static qboolean useansicolours; static int ansiremap[8] = {0, 4, 2, 6, 1, 5, 3, 7}; -void ApplyColour(unsigned int chr) +static void ApplyColour(unsigned int chr) { static int oldchar = CON_WHITEMASK; int bg, fg; @@ -284,7 +266,7 @@ void ApplyColour(unsigned int chr) } #define putch(c) putc(c, stdout); -void Sys_PrintColouredChar(unsigned int chr) +/*static void Sys_PrintColouredChar(unsigned int chr) { ApplyColour(chr); @@ -296,7 +278,7 @@ void Sys_PrintColouredChar(unsigned int chr) chr &= ~0x80; putch(chr); -} +}*/ /* ================ @@ -493,7 +475,7 @@ void Sys_Quit (void) static int do_stdin = 1; #if 1 -char *Sys_LineInputChar(char *line) +static char *Sys_LineInputChar(char *line) { char c; while(*line) @@ -777,9 +759,11 @@ static int Sys_CheckChRoot(void) #endif //FIXME: should we temporarily try swapping uid+euid so we don't have any more access than a non-suid binary for this initial init stuff? - struct addrinfo *info; - if (getaddrinfo("master.quakeservers.net", NULL, NULL, &info) == 0) //make sure we've loaded /etc/resolv.conf etc, otherwise any dns requests are going to fail, which would mean no masters. - freeaddrinfo(info); + { + struct addrinfo *info; + if (getaddrinfo("master.quakeservers.net", NULL, NULL, &info) == 0) //make sure we've loaded /etc/resolv.conf etc, otherwise any dns requests are going to fail, which would mean no masters. + freeaddrinfo(info); + } #ifdef SQL SQL_Available(); @@ -892,24 +876,26 @@ int main(int argc, char *argv[]) case false: parms.basedir = "./"; #ifdef __linux__ - //attempt to figure out where the exe is located - int l = readlink("/proc/self/exe", bindir, sizeof(bindir)-1); - if (l > 0) - { - bindir[l] = 0; - *COM_SkipPath(bindir) = 0; - printf("Binary is located at \"%s\"\n", bindir); - parms.binarydir = bindir; + { //attempt to figure out where the exe is located + int l = readlink("/proc/self/exe", bindir, sizeof(bindir)-1); + if (l > 0) + { + bindir[l] = 0; + *COM_SkipPath(bindir) = 0; + printf("Binary is located at \"%s\"\n", bindir); + parms.binarydir = bindir; + } } /*#elif defined(__bsd__) - //attempt to figure out where the exe is located - int l = readlink("/proc/self/exe", bindir, sizeof(bindir)-1); - if (l > 0) - { - bindir[l] = 0; - *COM_SkipPath(bindir) = 0; - printf("Binary is located at "%s"\n", bindir); - parms.binarydir = bindir; + { //attempt to figure out where the exe is located + int l = readlink("/proc/self/exe", bindir, sizeof(bindir)-1); + if (l > 0) + { + bindir[l] = 0; + *COM_SkipPath(bindir) = 0; + printf("Binary is located at "%s"\n", bindir); + parms.binarydir = bindir; + } } */ #endif @@ -970,7 +956,7 @@ int main(int argc, char *argv[]) return 0; } -int Sys_EnumerateFiles2 (const char *truepath, int apathofs, const char *match, int (*func)(const char *, qofs_t, time_t modtime, void *, searchpathfuncs_t *), void *parm, searchpathfuncs_t *spath) +static int Sys_EnumerateFiles2 (const char *truepath, int apathofs, const char *match, int (*func)(const char *, qofs_t, time_t modtime, void *, searchpathfuncs_t *), void *parm, searchpathfuncs_t *spath) { DIR *dir; char file[MAX_OSPATH]; diff --git a/engine/server/sv_user.c b/engine/server/sv_user.c index 510bf0dc7..43f554107 100644 --- a/engine/server/sv_user.c +++ b/engine/server/sv_user.c @@ -4386,7 +4386,8 @@ void SV_SetInfo_f (void) val = Z_StrDup(val); } - if (key[0] == '*') + + if (key[0] == '*' && !(ISNQCLIENT(host_client) && !host_client->spawned && !strcmp(key, "*ver"))) //nq clients are allowed to set some * keys if ClientConnect wasn't called yet. FIXME: saved games may still be an issue. SV_ClientPrintf(host_client, PRINT_HIGH, "setinfo: %s may not be changed mid-game\n", key); else if (sv_userinfo_keylimit.ival >= 0 && host_client->userinfo.numkeys >= sv_userinfo_keylimit.ival && !offset && *val && !InfoBuf_FindKey(&host_client->userinfo, key, &k)) //when the limit is hit, allow people to freely change existing keys, but not new ones. they can also silently remove any that don't exist yet, too. SV_ClientPrintf(host_client, PRINT_MEDIUM, "setinfo: userinfo is limited to %i keys. Ignoring setting %s\n", sv_userinfo_keylimit.ival, key); @@ -7046,17 +7047,7 @@ void SV_RunCmd (usercmd_t *ucmd, qboolean recurse) } #endif - sv_player->v->button0 = ucmd->buttons & 1; - sv_player->v->button2 = (ucmd->buttons >> 1) & 1; - if (pr_allowbutton1.ival && progstype == PROG_QW) //many mods use button1 - it's just a wasted field to many mods. So only work it if the cvar allows. - sv_player->v->button1 = ((ucmd->buttons >> 2) & 1); -// DP_INPUTBUTTONS - sv_player->xv->button3 = ((ucmd->buttons >> 2) & 1); - sv_player->xv->button4 = ((ucmd->buttons >> 3) & 1); - sv_player->xv->button5 = ((ucmd->buttons >> 4) & 1); - sv_player->xv->button6 = ((ucmd->buttons >> 5) & 1); - sv_player->xv->button7 = ((ucmd->buttons >> 6) & 1); - sv_player->xv->button8 = ((ucmd->buttons >> 7) & 1); + SV_SetEntityButtons(sv_player, ucmd->buttons); if (ucmd->impulse && SV_FilterImpulse(ucmd->impulse, host_client->trustlevel)) sv_player->v->impulse = ucmd->impulse; @@ -7872,17 +7863,7 @@ void SV_ExecuteClientMessage (client_t *cl) if (newcmd.impulse)// && SV_FilterImpulse(newcmd.impulse, host_client->trustlevel)) split->edict->v->impulse = newcmd.impulse; - split->edict->v->button0 = newcmd.buttons & 1; - split->edict->v->button2 = (newcmd.buttons >> 1) & 1; - if (pr_allowbutton1.ival) //many mods use button1 - it's just a wasted field to many mods. So only work it if the cvar allows. - split->edict->v->button1 = ((newcmd.buttons >> 2) & 1); - // DP_INPUTBUTTONS - split->edict->xv->button3 = ((newcmd.buttons >> 2) & 1); - split->edict->xv->button4 = ((newcmd.buttons >> 3) & 1); - split->edict->xv->button5 = ((newcmd.buttons >> 4) & 1); - split->edict->xv->button6 = ((newcmd.buttons >> 5) & 1); - split->edict->xv->button7 = ((newcmd.buttons >> 6) & 1); - split->edict->xv->button8 = ((newcmd.buttons >> 7) & 1); + SV_SetEntityButtons(split->edict, newcmd.buttons); } else { @@ -8347,17 +8328,7 @@ void SVNQ_ReadClientMove (usercmd_t *move, qboolean forceangle16) // if (i && SV_FilterImpulse(i, host_client->trustlevel)) // host_client->edict->v->impulse = i; - host_client->edict->v->button0 = bits & 1; - host_client->edict->v->button2 = (bits >> 1) & 1; - if (pr_allowbutton1.ival && progstype == PROG_QW) //many mods use button1 - it's just a wasted field to many mods. So only work it if the cvar allows. - host_client->edict->v->button1 = ((bits >> 2) & 1); -// DP_INPUTBUTTONS - host_client->edict->xv->button3 = ((bits >> 2) & 1); - host_client->edict->xv->button4 = ((bits >> 3) & 1); - host_client->edict->xv->button5 = ((bits >> 4) & 1); - host_client->edict->xv->button6 = ((bits >> 5) & 1); - host_client->edict->xv->button7 = ((bits >> 6) & 1); - host_client->edict->xv->button8 = ((bits >> 7) & 1); + SV_SetEntityButtons(host_client->edict, bits); if (host_client->last_sequence && !sv_nqplayerphysics.ival && host_client->state == cs_spawned) { diff --git a/engine/server/world.c b/engine/server/world.c index 95c1f8ede..8b582d043 100644 --- a/engine/server/world.c +++ b/engine/server/world.c @@ -591,7 +591,7 @@ void QDECL World_LinkEdict (world_t *w, wedict_t *ent, qboolean touch_triggers) #endif #ifdef SKELETALOBJECTS if (ent->xv->skeletonindex) - skel_updateentbounds(ent); + skel_updateentbounds(w, ent); #endif if (!ent->v->solid) @@ -2218,6 +2218,131 @@ static void World_ClipToLinks (world_t *w, areanode_t *node, moveclip_t *clip) World_ClipToLinks (w, node->children[1], clip ); } #endif + +#ifdef HAVE_CLIENT +//The logic of this function is seriously handicapped vs the other types of trace we could be doing. +static void World_ClipToNetwork (world_t *w, moveclip_t *clip) +{ + int i; + packet_entities_t *pe = cl.currentpackentities; + entity_state_t *touch; + + unsigned int touchcontents; + model_t *model; + vec3_t bmins, bmaxs; + trace_t trace; + static framestate_t framestate; //meh + + if (clip->type == MOVE_WORLDONLY) + return; + if (clip->type & MOVE_ENTCHAIN) + return; + + for (i = 0; i < pe->num_entities; i++) + { + touch = &pe->entities[i]; + + if (touch->solidsize == ES_SOLID_NOT) + continue; + else if (touch->solidsize == ES_SOLID_BSP) + { + switch(touch->skinnum) + { + case Q1CONTENTS_LADDER: touchcontents = FTECONTENTS_LADDER; break; + case Q1CONTENTS_SKY: touchcontents = FTECONTENTS_SKY; break; + case Q1CONTENTS_LAVA: touchcontents = FTECONTENTS_LAVA; break; + case Q1CONTENTS_SLIME: touchcontents = FTECONTENTS_SLIME; break; + case Q1CONTENTS_WATER: touchcontents = FTECONTENTS_WATER; break; + default: touchcontents = ~0; break; //could be anything... :( + } + if (touch->modelindex <= 0 || touch->modelindex >= MAX_PRECACHE_MODELS) + continue; //erk + model = cl.model_precache[touch->modelindex]; + VectorCopy(model->mins, bmins); + VectorCopy(model->maxs, bmaxs); + } + else + { + if (clip->type & MOVE_NOMONSTERS) + continue; + touchcontents = FTECONTENTS_BODY; + model = NULL; + COM_DecodeSize(touch->solidsize, bmins, bmaxs); + } + if (!(clip->hitcontentsmask & touchcontents)) + continue; + + //FIXME: this doesn't handle rotations. + if ( clip->boxmins[0] > touch->origin[0]+bmaxs[0] + || clip->boxmins[1] > touch->origin[1]+bmaxs[1] + || clip->boxmins[2] > touch->origin[2]+bmaxs[2] + || clip->boxmaxs[0] < touch->origin[0]+bmins[0] + || clip->boxmaxs[1] < touch->origin[1]+bmins[1] + || clip->boxmaxs[2] < touch->origin[2]+bmins[2] ) + continue; + + //lets say that ssqc ents are in dimension 0x1, as far as the csqc can see. + if (!((int)clip->passedict->xv->dimension_hit & 1)) + continue; + + if (!model || model->loadstate != MLS_LOADED) + { + model = NULL; + + if (clip->hitcontentsmask & FTECONTENTS_BODY) + touchcontents = FTECONTENTS_CORPSE|FTECONTENTS_BODY; + else + touchcontents = 0; + + World_HullForBox(bmins, bmaxs); + } + + framestate.g[FS_REG].frame[0] = touch->frame; + framestate.g[FS_REG].lerpweight[0] = 1; + + if (World_TransformedTrace(model, 0, &framestate, clip->start, clip->end, clip->mins, clip->maxs, clip->capsule, &trace, touch->origin, vec3_origin, clip->hitcontentsmask)) + { + // if using hitmodel, we know it hit the bounding box, so try a proper trace now. + /*if (clip->type & MOVE_HITMODEL && (trace.fraction != 1 || trace.startsolid) && !model) + { + //okay, we hit the bbox + model = w->Get_CModel(w, mdlidx); + + if (model && model->funcs.NativeTrace && model->loadstate == MLS_LOADED) + { + //do the second trace, using the actual mesh. + World_TransformedTrace(model, hullnum, &framestate, start, end, mins, maxs, capsule, &trace, eorg, vec3_origin, hitcontentsmask); + } + }*/ + } + + if (trace.fraction < clip->trace.fraction) + { + //trace traveled less, but don't forget if we started in a solid. + trace.startsolid |= clip->trace.startsolid; + trace.allsolid |= clip->trace.allsolid; + + if (clip->trace.startsolid && !trace.startsolid) + trace.ent = clip->trace.ent; //something else hit earlier, that one gets the trace entity, but not the fraction. yeah, combining traces like this was always going to be weird. + else + trace.ent = touch; + clip->trace = trace; + } + else if (trace.startsolid || trace.allsolid) + { + //even if the trace traveled less, we still care if it was in a solid. + clip->trace.startsolid |= trace.startsolid; + clip->trace.allsolid |= trace.allsolid; + if (!clip->trace.ent || trace.fraction == clip->trace.fraction) //xonotic requires that second test (DP has no check at all, which would end up reporting mismatched fraction/ent results, so yuck). + { + clip->trace.contents = trace.contents; + clip->trace.ent = touch; + } + } + } +} +#endif + /* ================== SV_MoveBounds @@ -2592,6 +2717,14 @@ trace_t World_Move (world_t *w, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t e World_ClipToLinks(w, &w->portallist, &clip); } +#ifdef HAVE_CLIENT + { + extern world_t csqc_world; + if (w == &csqc_world) + World_ClipToNetwork(w, &clip); + } +#endif + // if (clip.trace.startsolid) // clip.trace.fraction = 0; diff --git a/engine/shaders/glsl/defaultskin.glsl b/engine/shaders/glsl/defaultskin.glsl index 7c992d52b..29afcc77b 100644 --- a/engine/shaders/glsl/defaultskin.glsl +++ b/engine/shaders/glsl/defaultskin.glsl @@ -270,6 +270,7 @@ void main () #endif col.rgb *= light; + col *= e_colourident; #ifdef FULLBRIGHT vec4 fb = texture2D(s_fullbright, tc); @@ -278,7 +279,7 @@ void main () #endif #endif - gl_FragColor = fog4(col * e_colourident); + gl_FragColor = fog4(col); } #endif diff --git a/engine/web/sys_web.c b/engine/web/sys_web.c index daf82c765..ebfbef4b2 100644 --- a/engine/web/sys_web.c +++ b/engine/web/sys_web.c @@ -237,17 +237,13 @@ qboolean Sys_GetDesktopParameters(int *width, int *height, int *bpp, int *refres +#define SYS_CLIPBOARD_SIZE 256 static char *clipboard_buffer; -char *Sys_GetClipboard(void) +void Sys_Clipboard_PasteText(clipboardtype_t cbt, void (*callback)(void *cb, char *utf8), void *ctx) { - return clipboard_buffer; + callback(ctx, clipboard_buffer); } - -void Sys_CloseClipboard(char *bf) -{ -} - -void Sys_SaveClipboard(char *text) +void Sys_SaveClipboard(clipboardtype_t cbt, char *text) { free(clipboard_buffer); clipboard_buffer = strdup(text); diff --git a/plugins/ezhud/ezquakeisms.c b/plugins/ezhud/ezquakeisms.c index a7477d4b4..15d4a648f 100644 --- a/plugins/ezhud/ezquakeisms.c +++ b/plugins/ezhud/ezquakeisms.c @@ -182,7 +182,7 @@ void Draw_ColoredString3(float x, float y, const char *str, clrinfo_t *clr, int pDraw_String(x, y, str); pDraw_Colour4f(1, 1, 1, 1); } -void UI_PrintTextBlock() +void UI_PrintTextBlock(void) { } void Draw_AlphaRectangleRGB(int x, int y, int w, int h, int foo, int bar, byte r, byte g, byte b, byte a) diff --git a/plugins/ezhud/ezquakeisms.h b/plugins/ezhud/ezquakeisms.h index 0ca2941f1..a8888ac03 100644 --- a/plugins/ezhud/ezquakeisms.h +++ b/plugins/ezhud/ezquakeisms.h @@ -2,6 +2,11 @@ #include #include +//ezquake sucks. I'd fix these, but that'd make diffs more messy. +#pragma GCC diagnostic ignored "-Wold-style-definition" +#pragma GCC diagnostic ignored "-Wstrict-prototypes" +#pragma GCC diagnostic ignored "-Wmissing-prototypes" + //ezquake types. #define byte qbyte #define qbool qboolean @@ -31,127 +36,127 @@ #define MV_VIEWS 4 -extern float cursor_x; +extern float cursor_x; extern float cursor_y; -extern int host_screenupdatecount; -extern cvar_t *scr_newHud; -extern cvar_t *cl_multiview; - -#define Cam_TrackNum() cl.tracknum -#define spec_track cl.tracknum -#define autocam ((spec_track==-1)?CAM_NONE:CAM_TRACK) -#define CAM_TRACK true -#define CAM_NONE false -//#define HAXX - -#define vid plugvid -#define cls plugcls -#define cl plugcl -#define player_info_t plugclientinfo_t - -struct { - int intermission; - int teamplay; - int deathmatch; - int stats[MAX_CL_STATS]; - int item_gettime[32]; - char serverinfo[4096]; - player_info_t players[MAX_CLIENTS]; - int playernum; - int tracknum; - vec3_t simvel; - float time; - float matchstart; - float faceanimtime; - qboolean spectator; - qboolean standby; - qboolean countdown; - - int splitscreenview; -} cl; -struct { - int state; - float min_fps; - float fps; - float realtime; - float frametime; - qbool mvdplayback; - int demoplayback; -} cls; -struct { - int width; - int height; -// float displayFrequency; -} vid; - - -//reimplementations of ezquake functions -void Draw_SetOverallAlpha(float a); -void Draw_AlphaFillRGB(float x, float y, float w, float h, qbyte r, qbyte g, qbyte b, qbyte a); -void Draw_Fill(float x, float y, float w, float h, qbyte pal); -const char *ColorNameToRGBString (const char *newval); -byte *StringToRGB(const char *str); - -#define Draw_String pDraw_String - -void Draw_EZString(float x, float y, char *str, float scale, qboolean red); -#define Draw_Alt_String(x,y,s) Draw_EZString(x,y,s,8,true) -#define Draw_ColoredString(x,y,str,alt) Draw_EZString(x,y,str,8,alt) -#define Draw_SString(x,y,str,sc) Draw_EZString(x,y,str,8*sc,false) -#define Draw_SAlt_String(x,y,str,sc) Draw_EZString(x,y,str,8*sc,true) - -void Draw_SPic(float x, float y, mpic_t *pic, float scale); -void Draw_SSubPic(float x, float y, mpic_t *pic, float s1, float t1, float s2, float t2, float scale); -#define Draw_STransPic Draw_SPic -void Draw_Character(float x, float y, unsigned int ch); -void Draw_SCharacter(float x, float y, unsigned int ch, float scale); - -void SCR_DrawWadString(float x, float y, float scale, char *str); - -void Draw_SAlphaSubPic2(float x, float y, mpic_t *pic, float s1, float t1, float s2, float t2, float w, float h, float alpha); - -void Draw_AlphaFill(float x, float y, float w, float h, unsigned int pal, float alpha); -void Draw_AlphaPic(float x, float y, mpic_t *pic, float alpha); -void Draw_AlphaSubPic(float x, float y, mpic_t *pic, float s1, float t1, float s2, float t2, float alpha); -void SCR_HUD_DrawBar(int direction, int value, float max_value, float *rgba, int x, int y, int width, int height); - -mpic_t *Draw_CachePicSafe(const char *name, qbool crash, qbool ignorewad); -mpic_t *Draw_CacheWadPic(const char *name); - -int Sbar_TopColor(player_info_t *pi); -int Sbar_BottomColor(player_info_t *pi); -char *TP_ParseFunChars(char*, qbool chat); -char *TP_ItemName(unsigned int itbit); - -#define Util_SkipChars(src,strip,dst,dstlen) strlcpy(dst,src,dstlen) -#define Util_SkipEZColors(src,dst,dstlen) strlcpy(dst,src,dstlen) - -void Replace_In_String(char *string, size_t strsize, char leadchar, int patterns, ...); -//static qbool Utils_RegExpMatch(char *regexp, char *term) {return true;} -#define Utils_RegExpMatch(regexp,term) (true) - -#define clamp(v,min,max) v=bound(min,v,max) -#define strlen_color(line) (pDraw_StringWidth(8, 0, line)/8.0) - -#define TIMETYPE_CLOCK 0 -#define TIMETYPE_GAMECLOCK 1 -#define TIMETYPE_GAMECLOCKINV 2 -#define TIMETYPE_DEMOCLOCK 3 -int SCR_GetClockStringWidth(const char *s, qbool big, float scale); -int SCR_GetClockStringHeight(qbool big, float scale); -const char* SCR_GetTimeString(int timetype, const char *format); -void SCR_DrawBigClock(int x, int y, int style, int blink, float scale, const char *t); -void SCR_DrawSmallClock(int x, int y, int style, int blink, float scale, const char *t); - -typedef struct -{ - qbyte c[4]; -} clrinfo_t; -void Draw_ColoredString3(float x, float y, const char *str, clrinfo_t *clr, int huh, int wut); -void UI_PrintTextBlock(); -void Draw_AlphaRectangleRGB(int x, int y, int w, int h, int foo, int bar, byte r, byte g, byte b, byte a); -void Draw_AlphaLineRGB(float x1, float y1, float x2, float y2, float width, byte r, byte g, byte b, byte a); -void Draw_Polygon(int x, int y, vec3_t *vertices, int num_vertices, qbool fill, byte r, byte g, byte b, byte a); - +extern int host_screenupdatecount; +extern cvar_t *scr_newHud; +extern cvar_t *cl_multiview; + +#define Cam_TrackNum() cl.tracknum +#define spec_track cl.tracknum +#define autocam ((spec_track==-1)?CAM_NONE:CAM_TRACK) +#define CAM_TRACK true +#define CAM_NONE false +//#define HAXX + +#define vid plugvid +#define cls plugcls +#define cl plugcl +#define player_info_t plugclientinfo_t + +struct { + int intermission; + int teamplay; + int deathmatch; + int stats[MAX_CL_STATS]; + int item_gettime[32]; + char serverinfo[4096]; + player_info_t players[MAX_CLIENTS]; + int playernum; + int tracknum; + vec3_t simvel; + float time; + float matchstart; + float faceanimtime; + qboolean spectator; + qboolean standby; + qboolean countdown; + + int splitscreenview; +} cl; +struct { + int state; + float min_fps; + float fps; + float realtime; + float frametime; + qbool mvdplayback; + int demoplayback; +} cls; +struct { + int width; + int height; +// float displayFrequency; +} vid; + + +//reimplementations of ezquake functions +void Draw_SetOverallAlpha(float a); +void Draw_AlphaFillRGB(float x, float y, float w, float h, qbyte r, qbyte g, qbyte b, qbyte a); +void Draw_Fill(float x, float y, float w, float h, qbyte pal); +const char *ColorNameToRGBString (const char *newval); +byte *StringToRGB(const char *str); + +#define Draw_String pDraw_String + +void Draw_EZString(float x, float y, char *str, float scale, qboolean red); +#define Draw_Alt_String(x,y,s) Draw_EZString(x,y,s,8,true) +#define Draw_ColoredString(x,y,str,alt) Draw_EZString(x,y,str,8,alt) +#define Draw_SString(x,y,str,sc) Draw_EZString(x,y,str,8*sc,false) +#define Draw_SAlt_String(x,y,str,sc) Draw_EZString(x,y,str,8*sc,true) + +void Draw_SPic(float x, float y, mpic_t *pic, float scale); +void Draw_SSubPic(float x, float y, mpic_t *pic, float s1, float t1, float s2, float t2, float scale); +#define Draw_STransPic Draw_SPic +void Draw_Character(float x, float y, unsigned int ch); +void Draw_SCharacter(float x, float y, unsigned int ch, float scale); + +void SCR_DrawWadString(float x, float y, float scale, char *str); + +void Draw_SAlphaSubPic2(float x, float y, mpic_t *pic, float s1, float t1, float s2, float t2, float w, float h, float alpha); + +void Draw_AlphaFill(float x, float y, float w, float h, unsigned int pal, float alpha); +void Draw_AlphaPic(float x, float y, mpic_t *pic, float alpha); +void Draw_AlphaSubPic(float x, float y, mpic_t *pic, float s1, float t1, float s2, float t2, float alpha); +void SCR_HUD_DrawBar(int direction, int value, float max_value, float *rgba, int x, int y, int width, int height); + +mpic_t *Draw_CachePicSafe(const char *name, qbool crash, qbool ignorewad); +mpic_t *Draw_CacheWadPic(const char *name); + +int Sbar_TopColor(player_info_t *pi); +int Sbar_BottomColor(player_info_t *pi); +char *TP_ParseFunChars(char*, qbool chat); +char *TP_ItemName(unsigned int itbit); + +#define Util_SkipChars(src,strip,dst,dstlen) strlcpy(dst,src,dstlen) +#define Util_SkipEZColors(src,dst,dstlen) strlcpy(dst,src,dstlen) + +void Replace_In_String(char *string, size_t strsize, char leadchar, int patterns, ...); +//static qbool Utils_RegExpMatch(char *regexp, char *term) {return true;} +#define Utils_RegExpMatch(regexp,term) (true) + +#define clamp(v,min,max) v=bound(min,v,max) +#define strlen_color(line) (pDraw_StringWidth(8, 0, line)/8.0) + +#define TIMETYPE_CLOCK 0 +#define TIMETYPE_GAMECLOCK 1 +#define TIMETYPE_GAMECLOCKINV 2 +#define TIMETYPE_DEMOCLOCK 3 +int SCR_GetClockStringWidth(const char *s, qbool big, float scale); +int SCR_GetClockStringHeight(qbool big, float scale); +const char* SCR_GetTimeString(int timetype, const char *format); +void SCR_DrawBigClock(int x, int y, int style, int blink, float scale, const char *t); +void SCR_DrawSmallClock(int x, int y, int style, int blink, float scale, const char *t); + +typedef struct +{ + qbyte c[4]; +} clrinfo_t; +void Draw_ColoredString3(float x, float y, const char *str, clrinfo_t *clr, int huh, int wut); +void UI_PrintTextBlock(); +void Draw_AlphaRectangleRGB(int x, int y, int w, int h, int foo, int bar, byte r, byte g, byte b, byte a); +void Draw_AlphaLineRGB(float x1, float y1, float x2, float y2, float width, byte r, byte g, byte b, byte a); +void Draw_Polygon(int x, int y, vec3_t *vertices, int num_vertices, qbool fill, byte r, byte g, byte b, byte a); + //glue EBUILTIN(cvar_t*, Cvar_GetNVFDG, (const char *name, const char *defaultval, unsigned int flags, const char *description, const char *groupname)); diff --git a/plugins/ezhud/hud_common.c b/plugins/ezhud/hud_common.c index 1bf34c836..7185719eb 100644 --- a/plugins/ezhud/hud_common.c +++ b/plugins/ezhud/hud_common.c @@ -4800,7 +4800,7 @@ void OnAutoHudChange(cvar_t *var, char *value, qbool *cancel) { } // Is run when a new map is loaded. -void HUD_NewMap() { +void HUD_NewMap(void) { #if defined(WITH_PNG) HUD_NewRadarMap(); #endif // WITH_PNG diff --git a/plugins/irc/ircclient.c b/plugins/irc/ircclient.c index 88badb6b6..0832e1b5d 100644 --- a/plugins/irc/ircclient.c +++ b/plugins/irc/ircclient.c @@ -64,7 +64,7 @@ static char casevar[9][1000]; //numbered_command #define RELEASE __DATE__ void (*Con_TrySubPrint)(const char *subname, const char *text); -void Con_FakeSubPrint(const char *subname, const char *text) +static void Con_FakeSubPrint(const char *subname, const char *text) { pCon_Print(text); } @@ -220,7 +220,7 @@ typedef struct ircclient_s { ircclient_t *ircclients; -void IRC_SetFooter(ircclient_t *irc, const char *subname, const char *format, ...) +static void IRC_SetFooter(ircclient_t *irc, const char *subname, const char *format, ...) { va_list argptr; static char string[1024]; @@ -271,7 +271,7 @@ void IRC_SetFooter(ircclient_t *irc, const char *subname, const char *format, .. pCon_SetConsoleString(lwr, "footer", string); } } -qboolean IRC_WindowShown(ircclient_t *irc, const char *subname) +static qboolean IRC_WindowShown(ircclient_t *irc, const char *subname) { char lwr[128]; int i; @@ -293,7 +293,7 @@ qboolean IRC_WindowShown(ircclient_t *irc, const char *subname) } return true; } -void IRC_Printf(ircclient_t *irc, const char *subname, const char *format, ...) +static void IRC_Printf(ircclient_t *irc, const char *subname, const char *format, ...) { va_list argptr; static char string[1024]; @@ -351,7 +351,7 @@ void IRC_Printf(ircclient_t *irc, const char *subname, const char *format, ...) -void IRC_InitCvars(void) +static void IRC_InitCvars(void) { vmcvar_t *v; int i; @@ -362,7 +362,7 @@ void IRC_InitCvars(void) } } -int IRC_CvarUpdate(void) // perhaps void instead? +static int IRC_CvarUpdate(void) // perhaps void instead? { vmcvar_t *v; int i; @@ -458,7 +458,7 @@ qintptr_t IRC_ConExecuteCommand(qintptr_t *args) return true; } -void IRC_AddClientMessage(ircclient_t *irc, char *msg) +static void IRC_AddClientMessage(ircclient_t *irc, char *msg) { char output[4096]; int len; @@ -475,7 +475,7 @@ void IRC_AddClientMessage(ircclient_t *irc, char *msg) if (irc_debug.value == 1) { IRC_Printf(irc, DEFAULTCONSOLE,COLOURYELLOW "<< %s \n",msg); } } -ircclient_t *IRC_FindAccount(const char *server) +static ircclient_t *IRC_FindAccount(const char *server) { ircclient_t *irc; for (irc = ircclients; irc; irc = irc->next) @@ -486,7 +486,7 @@ ircclient_t *IRC_FindAccount(const char *server) return NULL; //no match } -ircclient_t *IRC_Create(const char *server, const char *nick, const char *realname, const char *hostname, const char *password, const char *channels) +static ircclient_t *IRC_Create(const char *server, const char *nick, const char *realname, const char *hostname, const char *password, const char *channels) { ircclient_t *irc; @@ -524,19 +524,19 @@ ircclient_t *IRC_Create(const char *server, const char *nick, const char *realna return irc; } -void IRC_SetPass(ircclient_t *irc, char *pass) +static void IRC_SetPass(ircclient_t *irc, char *pass) { Q_strlcpy(irc->pwd, pass, sizeof(irc->pwd)); if (*pass && irc->tlsmode != TLS_STARTING) IRC_AddClientMessage(irc, va("PASS %s", pass)); } -void IRC_SetNick(ircclient_t *irc, char *nick) +static void IRC_SetNick(ircclient_t *irc, char *nick) { Q_strlcpy(irc->nick, nick, sizeof(irc->nick)); if (irc->tlsmode != TLS_STARTING) IRC_AddClientMessage(irc, va("NICK %s", irc->nick)); } -void IRC_SetUser(ircclient_t *irc, char *user) +static void IRC_SetUser(ircclient_t *irc, char *user) { IRC_CvarUpdate(); @@ -544,7 +544,7 @@ void IRC_SetUser(ircclient_t *irc, char *user) IRC_AddClientMessage(irc, va("USER %s %s %s :%s", irc_ident.string, irc->hostname, irc->server, irc_realname.string)); } -qboolean IRC_Establish(ircclient_t *irc) +static qboolean IRC_Establish(ircclient_t *irc) { if (!irc) return false; @@ -591,7 +591,7 @@ qboolean IRC_Establish(ircclient_t *irc) return true; } -void IRC_ParseConfig(void) +static void IRC_ParseConfig(void) { qhandle_t config; int len = pFS_Open("**plugconfig", &config, 1); @@ -638,7 +638,7 @@ void IRC_ParseConfig(void) free(buf); } } -void IRC_WriteConfig(void) +static void IRC_WriteConfig(void) { qhandle_t config; pFS_Open("**plugconfig", &config, 2); @@ -657,7 +657,7 @@ void IRC_WriteConfig(void) } } -void IRC_PartChannelInternal(ircclient_t *irc, char *channelname) +static void IRC_PartChannelInternal(ircclient_t *irc, char *channelname) { char ac[countof(irc->autochannels)]; char *chan; @@ -686,13 +686,13 @@ void IRC_PartChannelInternal(ircclient_t *irc, char *channelname) } } -void IRC_PartChannel(ircclient_t *irc, char *channelname) +static void IRC_PartChannel(ircclient_t *irc, char *channelname) { IRC_PartChannelInternal(irc, channelname); IRC_AddClientMessage(irc, va("PART %s", channelname)); } -void IRC_JoinChannel(ircclient_t *irc, char *channel, char *key) // i screwed up, its actually: {,} [{,}] +static void IRC_JoinChannel(ircclient_t *irc, char *channel, char *key) // i screwed up, its actually: {,} [{,}] { IRC_PartChannelInternal(irc, channel); @@ -716,7 +716,7 @@ void IRC_JoinChannel(ircclient_t *irc, char *channel, char *key) // i screwed up } } -void IRC_JoinChannels(ircclient_t *irc, char *channelstring) +static void IRC_JoinChannels(ircclient_t *irc, char *channelstring) { char *chan = strtok(channelstring, " "); while(chan) @@ -763,7 +763,7 @@ background examples: (note I hope this makes sense to you, to be able to edit the IRC_FilterMircColours function ~ Moodles */ -void IRC_FilterMircColours(char *msg) +static void IRC_FilterMircColours(char *msg) { int i; int chars; @@ -851,7 +851,7 @@ void IRC_FilterMircColours(char *msg) #define IRC_CONTINUE 1 #define IRC_KILL 2 -void magic_tokenizer(int word,char *thestring) +static void magic_tokenizer(int word,char *thestring) { char *temp; int i = 1; @@ -879,7 +879,7 @@ void magic_tokenizer(int word,char *thestring) } -void magic_etghack(char *thestring) +static void magic_etghack(char *thestring) { char *temp; int i = 1; @@ -910,7 +910,7 @@ void magic_etghack(char *thestring) //================================================== -void numbered_command(int comm, char *msg, ircclient_t *irc) // move vars up 1 more than debug says +static void numbered_command(int comm, char *msg, ircclient_t *irc) // move vars up 1 more than debug says { magic_tokenizer(0,msg); @@ -1222,7 +1222,7 @@ void numbered_command(int comm, char *msg, ircclient_t *irc) // move vars up 1 m IRC_Printf(irc, DEFAULTCONSOLE, "%s\n", msg); // if no raw number exists, print the thing } -struct ircice_s *IRC_ICE_Find(ircclient_t *irc, const char *sender, enum iceproto_e type) +static struct ircice_s *IRC_ICE_Find(ircclient_t *irc, const char *sender, enum iceproto_e type) { struct ircice_s *ice; for (ice = irc->ice; ice; ice = ice->next) @@ -1232,7 +1232,7 @@ struct ircice_s *IRC_ICE_Find(ircclient_t *irc, const char *sender, enum iceprot } return NULL; } -struct ircice_s *IRC_ICE_Create(ircclient_t *irc, const char *sender, enum iceproto_e type, qboolean creator) +static struct ircice_s *IRC_ICE_Create(ircclient_t *irc, const char *sender, enum iceproto_e type, qboolean creator) { struct icestate_s *ice; struct ircice_s *ircice; @@ -1287,7 +1287,7 @@ struct ircice_s *IRC_ICE_Create(ircclient_t *irc, const char *sender, enum icepr return ircice; } -void IRC_ICE_Update(ircclient_t *irc, struct ircice_s *ice, char updatetype) +static void IRC_ICE_Update(ircclient_t *irc, struct ircice_s *ice, char updatetype) { //I was originally using colons to separate terms, but switched to slashes to avoid smilies for irc clients that print unknown CTCP messages. char message[1024]; @@ -1398,7 +1398,7 @@ void IRC_ICE_Update(ircclient_t *irc, struct ircice_s *ice, char updatetype) IRC_AddClientMessage(irc, va("NOTICE %s :\001FTEICE %c%s%s\001", ice->peer, updatetype, icetype, message)); } -void IRC_ICE_ParseCandidate(struct icestate_s *ice, char *cand) +static void IRC_ICE_ParseCandidate(struct icestate_s *ice, char *cand) { char *addr; struct icecandinfo_s info; @@ -1429,7 +1429,7 @@ void IRC_ICE_ParseCandidate(struct icestate_s *ice, char *cand) piceapi->ICE_AddRCandidateInfo(ice, &info); } -void IRC_ICE_ParseCodec(struct icestate_s *ice, char *codec) +static void IRC_ICE_ParseCodec(struct icestate_s *ice, char *codec) { char *start; unsigned int num; @@ -1444,7 +1444,7 @@ void IRC_ICE_ParseCodec(struct icestate_s *ice, char *codec) piceapi->ICE_Set(ice, va("codec%i", num), name); } -void IRC_ICE_Parse(ircclient_t *irc, const char *sender, char *message) +static void IRC_ICE_Parse(ircclient_t *irc, const char *sender, char *message) { struct ircice_s *ice; char token[256]; @@ -1556,7 +1556,7 @@ void IRC_ICE_Parse(ircclient_t *irc, const char *sender, char *message) IRC_Printf(irc, sender, "ICE command type not supported\n", token); } -void IRC_ICE_Frame(ircclient_t *irc) +static void IRC_ICE_Frame(ircclient_t *irc) { char bah[8]; struct ircice_s *ice; @@ -1768,7 +1768,7 @@ qintptr_t IRC_ConsoleLink(qintptr_t *args) //================================================== -int IRC_ClientFrame(ircclient_t *irc) +static int IRC_ClientFrame(ircclient_t *irc) { char prefix[64]; int ret; diff --git a/plugins/plugin.c b/plugins/plugin.c index 598bdd42d..085584cb7 100644 --- a/plugins/plugin.c +++ b/plugins/plugin.c @@ -41,7 +41,7 @@ BUILTINR(funcptr_t, Plug_GetEngineFunction, (const char *funcname)); #undef ARGNAMES #define ARGNAMES ,funcname,expnum -BUILTINR(int, Plug_ExportToEngine, (const char *funcname, quintptr_t expnum)); +static BUILTINR(int, Plug_ExportToEngine, (const char *funcname, quintptr_t expnum)); #undef ARGNAMES #ifndef Q3_VM @@ -112,7 +112,7 @@ BUILTIN(void, Cmd_Argv, (int argnum, char *buffer, int bufsize)); //retrieve a s BUILTINR(int, Cmd_Argc, (void)); //get the argument count. #undef ARGNAMES #define ARGNAMES ,msg -BUILTIN(void, Cmd_TokenizeString, (char *msg)); //tokenize a string. +BUILTIN(void, Cmd_TokenizeString, (const char *msg)); //tokenize a string. #undef ARGNAMES #define ARGNAMES ,text,insert @@ -405,12 +405,7 @@ void Sys_Errorf(const char *format, ...) pSys_Error(string); } -void BadBuiltin(void) -{ - pSys_Error("Plugin tried calling a missing builtin\n"); -} - -void Plug_InitStandardBuiltins(void) +static void Plug_InitStandardBuiltins(void) { //con_print is used if the others don't exist, and MUST come first (for the sake of sanity) CHECKBUILTIN(Con_Print); @@ -541,7 +536,7 @@ NATIVEEXPORT void QDECL dllEntry(qintptr_t (QDECL *funcptr)(qintptr_t,...)) #endif vmvideo_t pvid; -qintptr_t QDECL Plug_UpdateVideo(qintptr_t *args) +static qintptr_t QDECL Plug_UpdateVideo(qintptr_t *args) { pvid.width = args[0]; pvid.height = args[1]; @@ -549,7 +544,7 @@ qintptr_t QDECL Plug_UpdateVideo(qintptr_t *args) return true; } -qintptr_t QDECL Plug_InitAPI(qintptr_t *args) +static qintptr_t QDECL Plug_InitAPI(qintptr_t *args) { #ifdef Q3_VM Plug_GetEngineFunction = (void*)args[0]; diff --git a/plugins/plugin.h b/plugins/plugin.h index 9e75a2d49..fd5b06cbc 100644 --- a/plugins/plugin.h +++ b/plugins/plugin.h @@ -216,14 +216,14 @@ EBUILTIN(int, Con_GetConsoleString, (const char *conname, const char *attribname EBUILTIN(void, Con_SetConsoleString, (const char *conname, const char *attribname, const char *newvalue)); EBUILTIN(void, Sys_Error, (const char *message)); //abort the entire engine. -EBUILTIN(quintptr_t, Sys_Milliseconds, ()); +EBUILTIN(quintptr_t, Sys_Milliseconds, (void)); -EBUILTIN(int, Cmd_AddCommand, (const char *buffer)); //abort the entire engine. +EBUILTIN(int, Cmd_AddCommand, (const char *buffer)); //Registers a console command. EBUILTIN(void, Cmd_Args, (char *buffer, int bufsize)); //abort the entire engine. EBUILTIN(void, Cmd_Argv, (int argnum, char *buffer, int bufsize)); //abort the entire engine. EBUILTIN(int, Cmd_Argc, (void)); //abort the entire engine. EBUILTIN(void, Cmd_AddText, (const char *text, qboolean insert)); -EBUILTIN(void, Cmd_Tokenize, (const char *msg)); //abort the entire engine. +EBUILTIN(void, Cmd_TokenizeString, (const char *msg)); //tokenize a string. EBUILTIN(void, Cvar_SetString, (const char *name, const char *value)); EBUILTIN(void, Cvar_SetFloat, (const char *name, float value)); @@ -387,8 +387,8 @@ void Con_DPrintf(const char *format, ...); //not a particuarly efficient impleme void Sys_Errorf(const char *format, ...); void QDECL Q_strncpyz(char *d, const char *s, int n); - - +qintptr_t NATIVEEXPORT vmMain( qintptr_t command, qintptr_t arg0, qintptr_t arg1, qintptr_t arg2, qintptr_t arg3, qintptr_t arg4, qintptr_t arg5, qintptr_t arg6, qintptr_t arg7/*, qintptr_t arg8, qintptr_t arg9, qintptr_t arg10, qintptr_t arg11*/); +NATIVEEXPORT void QDECL dllEntry(qintptr_t (QDECL *funcptr)(qintptr_t,...)); #define PLUG_SHARED_BEGIN(t,p,b) \ { \ diff --git a/plugins/qi/qi.c b/plugins/qi/qi.c index d7950ad44..5cb2f3b7a 100644 --- a/plugins/qi/qi.c +++ b/plugins/qi/qi.c @@ -36,7 +36,7 @@ struct int type; } filters; -void Con_SubPrintf(const char *subname, char *format, ...) +static void Con_SubPrintf(const char *subname, char *format, ...) { va_list argptr; static char string[8192]; @@ -49,7 +49,7 @@ void Con_SubPrintf(const char *subname, char *format, ...) } -qintptr_t QI_Shutdown(qintptr_t *args) +static qintptr_t QI_Shutdown(qintptr_t *args) { if (dlcontext != -1) { //we're still downloading something? :o @@ -62,7 +62,7 @@ qintptr_t QI_Shutdown(qintptr_t *args) return false; } -qboolean QI_SetupWindow(const char *console, qboolean force) +static qboolean QI_SetupWindow(const char *console, qboolean force) { if (!BUILTINISVALID(Con_GetConsoleFloat)) return false; @@ -89,7 +89,7 @@ qboolean QI_SetupWindow(const char *console, qboolean force) pCon_SetActive(console); return true; } -void QI_DeHTML(const char *in, char *out, size_t outsize) +static void QI_DeHTML(const char *in, char *out, size_t outsize) { outsize--; while(*in && outsize > 0) @@ -210,7 +210,7 @@ static char *QI_strcasestr(const char *haystack, const char *needle) return NULL; //didn't find it } -void QI_RefreshMapList(qboolean forcedisplay) +static void QI_RefreshMapList(qboolean forcedisplay) { xmltree_t *file; const char *console = WINDOWNAME; @@ -497,7 +497,7 @@ static void QI_RunMap(xmltree_t *qifile, const char *map) pCmd_AddText("\n", false); } -qintptr_t QI_ConsoleLink(qintptr_t *args) +static qintptr_t QI_ConsoleLink(qintptr_t *args) { xmltree_t *file; char *map; @@ -570,7 +570,7 @@ qintptr_t QI_ConsoleLink(qintptr_t *args) } return false; } -qintptr_t QI_Tick(qintptr_t *args) +static qintptr_t QI_Tick(qintptr_t *args) { if (dlcontext != -1) { @@ -621,7 +621,7 @@ qintptr_t QI_Tick(qintptr_t *args) return false; } -qintptr_t QI_ConExecuteCommand(qintptr_t *args) +static qintptr_t QI_ConExecuteCommand(qintptr_t *args) { char console[256]; char filter[256]; @@ -635,7 +635,7 @@ qintptr_t QI_ConExecuteCommand(qintptr_t *args) return true; } -qintptr_t QI_ExecuteCommand(qintptr_t *args) +static qintptr_t QI_ExecuteCommand(qintptr_t *args) { char cmd[256]; pCmd_Argv(0, cmd, sizeof(cmd));