diff --git a/engine/client/cl_demo.c b/engine/client/cl_demo.c index e71d4a052..6b5d09c51 100644 --- a/engine/client/cl_demo.c +++ b/engine/client/cl_demo.c @@ -1575,7 +1575,7 @@ void CL_Record_f (void) return; } -#ifdef Q2SERVER +#ifdef Q2CLIENT if (cls.protocol == CP_QUAKE2) defaultext = ".dm2"; else diff --git a/engine/client/in_generic.c b/engine/client/in_generic.c index 734e80bc9..e3b99f328 100644 --- a/engine/client/in_generic.c +++ b/engine/client/in_generic.c @@ -15,7 +15,7 @@ extern qboolean mouse_active; static cvar_t m_filter = CVARF("m_filter", "0", CVAR_ARCHIVE); static cvar_t m_forcewheel = CVARD("m_forcewheel", "1", "0: ignore mousewheels in apis where it is abiguous.\n1: Use mousewheel when it is treated as a third axis. Motion above a threshold is ignored, to avoid issues with an unknown threshold.\n2: Like 1, but excess motion is retained. The threshold specifies exact z-axis distance per notice."); static cvar_t m_forcewheel_threshold = CVARD("m_forcewheel_threshold", "32", "Mousewheel graduations smaller than this will not trigger mousewheel deltas."); -static cvar_t m_strafeonright = CVARFD("m_strafeonright", "1", CVAR_ARCHIVE, "If 1, touching the right half of the touchscreen will strafe/move, while the left side will turn."); +static cvar_t m_touchstrafe = CVARAFD("m_touchstrafe", "1", "m_strafeonright", CVAR_ARCHIVE, "0: entire screen changes angles only.\n1: right hand side controls strafing.\n2:left hand side strafes."); static cvar_t m_fatpressthreshold = CVARFD("m_fatpressthreshold", "0.2", CVAR_ARCHIVE, "How fat your thumb has to be to register a fat press (touchscreens)."); static cvar_t m_touchmajoraxis = CVARFD("m_touchmajoraxis", "1", CVAR_ARCHIVE, "When using a touchscreen, use only the major axis for strafing."); static cvar_t m_slidethreshold = CVARFD("m_slidethreshold", "10", CVAR_ARCHIVE, "How far your finger needs to move to be considered a slide event (touchscreens)."); @@ -322,7 +322,7 @@ void IN_Init(void) Cvar_Register (&m_filter, "input controls"); Cvar_Register (&m_forcewheel, "Input Controls"); Cvar_Register (&m_forcewheel_threshold, "Input Controls"); - Cvar_Register (&m_strafeonright, "input controls"); + Cvar_Register (&m_touchstrafe, "input controls"); Cvar_Register (&m_fatpressthreshold, "input controls"); Cvar_Register (&m_slidethreshold, "input controls"); Cvar_Register (&m_touchmajoraxis, "input controls"); @@ -381,8 +381,20 @@ int IN_TranslateMButtonPress(unsigned int devid) } else { - //this is the key binding that the press should use - ret = (m_strafeonright.ival && ptr[devid].heldpos[0] > vid.pixelwidth/2)?K_MOUSE2:K_MOUSE1; + //translate touch to mouse2 if its on the strafing side of the screen. + switch(m_touchstrafe.ival) + { + case 2: + ret = ptr[devid].heldpos[0] < vid.pixelwidth/2; + break; + default: + ret = ptr[devid].heldpos[0] > vid.pixelwidth/2; + break; + case 0: + ret = false; + break; + } + ret = ret?K_MOUSE2:K_MOUSE1; } return ret; @@ -653,12 +665,28 @@ void IN_MoveMouse(struct mouse_s *mouse, float *movements, int pnum, float frame if (mouse->type == M_TOUCH) { - if (m_strafeonright.ival && mouse->heldpos[0] > vid.pixelwidth/2 && movements != NULL && !Key_Dest_Has(~kdm_game)) + qboolean strafing = false; + switch(m_touchstrafe.ival) + { + case 2: + strafing = mouse->heldpos[0] < vid.pixelwidth/2; + break; + default: + strafing = mouse->heldpos[0] > vid.pixelwidth/2; + break; + case 0: + strafing = true; + break; + } + if (strafing && movements != NULL && !Key_Dest_Has(~kdm_game)) { //if they're strafing, calculate the speed to move at based upon their displacement if (mouse->held) { - mx = mouse->oldpos[0] - (vid.pixelwidth*3)/4.0; + if (m_touchstrafe.ival) //left side + mx = mouse->oldpos[0] - (vid.pixelwidth*1)/4.0; + else //right side + mx = mouse->oldpos[0] - (vid.pixelwidth*3)/4.0; my = mouse->oldpos[1] - (vid.pixelheight*3)/4.0; //mx = (mouse->oldpos[0] - mouse->heldpos[0])*0.1; diff --git a/engine/client/m_download.c b/engine/client/m_download.c index 0f016a873..59a7e6ee3 100644 --- a/engine/client/m_download.c +++ b/engine/client/m_download.c @@ -2552,6 +2552,19 @@ void PM_ManifestPackage(const char *metaname, int security) manifestpackages = NULL; } +qboolean PM_CanInstall(const char *packagename) +{ + int i; + package_t *p = PM_FindPackage(packagename); + if (p && !(p->flags&(DPF_ENABLED|DPF_CORRUPT|DPF_HIDDEN))) + { + for (i = 0; i < countof(p->mirror); i++) + if (p->mirror[i]) + return true; + } + return false; +} + void PM_Command_f(void) { size_t i; diff --git a/engine/client/m_items.c b/engine/client/m_items.c index 30af90010..3a226ac18 100644 --- a/engine/client/m_items.c +++ b/engine/client/m_items.c @@ -1945,8 +1945,8 @@ static int M_Main_AddExtraOptions(menu_t *mainm, int y) {MC_AddConsoleCommandQBigFont(mainm, 72, y, "IRC ", "irc\n"); y += 20;} if (Cmd_Exists("qi")) {MC_AddConsoleCommandQBigFont(mainm, 72, y, "Quake Injector", "qi\n"); y += 20;} -// else if (PM_CanInstall("qi")) -// {MC_AddConsoleCommandQBigFont(mainm, 72, y, "Quake Injector", "pkg reset; pkg add qi; pkg apply\n"); y += 20;} + else if (PM_CanInstall("qi")) + {MC_AddConsoleCommandQBigFont(mainm, 72, y, "Get Quake Injector", "pkg reset; pkg add qi; pkg apply\n"); y += 20;} if (Cmd_Exists("menu_download")) {MC_AddConsoleCommandQBigFont(mainm, 72, y, "Updates ", "menu_download\n"); y += 20;} @@ -1957,9 +1957,10 @@ void M_Menu_Main_f (void) { extern cvar_t m_helpismedia; menubutton_t *b; - menu_t *mainm; + menu_t *mainm = NULL; mpic_t *p; static menuresel_t resel; + int y; #ifdef CSQC_DAT if (CSQC_ConsoleCommand(-1, va("%s %s", Cmd_Argv(0), Cmd_Args()))) @@ -2012,9 +2013,6 @@ void M_Menu_Main_f (void) mainm->key = MC_Main_Key; MC_AddPicture(mainm, 0, 4, 38, 166, "pics/m_main_plaque"); - p = R2D_SafeCachePic("pics/m_main_logo"); - if (!p) - return; MC_AddPicture(mainm, 0, 173, 36, 42, "pics/m_main_logo"); #ifndef CLIENTONLY MC_AddSelectablePicture(mainm, 68, 13, "pics/m_main_game"); @@ -2060,148 +2058,147 @@ void M_Menu_Main_f (void) if (M_GameType() == MGT_HEXEN2) { p = R2D_SafeCachePic("gfx/menu/title0.lmp"); - if (R_GetShaderSizes(p, NULL, NULL, true) <= 0) - return; + if (R_GetShaderSizes(p, NULL, NULL, true) > 0) + { + Key_Dest_Add(kdm_emenu); + mainm = M_CreateMenu(0); + mainm->key = MC_Main_Key; - Key_Dest_Add(kdm_emenu); - mainm = M_CreateMenu(0); - mainm->key = MC_Main_Key; - - MC_AddPicture(mainm, 16, 0, 35, 176, "gfx/menu/hplaque.lmp"); - MC_AddCenterPicture(mainm, 0, 60, "gfx/menu/title0.lmp"); + MC_AddPicture(mainm, 16, 0, 35, 176, "gfx/menu/hplaque.lmp"); + MC_AddCenterPicture(mainm, 0, 60, "gfx/menu/title0.lmp"); #ifndef CLIENTONLY - b=MC_AddConsoleCommandHexen2BigFont (mainm, 80, 64, "Single Player", "menu_single\n"); - mainm->selecteditem = (menuoption_t *)b; - b->common.width = 12*20; - b->common.height = 20; + b=MC_AddConsoleCommandHexen2BigFont (mainm, 80, 64, "Single Player", "menu_single\n"); + mainm->selecteditem = (menuoption_t *)b; + b->common.width = 12*20; + b->common.height = 20; #endif - b=MC_AddConsoleCommandHexen2BigFont (mainm, 80, 64+20, "MultiPlayer", "menu_multi\n"); + b=MC_AddConsoleCommandHexen2BigFont (mainm, 80, 64+20, "MultiPlayer", "menu_multi\n"); #ifdef CLIENTONLY - mainm->selecteditem = (menuoption_t *)b; + mainm->selecteditem = (menuoption_t *)b; #endif - b->common.width = 12*20; - b->common.height = 20; - b=MC_AddConsoleCommandHexen2BigFont (mainm, 80, 64+40, "Options", "menu_options\n"); - b->common.width = 12*20; - b->common.height = 20; - if (m_helpismedia.value) - b=MC_AddConsoleCommandHexen2BigFont (mainm, 80, 64+60, "Media", "menu_media\n"); - else - b=MC_AddConsoleCommandHexen2BigFont (mainm, 80, 64+60, "Help", "help\n"); - b->common.width = 12*20; - b->common.height = 20; - b=MC_AddConsoleCommandHexen2BigFont (mainm, 80, 64+80, "Quit", "menu_quit\n"); - b->common.width = 12*20; - b->common.height = 20; + b->common.width = 12*20; + b->common.height = 20; + b=MC_AddConsoleCommandHexen2BigFont (mainm, 80, 64+40, "Options", "menu_options\n"); + b->common.width = 12*20; + b->common.height = 20; + if (m_helpismedia.value) + b=MC_AddConsoleCommandHexen2BigFont (mainm, 80, 64+60, "Media", "menu_media\n"); + else + b=MC_AddConsoleCommandHexen2BigFont (mainm, 80, 64+60, "Help", "help\n"); + b->common.width = 12*20; + b->common.height = 20; + b=MC_AddConsoleCommandHexen2BigFont (mainm, 80, 64+80, "Quit", "menu_quit\n"); + b->common.width = 12*20; + b->common.height = 20; - mainm->cursoritem = (menuoption_t *)MC_AddCursor(mainm, &resel, 56, mainm->selecteditem->common.posy); + mainm->cursoritem = (menuoption_t *)MC_AddCursor(mainm, &resel, 56, mainm->selecteditem->common.posy); + } } else #endif if (QBigFontWorks()) { - int y; - Key_Dest_Add(kdm_emenu); - mainm = M_CreateMenu(0); - p = R2D_SafeCachePic("gfx/ttl_main.lmp"); - if (R_GetShaderSizes(p, NULL, NULL, true) <= 0) + if (R_GetShaderSizes(p, NULL, NULL, true) > 0) { - MC_AddRedText(mainm, 16, 170, 0, "MAIN MENU", false); + Key_Dest_Add(kdm_emenu); + mainm = M_CreateMenu(0); + mainm->key = MC_Main_Key; + MC_AddPicture(mainm, 16, 4, 32, 144, "gfx/qplaque.lmp"); + MC_AddCenterPicture(mainm, 4, 24, "gfx/ttl_main.lmp"); + + y = 32; mainm->selecteditem = (menuoption_t *) - MC_AddConsoleCommand (mainm, 64, 170, 32, "Join server", "menu_servers\n"); - MC_AddConsoleCommand (mainm, 64, 170, 40, "Options", "menu_options\n"); - MC_AddConsoleCommand (mainm, 64, 170, 48, "Quit", "menu_quit\n"); - return; - } - mainm->key = MC_Main_Key; - MC_AddPicture(mainm, 16, 4, 32, 144, "gfx/qplaque.lmp"); - - MC_AddCenterPicture(mainm, 4, 24, "gfx/ttl_main.lmp"); - - y = 32; - mainm->selecteditem = (menuoption_t *) #ifndef CLIENTONLY - MC_AddConsoleCommandQBigFont (mainm, 72, y, "Single ", "menu_single\n"); y += 20; + MC_AddConsoleCommandQBigFont (mainm, 72, y, "Single ", "menu_single\n"); y += 20; #endif - MC_AddConsoleCommandQBigFont (mainm, 72, y, "Multiplayer ", "menu_multi\n"); y += 20; - MC_AddConsoleCommandQBigFont (mainm, 72, y, "Options ", "menu_options\n"); y += 20; - if (m_helpismedia.value) - {MC_AddConsoleCommandQBigFont(mainm, 72, y, "Media ", "menu_media\n"); y += 20;} - else - {MC_AddConsoleCommandQBigFont(mainm, 72, y, "Help ", "help\n"); y += 20;} - y = M_Main_AddExtraOptions(mainm, y); + MC_AddConsoleCommandQBigFont (mainm, 72, y, "Multiplayer ", "menu_multi\n"); y += 20; + MC_AddConsoleCommandQBigFont (mainm, 72, y, "Options ", "menu_options\n"); y += 20; + if (m_helpismedia.value) + {MC_AddConsoleCommandQBigFont(mainm, 72, y, "Media ", "menu_media\n"); y += 20;} + else + {MC_AddConsoleCommandQBigFont(mainm, 72, y, "Help ", "help\n"); y += 20;} + y = M_Main_AddExtraOptions(mainm, y); #ifdef FTE_TARGET_WEB - MC_AddConsoleCommandQBigFont (mainm, 72, y, "Save Settings ", "menu_quit\n"); y += 20; + MC_AddConsoleCommandQBigFont (mainm, 72, y, "Save Settings ", "menu_quit\n"); y += 20; #else - MC_AddConsoleCommandQBigFont (mainm, 72, y, "Quit ", "menu_quit\n"); y += 20; + MC_AddConsoleCommandQBigFont (mainm, 72, y, "Quit ", "menu_quit\n"); y += 20; #endif - mainm->cursoritem = (menuoption_t *)MC_AddCursor(mainm, &resel, 54, 32); + mainm->cursoritem = (menuoption_t *)MC_AddCursor(mainm, &resel, 54, 32); + } } else { int width; - Key_Dest_Add(kdm_emenu); - mainm = M_CreateMenu(0); - p = R2D_SafeCachePic("gfx/mainmenu.lmp"); R2D_SafeCachePic("gfx/ttl_main.lmp"); - if (R_GetShaderSizes(p, &width, NULL, true) <= 0) + if (R_GetShaderSizes(p, &width, NULL, true) > 0) { - MC_AddRedText(mainm, 16, 170, 0, "MAIN MENU", false); + Key_Dest_Add(kdm_emenu); + mainm = M_CreateMenu(0); - mainm->selecteditem = (menuoption_t *) - MC_AddConsoleCommand (mainm, 64, 170, 32, "Join server", "menu_servers\n"); - MC_AddConsoleCommand (mainm, 64, 170, 40, "Options", "menu_options\n"); - MC_AddConsoleCommand (mainm, 64, 170, 48, "Quit", "menu_quit\n"); - return; - } - mainm->key = MC_Main_Key; - MC_AddPicture(mainm, 16, 4, 32, 144, "gfx/qplaque.lmp"); + mainm->key = MC_Main_Key; + MC_AddPicture(mainm, 16, 4, 32, 144, "gfx/qplaque.lmp"); - MC_AddCenterPicture(mainm, 4, 24, "gfx/ttl_main.lmp"); - MC_AddPicture(mainm, 72, 32, 240, 112, "gfx/mainmenu.lmp"); + MC_AddCenterPicture(mainm, 4, 24, "gfx/ttl_main.lmp"); + MC_AddPicture(mainm, 72, 32, 240, 112, "gfx/mainmenu.lmp"); - b=MC_AddConsoleCommand (mainm, 72, 312, 32, "", "menu_single\n"); - b->common.tooltip = "Start singleplayer Quake game."; - mainm->selecteditem = (menuoption_t *)b; - b->common.width = width; - b->common.height = 20; - b=MC_AddConsoleCommand (mainm, 72, 312, 52, "", "menu_multi\n"); - b->common.tooltip = "Multiplayer menu."; - b->common.width = width; - b->common.height = 20; - b=MC_AddConsoleCommand (mainm, 72, 312, 72, "", "menu_options\n"); - b->common.tooltip = "Options menu."; - b->common.width = width; - b->common.height = 20; - if (m_helpismedia.value) - { - b=MC_AddConsoleCommand(mainm, 72, 312, 92, "", "menu_media\n"); - b->common.tooltip = "Media menu."; - } - else - { - b=MC_AddConsoleCommand(mainm, 72, 312, 92, "", "help\n"); - b->common.tooltip = "Help menu."; - } - b->common.width = width; - b->common.height = 20; - b=MC_AddConsoleCommand (mainm, 72, 312, 112, "", "menu_quit\n"); + b=MC_AddConsoleCommand (mainm, 72, 312, 32, "", "menu_single\n"); + b->common.tooltip = "Start singleplayer Quake game."; + mainm->selecteditem = (menuoption_t *)b; + b->common.width = width; + b->common.height = 20; + b=MC_AddConsoleCommand (mainm, 72, 312, 52, "", "menu_multi\n"); + b->common.tooltip = "Multiplayer menu."; + b->common.width = width; + b->common.height = 20; + b=MC_AddConsoleCommand (mainm, 72, 312, 72, "", "menu_options\n"); + b->common.tooltip = "Options menu."; + b->common.width = width; + b->common.height = 20; + if (m_helpismedia.value) + { + b=MC_AddConsoleCommand(mainm, 72, 312, 92, "", "menu_media\n"); + b->common.tooltip = "Media menu."; + } + else + { + b=MC_AddConsoleCommand(mainm, 72, 312, 92, "", "help\n"); + b->common.tooltip = "Help menu."; + } + b->common.width = width; + b->common.height = 20; + b=MC_AddConsoleCommand (mainm, 72, 312, 112, "", "menu_quit\n"); #ifdef FTE_TARGET_WEB - b->common.tooltip = "Save settings to local storage."; + b->common.tooltip = "Save settings to local storage."; #else - b->common.tooltip = "Exit to DOS."; + b->common.tooltip = "Exit to DOS."; #endif - b->common.width = width; - b->common.height = 20; + b->common.width = width; + b->common.height = 20; - M_Main_AddExtraOptions(mainm, 112+20); + M_Main_AddExtraOptions(mainm, 112+20); - mainm->cursoritem = (menuoption_t *)MC_AddCursor(mainm, &resel, 54, 32); + mainm->cursoritem = (menuoption_t *)MC_AddCursor(mainm, &resel, 54, 32); + } + } + + if (!mainm) + { + Key_Dest_Add(kdm_emenu); + mainm = M_CreateMenu(0); + MC_AddRedText(mainm, 16, 170, 0, "MAIN MENU", false); + + y = 36; + mainm->selecteditem = (menuoption_t *) + //skip menu_single if we don't seem to have any content. + MC_AddConsoleCommandQBigFont (mainm, 72, y, "Join server", "menu_servers\n"); y += 20; + MC_AddConsoleCommandQBigFont (mainm, 72, y, "Options", "menu_options\n"); y += 20; + y = M_Main_AddExtraOptions(mainm, y); + MC_AddConsoleCommandQBigFont (mainm, 72, y, "Quit", "menu_quit\n"); y += 20; } if (!m_preset_chosen.ival) diff --git a/engine/client/renderer.c b/engine/client/renderer.c index 7ce2ef72b..9c5a1e12f 100644 --- a/engine/client/renderer.c +++ b/engine/client/renderer.c @@ -574,7 +574,6 @@ void GLRenderer_Init(void) Cvar_Register (&r_lightmap_nearest, GLRENDEREROPTIONS); Cvar_Register (&r_lightmap_average, GLRENDEREROPTIONS); - Cvar_Register (&r_lightmap_format, GLRENDEREROPTIONS); } #endif @@ -848,6 +847,7 @@ void Renderer_Init(void) Cvar_Register(&r_lightstylespeed, GRAPHICALNICETIES); Cvar_Register(&r_lightstylescale, GRAPHICALNICETIES); Cvar_Register(&r_lightmap_scale, GRAPHICALNICETIES); + Cvar_Register(&r_lightmap_format, GRAPHICALNICETIES); Cvar_Register(&r_hdr_framebuffer, GRAPHICALNICETIES); Cvar_Register(&r_hdr_irisadaptation, GRAPHICALNICETIES); @@ -1790,16 +1790,34 @@ TRACE(("dbg: R_ApplyRenderer: efrags\n")); void R_ReloadRenderer_f (void) { + void *portalblob = NULL; + size_t portalsize = 0; float time = Sys_DoubleTime(); if (qrenderer == QR_NONE || qrenderer == QR_HEADLESS) return; //don't bother reloading the renderer if its not actually rendering anything anyway. + if (sv.state == ss_active && sv.world.worldmodel && sv.world.worldmodel->loadstate == MLS_LOADED) + { + void *t; + portalsize = CM_WritePortalState(sv.world.worldmodel, &t); + if (portalsize && (portalblob = BZ_Malloc(portalsize))) + memcpy(portalblob, t, portalsize); + } + Cvar_ApplyLatches(CVAR_VIDEOLATCH|CVAR_RENDERERLATCH); R_ShutdownRenderer(false); Con_DPrintf("teardown = %f\n", Sys_DoubleTime() - time); //reloads textures without destroying video context. R_ApplyRenderer_Load(NULL); Cvar_ApplyCallbacks(CVAR_RENDERERCALLBACK); + + + if (portalblob) + { + if (sv.world.worldmodel && sv.world.worldmodel->loadstate == MLS_LOADED) + CM_ReadPortalState(sv.world.worldmodel, portalblob, portalsize); + BZ_Free(portalblob); + } } //use Cvar_ApplyLatches(CVAR_RENDERERLATCH) beforehand. @@ -2002,6 +2020,8 @@ qboolean R_BuildRenderstate(rendererstate_t *newr, char *rendererstring) void R_RestartRenderer (rendererstate_t *newr) { + void *portalblob = NULL; + size_t portalsize = 0; rendererstate_t oldr; if (r_blockvidrestart) { @@ -2009,6 +2029,14 @@ void R_RestartRenderer (rendererstate_t *newr) return; } + if (sv.state == ss_active && sv.world.worldmodel && sv.world.worldmodel->loadstate == MLS_LOADED) + { + void *t; + portalsize = CM_WritePortalState(sv.world.worldmodel, &t); + if (portalsize && (portalblob = BZ_Malloc(portalsize))) + memcpy(portalblob, t, portalsize); + } + TRACE(("dbg: R_RestartRenderer_f renderer %p\n", newr->renderer)); memcpy(&oldr, ¤trendererstate, sizeof(rendererstate_t)); @@ -2083,6 +2111,13 @@ void R_RestartRenderer (rendererstate_t *newr) } } + if (portalblob) + { + if (sv.world.worldmodel && sv.world.worldmodel->loadstate == MLS_LOADED) + CM_ReadPortalState(sv.world.worldmodel, portalblob, portalsize); + BZ_Free(portalblob); + } + Cvar_ApplyCallbacks(CVAR_RENDERERCALLBACK); SCR_EndLoadingPlaque(); diff --git a/engine/common/common.h b/engine/common/common.h index 8590dae11..c35ff5ebb 100644 --- a/engine/common/common.h +++ b/engine/common/common.h @@ -681,6 +681,7 @@ void FS_Manifest_Free(ftemanifest_t *man); ftemanifest_t *FS_Manifest_Parse(const char *fname, const char *data); void PM_Shutdown(void); void PM_Command_f(void); +qboolean PM_CanInstall(const char *packagename); void COM_InitFilesystem (void); //does not set up any gamedirs. qboolean FS_DownloadingPackage(void); diff --git a/engine/common/gl_q2bsp.c b/engine/common/gl_q2bsp.c index 0d200a7b4..d89bf239d 100644 --- a/engine/common/gl_q2bsp.c +++ b/engine/common/gl_q2bsp.c @@ -5972,6 +5972,13 @@ static trace_t CM_BoxTrace (model_t *mod, vec3_t start, vec3_t end, trace_extents[2] = ((-trace_mins[2] > trace_maxs[2]) ? -trace_mins[2] : trace_maxs[2])+1; } + trace_absmins[0] -= 1.0; + trace_absmins[1] -= 1.0; + trace_absmins[2] -= 1.0; + trace_absmaxs[0] += 1.0; + trace_absmaxs[1] += 1.0; + trace_absmaxs[2] += 1.0; + #if 0 if (0) { //treat *ALL* tests against the actual geometry instead of using any brushes. @@ -6003,18 +6010,9 @@ static trace_t CM_BoxTrace (model_t *mod, vec3_t start, vec3_t end, { int leafs[1024]; int i, numleafs; - vec3_t c1, c2; int topnode; - VectorAdd (trace_start, mins, c1); - VectorAdd (trace_start, maxs, c2); - for (i=0 ; i<3 ; i++) - { - c1[i] -= 1; - c2[i] += 1; - } - - numleafs = CM_BoxLeafnums_headnode (mod, c1, c2, leafs, sizeof(leafs)/sizeof(leafs[0]), mod->hulls[0].firstclipnode, &topnode); + numleafs = CM_BoxLeafnums_headnode (mod, trace_absmins, trace_absmaxs, leafs, sizeof(leafs)/sizeof(leafs[0]), mod->hulls[0].firstclipnode, &topnode); for (i=0 ; imeshinfo, &mod->leafs[leafs[i]]); @@ -6620,13 +6618,30 @@ int CM_WriteAreaBits (model_t *mod, qbyte *buffer, int area, qboolean merge) =================== CM_WritePortalState -Writes the portal state to a savegame file +Returns a size+pointer to the data that needs to be written into a saved game. =================== */ -void CM_WritePortalState (model_t *mod, vfsfile_t *f) +size_t CM_WritePortalState (model_t *mod, void **data) { cminfo_t *prv = (cminfo_t*)mod->meshinfo; - VFS_WRITE(f, prv->portalopen, sizeof(prv->portalopen)); + + if (mod->type == mod_brush && (mod->fromgame == fg_quake2 || mod->fromgame == fg_quake3)) + { +#ifdef Q3BSPS + if (prv->mapisq3) + { //endian issues. oh well. + *data = prv->q3areas; + return sizeof(prv->q3areas); + } + else +#endif + { + *data = prv->portalopen; + return sizeof(prv->portalopen); + } + } + *data = NULL; + return 0; } /* @@ -6641,14 +6656,34 @@ qofs_t CM_ReadPortalState (model_t *mod, qbyte *ptr, qofs_t ptrsize) { cminfo_t *prv = (cminfo_t*)mod->meshinfo; - if (ptrsize < sizeof(prv->portalopen)) - Con_Printf("CM_ReadPortalState() expected %u, but only %u available\n",(unsigned int)sizeof(prv->portalopen),(unsigned int)ptrsize); - else + if (mod->type == mod_brush && (mod->fromgame == fg_quake2 || mod->fromgame == fg_quake3)) { - memcpy(prv->portalopen, ptr, sizeof(prv->portalopen)); +#ifdef Q3BSPS + if (prv->mapisq3) + { + if (ptrsize < sizeof(prv->q3areas)) + Con_Printf("CM_ReadPortalState() expected %u, but only %u available\n",(unsigned int)sizeof(prv->q3areas),(unsigned int)ptrsize); + else + { + memcpy(prv->q3areas, ptr, sizeof(prv->q3areas)); - FloodAreaConnections (prv); - return sizeof(prv->portalopen); + FloodAreaConnections (prv); + return sizeof(prv->portalopen); + } + } + else +#endif + { + if (ptrsize < sizeof(prv->portalopen)) + Con_Printf("CM_ReadPortalState() expected %u, but only %u available\n",(unsigned int)sizeof(prv->portalopen),(unsigned int)ptrsize); + else + { + memcpy(prv->portalopen, ptr, sizeof(prv->portalopen)); + + FloodAreaConnections (prv); + return sizeof(prv->portalopen); + } + } } return 0; } diff --git a/engine/common/pr_bgcmd.c b/engine/common/pr_bgcmd.c index 6427f922b..212559582 100644 --- a/engine/common/pr_bgcmd.c +++ b/engine/common/pr_bgcmd.c @@ -6702,7 +6702,7 @@ lh_extension_t QSG_Extensions[] = { {"FTE_QUAKE3_SERVER", 0, NULL, {NULL}, "This engine is able to act as a quake3 server"}, #endif {"FTE_SOLID_LADDER", NOBI "Allows a simple trigger to remove effects of gravity (solid 20). obsolete. will prolly be removed at some point as it is not networked properly. Use FTE_ENT_SKIN_CONTENTS"}, - {"FTE_SPLITSCREEN", NOBI "Client supports splitscreen, controlled via cl_splitclients. Servers require allow_splitscreen 1 if splitscreen is to be used over the internet. Mods that use csqc will need to be aware for this to work properly. per-client networking may be problematic."}, + {"FTE_SPLITSCREEN", NOBI "Client supports splitscreen, controlled via cl_splitscreen. Servers require allow_splitscreen 1 if splitscreen is to be used over the internet. Mods that use csqc will need to be aware for this to work properly. per-client networking may be problematic."}, #ifdef SQL // serverside SQL functions for managing an SQL database connection diff --git a/engine/gl/gl_model.h b/engine/gl/gl_model.h index 4a1b3e013..9dc32cb7c 100644 --- a/engine/gl/gl_model.h +++ b/engine/gl/gl_model.h @@ -1108,7 +1108,7 @@ void CMQ2_SetAreaPortalState (model_t *mod, unsigned int portalnum, qboolean ope void CMQ3_SetAreaPortalState (model_t *mod, unsigned int area1, unsigned int area2, qboolean open); //for saved games to write the raw state. -void CM_WritePortalState (model_t *mod, vfsfile_t *f); +size_t CM_WritePortalState (model_t *mod, void **data); qofs_t CM_ReadPortalState (model_t *mod, qbyte *ptr, qofs_t ptrsize); #endif diff --git a/engine/server/savegame.c b/engine/server/savegame.c index 1815e5deb..72eb2f8ca 100644 --- a/engine/server/savegame.c +++ b/engine/server/savegame.c @@ -972,6 +972,8 @@ void SV_SaveLevelCache(const char *savedir, qboolean dontharmgame) f = FS_OpenVFS (name, "wbp", FS_GAMEONLY); if (f) { + size_t portalblobsize; + void *portalblob = NULL; for (i = 0; i < countof(sv.strings.configstring); i++) { if (sv.strings.configstring[i]) @@ -996,7 +998,9 @@ void SV_SaveLevelCache(const char *savedir, qboolean dontharmgame) } VFS_WRITE(f, "", 1); - CM_WritePortalState(sv.world.worldmodel, f); + portalblobsize = CM_WritePortalState(sv.world.worldmodel, &portalblob); + VFS_WRITE(f, portalblob, portalblobsize); + VFS_CLOSE(f); } diff --git a/engine/server/sv_move.c b/engine/server/sv_move.c index 00007e4d7..e6e83c839 100644 --- a/engine/server/sv_move.c +++ b/engine/server/sv_move.c @@ -709,6 +709,8 @@ static struct waypointnetwork_s *WayNet_Begin(void **ctxptr, model_t *worldmodel } if (!wf) wf = FS_MallocFile(va("%s.way", worldmodel->name), FS_GAME, NULL); + if (!wf) + return NULL; l = wf; //read the number of waypoints diff --git a/engine/vk/vk_init.c b/engine/vk/vk_init.c index 058b81aea..954eb53ce 100644 --- a/engine/vk/vk_init.c +++ b/engine/vk/vk_init.c @@ -311,6 +311,9 @@ static qboolean VK_CreateSwapChain(void) VkFramebufferCreateInfo fb_info = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO}; VkSampleCountFlagBits oldms; + VkFormat oldformat = vk.backbufformat; + VkFormat olddepthformat = vk.depthformat; + vk.dopresent(NULL); //make sure they're all pushed through. @@ -695,7 +698,8 @@ static qboolean VK_CreateSwapChain(void) } #endif - if (oldms != vk.multisamplebits) + //destroy+recreate the renderpass if something changed that prevents them being compatible (this also requires rebuilding all the pipelines too, which sucks). + if (oldms != vk.multisamplebits || oldformat != vk.backbufformat || olddepthformat != vk.depthformat) { VK_DestroyRenderPass(); reloadshaders = true;