diff --git a/src/console.c b/src/console.c index 67d995f98..cbfcb6e38 100644 --- a/src/console.c +++ b/src/console.c @@ -76,7 +76,6 @@ static UINT8 con_hudlines; // number of console heads up message li static UINT32 con_hudtime[MAXHUDLINES]; // remaining time of display for hud msg lines INT32 con_clearlines; // top screen lines to refresh when view reduced - boolean con_hudupdate; // when messages scroll, we need a backgrnd refresh // console text output static char *con_line; // console text output current line @@ -1348,9 +1347,6 @@ static void CON_Linefeed(void) con_line = &con_buffer[(con_cy%con_totallines)*con_width]; memset(con_line, ' ', con_width); - - // make sure the view borders are refreshed if hud messages scroll - con_hudupdate = true; // see HU_Erase() } // Outputs text into the console text buffer @@ -1579,13 +1575,6 @@ void CONS_Debug(INT32 debugflags, const char *fmt, ...) // void CONS_Error(const char *msg) { -#if defined(RPC_NO_WINDOWS_H) && defined(_WINDOWS) - if (!graphics_started) - { - MessageBoxA(vid.WndParent, msg, "SRB2 Warning", MB_OK); - return; - } -#endif CONS_Printf("\x82%s", msg); // write error msg in different colour CONS_Printf(M_GetText("Press ENTER to continue\n")); @@ -1809,7 +1798,6 @@ static void CON_DrawConsole(void) //FIXME: refresh borders only when console bg is translucent con_clearlines = con_curlines; // clear console draw from view borders - con_hudupdate = true; // always refresh while console is on // draw console background if (cons_backpic.value || con_forcepic) diff --git a/src/console.h b/src/console.h index f22f8dcbc..2794770eb 100644 --- a/src/console.h +++ b/src/console.h @@ -41,7 +41,6 @@ extern INT32 con_clipviewtop; extern INT32 con_destlines; extern INT32 con_clearlines; // lines of top of screen to refresh -extern boolean con_hudupdate; // hud messages have changed, need refresh extern UINT32 con_scalefactor; // console text scale factor extern consvar_t cons_backcolor; diff --git a/src/d_main.c b/src/d_main.c index 5861f9886..e3143d22c 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -325,7 +325,7 @@ static void D_Display(void) // 4. The frame is ready to be drawn! // Check for change of renderer or screen size (video mode) - if ((setrenderneeded || setmodeneeded) && !wipe) + if (vid.change.set && !wipe) SCR_SetMode(); // change video mode // Recalc the screen @@ -405,13 +405,11 @@ static void D_Display(void) case GS_LEVEL: if (!gametic) break; - HU_Erase(); AM_Drawer(); break; case GS_INTERMISSION: Y_IntermissionDrawer(); - HU_Erase(); HU_Drawer(); break; @@ -426,13 +424,11 @@ static void D_Display(void) case GS_ENDING: F_EndingDrawer(); - HU_Erase(); HU_Drawer(); break; case GS_CUTSCENE: F_CutsceneDrawer(); - HU_Erase(); HU_Drawer(); break; @@ -442,7 +438,6 @@ static void D_Display(void) case GS_EVALUATION: F_GameEvaluationDrawer(); - HU_Erase(); HU_Drawer(); break; @@ -452,7 +447,6 @@ static void D_Display(void) case GS_CREDITS: F_CreditDrawer(); - HU_Erase(); HU_Drawer(); break; diff --git a/src/dummy/i_video.c b/src/dummy/i_video.c index 3b0a12a32..3a1cbd223 100644 --- a/src/dummy/i_video.c +++ b/src/dummy/i_video.c @@ -35,9 +35,10 @@ INT32 VID_GetModeForSize(INT32 w, INT32 h) void VID_PrepareModeList(void){} -INT32 VID_SetMode(INT32 modenum) +void VID_SetSize(INT32 width, INT32 height) { - (void)modenum; + (void)width; + (void)height; return 0; } diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index eb0b9e332..d9a0fefe6 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -22,7 +22,7 @@ #include "hw_drv.h" #include "../m_misc.h" //FIL_WriteFile() -#include "../r_draw.h" //viewborderlump +#include "../r_draw.h" #include "../r_main.h" #include "../w_wad.h" #include "../z_zone.h" @@ -1005,136 +1005,6 @@ void HWR_DrawTutorialBack(UINT32 color, INT32 boxheight) HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest); } - -// ========================================================================== -// R_DRAW.C STUFF -// ========================================================================== - -// ------------------ -// HWR_DrawViewBorder -// Fill the space around the view window with a Doom flat texture, draw the -// beveled edges. -// 'clearlines' is useful to clear the heads up messages, when the view -// window is reduced, it doesn't refresh all the view borders. -// ------------------ -void HWR_DrawViewBorder(INT32 clearlines) -{ - INT32 x, y; - INT32 top, side; - INT32 baseviewwidth, baseviewheight; - INT32 basewindowx, basewindowy; - patch_t *patch; - -// if (gl_viewwidth == vid.width) -// return; - - if (!clearlines) - clearlines = BASEVIDHEIGHT; // refresh all - - // calc view size based on original game resolution - baseviewwidth = FixedInt(FixedDiv(FLOAT_TO_FIXED(gl_viewwidth), vid.fdupx)); //(cv_viewsize.value * BASEVIDWIDTH/10)&~7; - baseviewheight = FixedInt(FixedDiv(FLOAT_TO_FIXED(gl_viewheight), vid.fdupy)); - top = FixedInt(FixedDiv(FLOAT_TO_FIXED(gl_baseviewwindowy), vid.fdupy)); - side = FixedInt(FixedDiv(FLOAT_TO_FIXED(gl_viewwindowx), vid.fdupx)); - - // top - HWR_DrawFlatFill(0, 0, - BASEVIDWIDTH, (top < clearlines ? top : clearlines), - st_borderpatchnum); - - // left - if (top < clearlines) - HWR_DrawFlatFill(0, top, side, - (clearlines-top < baseviewheight ? clearlines-top : baseviewheight), - st_borderpatchnum); - - // right - if (top < clearlines) - HWR_DrawFlatFill(side + baseviewwidth, top, side, - (clearlines-top < baseviewheight ? clearlines-top : baseviewheight), - st_borderpatchnum); - - // bottom - if (top + baseviewheight < clearlines) - HWR_DrawFlatFill(0, top + baseviewheight, - BASEVIDWIDTH, BASEVIDHEIGHT, st_borderpatchnum); - - // - // draw the view borders - // - - basewindowx = (BASEVIDWIDTH - baseviewwidth)>>1; - if (baseviewwidth == BASEVIDWIDTH) - basewindowy = 0; - else - basewindowy = top; - - // top edge - if (clearlines > basewindowy - 8) - { - patch = W_CachePatchNum(viewborderlump[BRDR_T], PU_PATCH); - for (x = 0; x < baseviewwidth; x += 8) - HWR_DrawPatch(patch, basewindowx + x, basewindowy - 8, - 0); - } - - // bottom edge - if (clearlines > basewindowy + baseviewheight) - { - patch = W_CachePatchNum(viewborderlump[BRDR_B], PU_PATCH); - for (x = 0; x < baseviewwidth; x += 8) - HWR_DrawPatch(patch, basewindowx + x, - basewindowy + baseviewheight, 0); - } - - // left edge - if (clearlines > basewindowy) - { - patch = W_CachePatchNum(viewborderlump[BRDR_L], PU_PATCH); - for (y = 0; y < baseviewheight && basewindowy + y < clearlines; - y += 8) - { - HWR_DrawPatch(patch, basewindowx - 8, basewindowy + y, - 0); - } - } - - // right edge - if (clearlines > basewindowy) - { - patch = W_CachePatchNum(viewborderlump[BRDR_R], PU_PATCH); - for (y = 0; y < baseviewheight && basewindowy+y < clearlines; - y += 8) - { - HWR_DrawPatch(patch, basewindowx + baseviewwidth, - basewindowy + y, 0); - } - } - - // Draw beveled corners. - if (clearlines > basewindowy - 8) - HWR_DrawPatch(W_CachePatchNum(viewborderlump[BRDR_TL], - PU_PATCH), - basewindowx - 8, basewindowy - 8, 0); - - if (clearlines > basewindowy - 8) - HWR_DrawPatch(W_CachePatchNum(viewborderlump[BRDR_TR], - PU_PATCH), - basewindowx + baseviewwidth, basewindowy - 8, 0); - - if (clearlines > basewindowy+baseviewheight) - HWR_DrawPatch(W_CachePatchNum(viewborderlump[BRDR_BL], - PU_PATCH), - basewindowx - 8, basewindowy + baseviewheight, 0); - - if (clearlines > basewindowy + baseviewheight) - HWR_DrawPatch(W_CachePatchNum(viewborderlump[BRDR_BR], - PU_PATCH), - basewindowx + baseviewwidth, - basewindowy + baseviewheight, 0); -} - - // ========================================================================== // AM_MAP.C DRAWING STUFF // ========================================================================== diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 091e2b2fb..38e55872a 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -2051,76 +2051,6 @@ void HU_Drawer(void) } } -//====================================================================== -// HUD MESSAGES CLEARING FROM SCREEN -//====================================================================== - -// Clear old messages from the borders around the view window -// (only for reduced view, refresh the borders when needed) -// -// startline: y coord to start clear, -// clearlines: how many lines to clear. -// -static INT32 oldclearlines; - -void HU_Erase(void) -{ - INT32 topline, bottomline; - INT32 y, yoffset; - -#ifdef HWRENDER - // clear hud msgs on double buffer (OpenGL mode) - boolean secondframe; - static INT32 secondframelines; -#endif - - if (con_clearlines == oldclearlines && !con_hudupdate && !chat_on) - return; - -#ifdef HWRENDER - // clear the other frame in double-buffer modes - secondframe = (con_clearlines != oldclearlines); - if (secondframe) - secondframelines = oldclearlines; -#endif - - // clear the message lines that go away, so use _oldclearlines_ - bottomline = oldclearlines; - oldclearlines = con_clearlines; - if (chat_on && OLDCHAT) - if (bottomline < 8) - bottomline = 8; // only do it for consolechat. consolechat is gay. - - if (automapactive || viewwindowx == 0) // hud msgs don't need to be cleared - return; - - // software mode copies view border pattern & beveled edges from the backbuffer - if (rendermode == render_soft) - { - topline = 0; - for (y = topline, yoffset = y*vid.width; y < bottomline; y++, yoffset += vid.width) - { - if (y < viewwindowy || y >= viewwindowy + viewheight) - R_VideoErase(yoffset, vid.width); // erase entire line - else - { - R_VideoErase(yoffset, viewwindowx); // erase left border - // erase right border - R_VideoErase(yoffset + viewwindowx + viewwidth, viewwindowx); - } - } - con_hudupdate = false; // if it was set.. - } -#ifdef HWRENDER - else if (rendermode != render_none) - { - // refresh just what is needed from the view borders - HWR_DrawViewBorder(secondframelines); - con_hudupdate = secondframe; - } -#endif -} - //====================================================================== // IN-LEVEL MULTIPLAYER RANKINGS //====================================================================== diff --git a/src/hu_stuff.h b/src/hu_stuff.h index 8647e4500..b3069c215 100644 --- a/src/hu_stuff.h +++ b/src/hu_stuff.h @@ -111,7 +111,6 @@ boolean HU_Responder(event_t *ev); void HU_Ticker(void); void HU_Drawer(void); char HU_dequeueChatChar(void); -void HU_Erase(void); void HU_clearChatChars(void); void HU_drawPing(INT32 x, INT32 y, UINT32 ping, boolean notext, INT32 flags); // Lat': Ping drawer for scoreboard. void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer); diff --git a/src/i_video.h b/src/i_video.h index 8efca5f9a..117961e1d 100644 --- a/src/i_video.h +++ b/src/i_video.h @@ -73,20 +73,9 @@ INT32 VID_NumModes(void); */ INT32 VID_GetModeForSize(INT32 w, INT32 h); - -/** \brief The VID_SetMode function - - Set the video mode right now, - the video mode change is delayed until the start of the next refresh - by setting the setmodeneeded to a value >0 - setup a video mode, this is to be called from the menu - - - \param modenum video mode to set to - - \return current video mode +/** \brief Changes the current resolution */ -INT32 VID_SetMode(INT32 modenum); +void VID_SetSize(INT32 width, INT32 height); /** \brief Checks the render state \return true if the renderer changed diff --git a/src/m_menu.c b/src/m_menu.c index 12003f945..6c75936d0 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -167,7 +167,8 @@ static INT32 (*setupcontrols)[2]; // pointer to the gamecontrols of the play // shhh... what am I doing... nooooo! static INT32 vidm_testingmode = 0; -static INT32 vidm_previousmode; +static INT32 vidm_previouswidth; +static INT32 vidm_previousheight; static INT32 vidm_selected = 0; static INT32 vidm_nummodes; static INT32 vidm_column_size; @@ -3872,7 +3873,7 @@ void M_Ticker(void) { // restore the previous video mode if (--vidm_testingmode == 0) - setmodeneeded = vidm_previousmode + 1; + SCR_ChangeResolution(vidm_previouswidth, vidm_previousheight); } if (currentMenu == &OP_ScreenshotOptionsDef) @@ -4106,53 +4107,6 @@ void M_DrawTextBox(INT32 x, INT32 y, INT32 width, INT32 boxlines) { // Solid color textbox. V_DrawFill(x+5, y+5, width*8+6, boxlines*8+6, 159); - //V_DrawFill(x+8, y+8, width*8, boxlines*8, 31); -/* - patch_t *p; - INT32 cx, cy, n; - INT32 step, boff; - - step = 8; - boff = 8; - - // draw left side - cx = x; - cy = y; - V_DrawScaledPatch(cx, cy, 0, W_CachePatchNum(viewborderlump[BRDR_TL], PU_PATCH)); - cy += boff; - p = W_CachePatchNum(viewborderlump[BRDR_L], PU_PATCH); - for (n = 0; n < boxlines; n++) - { - V_DrawScaledPatch(cx, cy, 0, p); - cy += step; - } - V_DrawScaledPatch(cx, cy, 0, W_CachePatchNum(viewborderlump[BRDR_BL], PU_PATCH)); - - // draw middle - V_DrawFlatFill(x + boff, y + boff, width*step, boxlines*step, st_borderpatchnum); - - cx += boff; - cy = y; - while (width > 0) - { - V_DrawScaledPatch(cx, cy, 0, W_CachePatchNum(viewborderlump[BRDR_T], PU_PATCH)); - V_DrawScaledPatch(cx, y + boff + boxlines*step, 0, W_CachePatchNum(viewborderlump[BRDR_B], PU_PATCH)); - width--; - cx += step; - } - - // draw right side - cy = y; - V_DrawScaledPatch(cx, cy, 0, W_CachePatchNum(viewborderlump[BRDR_TR], PU_PATCH)); - cy += boff; - p = W_CachePatchNum(viewborderlump[BRDR_R], PU_PATCH); - for (n = 0; n < boxlines; n++) - { - V_DrawScaledPatch(cx, cy, 0, p); - cy += step; - } - V_DrawScaledPatch(cx, cy, 0, W_CachePatchNum(viewborderlump[BRDR_BR], PU_PATCH)); -*/ } static fixed_t staticalong = 0; @@ -13375,8 +13329,7 @@ static modedesc_t modedescs[MAXMODEDESCS]; static void M_VideoModeMenu(INT32 choice) { - INT32 i, j, vdup, nummodes, width, height; - const char *desc; + INT32 i; (void)choice; @@ -13385,66 +13338,33 @@ static void M_VideoModeMenu(INT32 choice) #if defined (__unix__) || defined (UNIXCOMMON) || defined (HAVE_SDL) VID_PrepareModeList(); // FIXME: hack #endif + vidm_nummodes = 0; vidm_selected = 0; - nummodes = VID_NumModes(); -#ifdef _WINDOWS - // clean that later: skip windowed mode 0, video modes menu only shows FULL SCREEN modes - if (nummodes <= NUMSPECIALMODES) - i = 0; // unless we have nothing - else - i = NUMSPECIALMODES; -#else - // DOS does not skip mode 0, because mode 0 is ALWAYS present - i = 0; -#endif - for (; i < nummodes && vidm_nummodes < MAXMODEDESCS; i++) + INT32 nummodes = VID_NumModes(); + + for (i = 0; i < nummodes && vidm_nummodes < MAXMODEDESCS; i++) { - desc = VID_GetModeName(i); + const char *desc = VID_GetModeName(i); if (desc) { - vdup = 0; + // Pull out the width and height + INT32 width, height; + sscanf(desc, "%u%*c%u", &width, &height); - // when a resolution exists both under VGA and VESA, keep the - // VESA mode, which is always a higher modenum - for (j = 0; j < vidm_nummodes; j++) - { - if (!strcmp(modedescs[j].desc, desc)) - { - // mode(0): 320x200 is always standard VGA, not vesa - if (modedescs[j].modenum) - { - modedescs[j].modenum = i; - vdup = 1; + modedescs[vidm_nummodes].width = width; + modedescs[vidm_nummodes].height = height; + modedescs[vidm_nummodes].desc = desc; - if (i == vid.modenum) - vidm_selected = j; - } - else - vdup = 1; + if (width == vid.width && height == vid.height) + vidm_selected = vidm_nummodes; - break; - } - } + // Show multiples of 320x200 as green. + if (SCR_IsAspectCorrect(width, height)) + modedescs[vidm_nummodes].goodratio = 1; - if (!vdup) - { - modedescs[vidm_nummodes].modenum = i; - modedescs[vidm_nummodes].desc = desc; - - if (i == vid.modenum) - vidm_selected = vidm_nummodes; - - // Pull out the width and height - sscanf(desc, "%u%*c%u", &width, &height); - - // Show multiples of 320x200 as green. - if (SCR_IsAspectCorrect(width, height)) - modedescs[vidm_nummodes].goodratio = 1; - - vidm_nummodes++; - } + vidm_nummodes++; } } @@ -13522,11 +13442,11 @@ static void M_DrawVideoMode(void) vid.width, vid.height)); V_DrawCenteredString(BASEVIDWIDTH/2, OP_VideoModeDef.y + 116, (cv_fullscreen.value ? 0 : V_TRANSLUCENT), va("Default mode is %c%dx%d", - (SCR_IsAspectCorrect(cv_scr_width.value, cv_scr_height.value)) ? 0x83 : (!(VID_GetModeForSize(cv_scr_width.value, cv_scr_height.value)+1) ? 0x85 : 0x80), + (SCR_IsAspectCorrect(cv_scr_width.value, cv_scr_height.value)) ? 0x83 : 0x80, cv_scr_width.value, cv_scr_height.value)); V_DrawCenteredString(BASEVIDWIDTH/2, OP_VideoModeDef.y + 124, (cv_fullscreen.value ? V_TRANSLUCENT : 0), va("Windowed mode is %c%dx%d", - (SCR_IsAspectCorrect(cv_scr_width_w.value, cv_scr_height_w.value)) ? 0x83 : (!(VID_GetModeForSize(cv_scr_width_w.value, cv_scr_height_w.value)+1) ? 0x85 : 0x80), + (SCR_IsAspectCorrect(cv_scr_width_w.value, cv_scr_height_w.value)) ? 0x83 : 0x80, cv_scr_width_w.value, cv_scr_height_w.value)); V_DrawCenteredString(BASEVIDWIDTH/2, OP_VideoModeDef.y + 138, @@ -13680,7 +13600,7 @@ static void M_HandleVideoMode(INT32 ch) { // change back to the previous mode quickly case KEY_ESCAPE: - setmodeneeded = vidm_previousmode + 1; + SCR_ChangeResolution(vidm_previouswidth, vidm_previousheight); vidm_testingmode = 0; break; @@ -13722,7 +13642,7 @@ static void M_HandleVideoMode(INT32 ch) break; case KEY_ENTER: - if (vid.modenum == modedescs[vidm_selected].modenum) + if (vid.width == modedescs[vidm_selected].width && vid.height == modedescs[vidm_selected].height) { S_StartSound(NULL, sfx_strpst); SCR_SetDefaultMode(); @@ -13731,9 +13651,11 @@ static void M_HandleVideoMode(INT32 ch) { S_StartSound(NULL, sfx_menu1); vidm_testingmode = 15*TICRATE; - vidm_previousmode = vid.modenum; - if (!setmodeneeded) // in case the previous setmode was not finished - setmodeneeded = modedescs[vidm_selected].modenum + 1; + vidm_previouswidth = vid.width; + vidm_previousheight = vid.height; + + if (!vid.change.set) // in case the previous setmode was not finished + SCR_SetWindowSize(modedescs[vidm_selected].width, modedescs[vidm_selected].height); } break; @@ -13751,9 +13673,9 @@ static void M_HandleVideoMode(INT32 ch) CV_Set(&cv_scr_width_w, cv_scr_width_w.defaultvalue); CV_Set(&cv_scr_height_w, cv_scr_height_w.defaultvalue); if (cv_fullscreen.value) - setmodeneeded = VID_GetModeForSize(cv_scr_width.value, cv_scr_height.value)+1; + SCR_SetWindowSize(cv_scr_width.value, cv_scr_height.value); else - setmodeneeded = VID_GetModeForSize(cv_scr_width_w.value, cv_scr_height_w.value)+1; + SCR_SetWindowSize(cv_scr_width_w.value, cv_scr_height_w.value); break; case KEY_F10: // Renderer toggle, also processed inside menus diff --git a/src/m_menu.h b/src/m_menu.h index c925c7f49..ebb8dbde3 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -413,7 +413,7 @@ extern gtdesc_t gametypedesc[NUMGAMETYPES]; // mode descriptions for video mode menu typedef struct { - INT32 modenum; // video mode number in the vidmodes list + INT32 width, height; const char *desc; // XXXxYYY UINT8 goodratio; // aspect correct if 1 } modedesc_t; diff --git a/src/r_draw.c b/src/r_draw.c index b0467e4f7..79ad9adde 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -722,100 +722,6 @@ void R_InitViewBuffer(INT32 width, INT32 height) } } -/** \brief viewborder patches lump numbers -*/ -lumpnum_t viewborderlump[8]; - -/** \brief Store the lumpnumber of the viewborder patches -*/ - -void R_InitViewBorder(void) -{ - viewborderlump[BRDR_T] = W_GetNumForName("brdr_t"); - viewborderlump[BRDR_B] = W_GetNumForName("brdr_b"); - viewborderlump[BRDR_L] = W_GetNumForName("brdr_l"); - viewborderlump[BRDR_R] = W_GetNumForName("brdr_r"); - viewborderlump[BRDR_TL] = W_GetNumForName("brdr_tl"); - viewborderlump[BRDR_BL] = W_GetNumForName("brdr_bl"); - viewborderlump[BRDR_TR] = W_GetNumForName("brdr_tr"); - viewborderlump[BRDR_BR] = W_GetNumForName("brdr_br"); -} - -#if 0 -/** \brief R_FillBackScreen - - Fills the back screen with a pattern for variable screen sizes - Also draws a beveled edge. -*/ -void R_FillBackScreen(void) -{ - UINT8 *src, *dest; - patch_t *patch; - INT32 x, y, step, boff; - - // quickfix, don't cache lumps in both modes - if (rendermode != render_soft) - return; - - // draw pattern around the status bar too (when hires), - // so return only when in full-screen without status bar. - if (scaledviewwidth == vid.width && viewheight == vid.height) - return; - - src = scr_borderpatch; - dest = screens[1]; - - for (y = 0; y < vid.height; y++) - { - for (x = 0; x < vid.width/128; x++) - { - M_Memcpy (dest, src+((y&127)<<7), 128); - dest += 128; - } - - if (vid.width&127) - { - M_Memcpy(dest, src+((y&127)<<7), vid.width&127); - dest += (vid.width&127); - } - } - - // don't draw the borders when viewwidth is full vid.width. - if (scaledviewwidth == vid.width) - return; - - step = 8; - boff = 8; - - patch = W_CacheLumpNum(viewborderlump[BRDR_T], PU_CACHE); - for (x = 0; x < scaledviewwidth; x += step) - V_DrawPatch(viewwindowx + x, viewwindowy - boff, 1, patch); - - patch = W_CacheLumpNum(viewborderlump[BRDR_B], PU_CACHE); - for (x = 0; x < scaledviewwidth; x += step) - V_DrawPatch(viewwindowx + x, viewwindowy + viewheight, 1, patch); - - patch = W_CacheLumpNum(viewborderlump[BRDR_L], PU_CACHE); - for (y = 0; y < viewheight; y += step) - V_DrawPatch(viewwindowx - boff, viewwindowy + y, 1, patch); - - patch = W_CacheLumpNum(viewborderlump[BRDR_R],PU_CACHE); - for (y = 0; y < viewheight; y += step) - V_DrawPatch(viewwindowx + scaledviewwidth, viewwindowy + y, 1, - patch); - - // Draw beveled corners. - V_DrawPatch(viewwindowx - boff, viewwindowy - boff, 1, - W_CacheLumpNum(viewborderlump[BRDR_TL], PU_CACHE)); - V_DrawPatch(viewwindowx + scaledviewwidth, viewwindowy - boff, 1, - W_CacheLumpNum(viewborderlump[BRDR_TR], PU_CACHE)); - V_DrawPatch(viewwindowx - boff, viewwindowy + viewheight, 1, - W_CacheLumpNum(viewborderlump[BRDR_BL], PU_CACHE)); - V_DrawPatch(viewwindowx + scaledviewwidth, viewwindowy + viewheight, 1, - W_CacheLumpNum(viewborderlump[BRDR_BR], PU_CACHE)); -} -#endif - /** \brief The R_VideoErase function Copy a screen buffer. @@ -837,55 +743,6 @@ void R_VideoErase(size_t ofs, INT32 count) M_Memcpy(screens[0] + ofs, screens[1] + ofs, count); } -#if 0 -/** \brief The R_DrawViewBorder - - Draws the border around the view - for different size windows? -*/ -void R_DrawViewBorder(void) -{ - INT32 top, side, ofs; - - if (rendermode == render_none) - return; -#ifdef HWRENDER - if (rendermode != render_soft) - { - HWR_DrawViewBorder(0); - return; - } - else -#endif - -#ifdef DEBUG - fprintf(stderr,"RDVB: vidwidth %d vidheight %d scaledviewwidth %d viewheight %d\n", - vid.width, vid.height, scaledviewwidth, viewheight); -#endif - - if (scaledviewwidth == vid.width) - return; - - top = (vid.height - viewheight)>>1; - side = (vid.width - scaledviewwidth)>>1; - - // copy top and one line of left side - R_VideoErase(0, top*vid.width+side); - - // copy one line of right side and bottom - ofs = (viewheight+top)*vid.width - side; - R_VideoErase(ofs, top*vid.width + side); - - // copy sides using wraparound - ofs = top*vid.width + vid.width-side; - side <<= 1; - - // simpler using our VID_Blit routine - VID_BlitLinearScreen(screens[1] + ofs, screens[0] + ofs, side, viewheight - 1, - vid.width, vid.width); -} -#endif - // R_CalcTiltedLighting // Exactly what it says on the tin. I wish I wasn't too lazy to explain things properly. static INT32 tiltlighting[MAXVIDWIDTH]; diff --git a/src/r_draw.h b/src/r_draw.h index ea03a8e3d..09fd2fff2 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -81,25 +81,6 @@ extern UINT32 nflatyshift; extern UINT32 nflatshiftup; extern UINT32 nflatmask; -/// \brief Top border -#define BRDR_T 0 -/// \brief Bottom border -#define BRDR_B 1 -/// \brief Left border -#define BRDR_L 2 -/// \brief Right border -#define BRDR_R 3 -/// \brief Topleft border -#define BRDR_TL 4 -/// \brief Topright border -#define BRDR_TR 5 -/// \brief Bottomleft border -#define BRDR_BL 6 -/// \brief Bottomright border -#define BRDR_BR 7 - -extern lumpnum_t viewborderlump[8]; - // ------------------------------------------------ // r_draw.c COMMON ROUTINES FOR BOTH 8bpp and 16bpp // ------------------------------------------------ @@ -150,17 +131,8 @@ boolean R_BlendLevelVisible(INT32 blendmode, INT32 alphalevel); extern UINT8 skincolor_modified[]; void R_InitViewBuffer(INT32 width, INT32 height); -void R_InitViewBorder(void); void R_VideoErase(size_t ofs, INT32 count); -// Rendering function. -#if 0 -void R_FillBackScreen(void); - -// If the view size is not full screen, draws a border around it. -void R_DrawViewBorder(void); -#endif - #define TRANSPARENTPIXEL 255 // ----------------- diff --git a/src/r_main.c b/src/r_main.c index 55bb9c4ff..39231981c 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1016,8 +1016,6 @@ void R_Init(void) //I_OutputMsg("\nR_InitData"); R_InitData(); - //I_OutputMsg("\nR_InitViewBorder"); - R_InitViewBorder(); R_SetViewSize(); // setsizeneeded is set true //I_OutputMsg("\nR_InitPlanes"); diff --git a/src/screen.c b/src/screen.c index fe5b39995..1017706eb 100644 --- a/src/screen.c +++ b/src/screen.c @@ -62,8 +62,29 @@ void (*spanfuncs_npo2[SPANDRAWFUNC_MAX])(void); // global video state // ------------------ viddef_t vid; -INT32 setmodeneeded; //video mode change needed if > 0 (the mode number to set + 1) -UINT8 setrenderneeded = 0; + +// windowed video modes from which to choose from. +INT32 windowedModes[MAXWINMODES][2] = +{ + {1920,1200}, // 1.60,6.00 + {1920,1080}, // 1.66 + {1680,1050}, // 1.60,5.25 + {1600,1200}, // 1.33 + {1600, 900}, // 1.66 + {1366, 768}, // 1.66 + {1440, 900}, // 1.60,4.50 + {1280,1024}, // 1.33? + {1280, 960}, // 1.33,4.00 + {1280, 800}, // 1.60,4.00 + {1280, 720}, // 1.66 + {1152, 864}, // 1.33,3.60 + {1024, 768}, // 1.33,3.20 + { 800, 600}, // 1.33,2.50 + { 640, 480}, // 1.33,2.00 + { 640, 400}, // 1.60,2.00 + { 320, 240}, // 1.33,1.00 + { 320, 200}, // 1.60,1.00 +}; static CV_PossibleValue_t scr_depth_cons_t[] = {{8, "8 bits"}, {16, "16 bits"}, {24, "24 bits"}, {32, "32 bits"}, {0, NULL}}; @@ -95,13 +116,9 @@ consvar_t cv_fullscreen = CVAR_INIT ("fullscreen", "Yes", CV_SAVE|CV_CALL, CV_Ye // ========================================================================= INT32 scr_bpp; // current video mode bytes per pixel -UINT8 *scr_borderpatch; // flat used to fill the reduced view borders set at ST_Init() // ========================================================================= -// Short and Tall sky drawer, for the current color mode -void (*walldrawerfunc)(void); - boolean R_ASM = true; boolean R_486 = false; boolean R_586 = false; @@ -215,35 +232,26 @@ void SCR_SetMode(void) if (dedicated) return; - if (!(setmodeneeded || setrenderneeded) || WipeInAction) + if (!vid.change.set || WipeInAction) return; // should never happen and don't change it during a wipe, BAD! - // Lactozilla: Renderer switching - if (setrenderneeded) + if (vid.change.renderer != -1) { - // stop recording movies (APNG only) - if (setrenderneeded && (moviemode == MM_APNG)) + if (moviemode == MM_APNG) M_StopMovie(); - - // VID_SetMode will call VID_CheckRenderer itself, - // so no need to do this in here. - if (!setmodeneeded) - VID_CheckRenderer(); - - vid.recalc = 1; } - // Set the video mode in the video interface. - if (setmodeneeded) - VID_SetMode(setmodeneeded - 1); + if (vid.change.set) + VID_SetSize(vid.change.width, vid.change.height); V_SetPalette(0); SCR_SetDrawFuncs(); - // set the apprpriate drawer for the sky (tall or INT16) - setmodeneeded = 0; - setrenderneeded = 0; + vid.change.set = VID_RESOLUTION_UNCHANGED; + vid.change.width = -1; + vid.change.height = -1; + vid.change.renderer = -1; } // do some initial settings for the game loading screen @@ -350,11 +358,41 @@ void SCR_Recalc(void) #endif } +boolean SCR_IsValidResolution(INT32 width, INT32 height) +{ + if (width < BASEVIDWIDTH || width > MAXVIDWIDTH) + return false; + if (height < BASEVIDHEIGHT || height > MAXVIDHEIGHT) + return false; + return true; +} + +void SCR_ChangeResolution(INT32 width, INT32 height) +{ + if (SCR_IsValidResolution(width, height)) + { + vid.change.width = width; + vid.change.height = height; + vid.change.renderer = -1; + vid.change.set = VID_RESOLUTION_CHANGED; + } +} + +void SCR_SetWindowSize(INT32 width, INT32 height) +{ + if (SCR_IsValidResolution(width, height)) + { + vid.change.width = width; + vid.change.height = height; + vid.change.renderer = -1; + vid.change.set = VID_RESOLUTION_RESIZED_WINDOW; + } +} + // Check for screen cmd-line parms: to force a resolution. // -// Set the video mode to set at the 1st display loop (setmodeneeded) +// Set the video mode to set at the 1st display loop // - void SCR_CheckDefaultMode(void) { INT32 scr_forcex, scr_forcey; // resolution asked from the cmd-line @@ -374,21 +412,35 @@ void SCR_CheckDefaultMode(void) if (scr_forcex && scr_forcey) { CONS_Printf(M_GetText("Using resolution: %d x %d\n"), scr_forcex, scr_forcey); - // returns -1 if not found, thus will be 0 (no mode change) if not found - setmodeneeded = VID_GetModeForSize(scr_forcex, scr_forcey) + 1; + SCR_ChangeResolution(scr_forcex, scr_forcey); } else { CONS_Printf(M_GetText("Default resolution: %d x %d\n"), cv_scr_width.value, cv_scr_height.value); CONS_Printf(M_GetText("Windowed resolution: %d x %d\n"), cv_scr_width_w.value, cv_scr_height_w.value); CONS_Printf(M_GetText("Default bit depth: %d bits\n"), cv_scr_depth.value); - if (cv_fullscreen.value) - setmodeneeded = VID_GetModeForSize(cv_scr_width.value, cv_scr_height.value) + 1; // see note above - else - setmodeneeded = VID_GetModeForSize(cv_scr_width_w.value, cv_scr_height_w.value) + 1; // see note above - if (setmodeneeded <= 0) + INT32 width, height; + + if (cv_fullscreen.value) + { + width = cv_scr_width.value; + height = cv_scr_height.value; + } + else + { + width = cv_scr_width_w.value; + height = cv_scr_height_w.value; + } + + if (!SCR_IsValidResolution(width, height)) + { CONS_Alert(CONS_WARNING, "Invalid resolution given, defaulting to base resolution\n"); + width = BASEVIDWIDTH; + height = BASEVIDHEIGHT; + } + + SCR_ChangeResolution(width, height); } if (cv_renderer.value != (signed)rendermode) @@ -422,31 +474,40 @@ void SCR_ChangeFullscreen(void) if (graphics_started) { VID_PrepareModeList(); - if (cv_fullscreen.value) - setmodeneeded = VID_GetModeForSize(cv_scr_width.value, cv_scr_height.value) + 1; - else - setmodeneeded = VID_GetModeForSize(cv_scr_width_w.value, cv_scr_height_w.value) + 1; - if (setmodeneeded <= 0) // hacky safeguard + INT32 width, height; + + if (cv_fullscreen.value) { - CONS_Alert(CONS_WARNING, "Invalid resolution given, defaulting to base resolution.\n"); - setmodeneeded = VID_GetModeForSize(BASEVIDWIDTH, BASEVIDHEIGHT) + 1; + width = cv_scr_width.value; + height = cv_scr_height.value; } + else + { + width = cv_scr_width_w.value; + height = cv_scr_height_w.value; + } + + if (!SCR_IsValidResolution(width, height)) + { + CONS_Alert(CONS_WARNING, "Invalid resolution given, defaulting to base resolution\n"); + width = BASEVIDWIDTH; + height = BASEVIDHEIGHT; + } + + SCR_ChangeResolution(width, height); } - return; #endif } void SCR_ChangeRenderer(void) { - if (chosenrendermode != render_none - || (signed)rendermode == cv_renderer.value) + if (chosenrendermode != render_none || (signed)rendermode == cv_renderer.value) return; #ifdef HWRENDER // Check if OpenGL loaded successfully (or wasn't disabled) before switching to it. - if ((vid.glstate == VID_GL_LIBRARY_ERROR) - && (cv_renderer.value == render_opengl)) + if (vid.glstate == VID_GL_LIBRARY_ERROR && cv_renderer.value == render_opengl) { if (M_CheckParm("-nogl")) CONS_Alert(CONS_ERROR, "OpenGL rendering was disabled!\n"); @@ -457,11 +518,11 @@ void SCR_ChangeRenderer(void) if (rendermode == render_opengl && (vid.glstate == VID_GL_LIBRARY_LOADED)) // Clear these out before switching to software HWR_ClearAllTextures(); - #endif // Set the new render mode - setrenderneeded = cv_renderer.value; + vid.change.renderer = cv_renderer.value; + vid.change.set = VID_RESOLUTION_CHANGED; } boolean SCR_IsAspectCorrect(INT32 width, INT32 height) diff --git a/src/screen.h b/src/screen.h index 65e82ff4d..620535685 100644 --- a/src/screen.h +++ b/src/screen.h @@ -53,20 +53,20 @@ typedef struct viddef_s size_t rowbytes; // bytes per scanline of the VIDEO mode INT32 width; // PIXELS per scanline INT32 height; - union { // don't need numpages for OpenGL, so we can use it for fullscreen/windowed mode - INT32 numpages; // always 1, page flipping todo - INT32 windowed; // windowed or fullscren mode? - } u; INT32 recalc; // if true, recalc vid-based stuff UINT8 *direct; // linear frame buffer, or vga base mem. INT32 dupx, dupy; // scale 1, 2, 3 value for menus & overlays - INT32/*fixed_t*/ fdupx, fdupy; // same as dupx, dupy, but exact value when aspect ratio isn't 320/200 + INT32 fdupx, fdupy; // same as dupx, dupy, but exact value when aspect ratio isn't 320/200 INT32 bpp; // BYTES per pixel: 1 = 256color, 2 = highcolor - INT32 baseratio; // Used to get the correct value for lighting walls + struct { + INT32 width; + INT32 height; + INT32 renderer; + UINT8 set; + } change; // for Win32 version - DNWH WndParent; // handle of the application's window UINT8 smalldupx, smalldupy; // factor for a little bit of scaling UINT8 meddupx, meddupy; // factor for moderate, but not full, scaling #ifdef HWRENDER @@ -78,39 +78,21 @@ typedef struct viddef_s enum { - VID_GL_LIBRARY_NOTLOADED = 0, - VID_GL_LIBRARY_LOADED = 1, - VID_GL_LIBRARY_ERROR = -1, + VID_RESOLUTION_UNCHANGED = 0, + VID_RESOLUTION_CHANGED = 1, + VID_RESOLUTION_RESIZED_WINDOW = 2 }; -// internal additional info for vesa modes only -typedef struct +enum { - INT32 vesamode; // vesa mode number plus LINEAR_MODE bit - void *plinearmem; // linear address of start of frame buffer -} vesa_extra_t; -// a video modes from the video modes list, -// note: video mode 0 is always standard VGA320x200. -typedef struct vmode_s -{ - struct vmode_s *pnext; - char *name; - UINT32 width, height; - UINT32 rowbytes; // bytes per scanline - UINT32 bytesperpixel; // 1 for 256c, 2 for highcolor - INT32 windowed; // if true this is a windowed mode - INT32 numpages; - vesa_extra_t *pextradata; // vesa mode extra data -#ifdef _WIN32 - INT32 (WINAPI *setmode)(viddef_t *lvid, struct vmode_s *pcurrentmode); -#else - INT32 (*setmode)(viddef_t *lvid, struct vmode_s *pcurrentmode); -#endif - INT32 misc; // misc for display driver (r_opengl.dll etc) -} vmode_t; + VID_GL_LIBRARY_NOTLOADED = 0, + VID_GL_LIBRARY_LOADED = 1, + VID_GL_LIBRARY_ERROR = -1 +}; -#define NUMSPECIALMODES 4 -extern vmode_t specialmodes[NUMSPECIALMODES]; +#define MAXWINMODES 18 + +extern INT32 windowedModes[MAXWINMODES][2]; // --------------------------------------------- // color mode dependent drawer function pointers @@ -187,17 +169,18 @@ extern boolean R_SSE2; // screen variables // ---------------- extern viddef_t vid; -extern INT32 setmodeneeded; // mode number to set if needed, or 0 -extern UINT8 setrenderneeded; extern double averageFPS; +void SCR_ChangeResolution(INT32 width, INT32 height); +void SCR_SetWindowSize(INT32 width, INT32 height); void SCR_ChangeRenderer(void); +boolean SCR_IsValidResolution(INT32 width, INT32 height); + extern CV_PossibleValue_t cv_renderer_t[]; extern INT32 scr_bpp; -extern UINT8 *scr_borderpatch; // patch used to fill the view borders extern consvar_t cv_scr_width, cv_scr_height, cv_scr_width_w, cv_scr_height_w, cv_scr_depth, cv_fullscreen; extern consvar_t cv_renderview, cv_renderer; diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index a90700fa9..846b4c742 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -87,9 +87,6 @@ #include "ogl_sdl.h" #endif -// maximum number of windowed modes (see windowedModes[][]) -#define MAXWINMODES (18) - rendermode_t rendermode = render_soft; rendermode_t chosenrendermode = render_none; // set by command line arguments @@ -162,29 +159,6 @@ static void Impl_SetWindowIcon(void); static SDL_Surface *icoSurface = NULL; #endif -// windowed video modes from which to choose from. -static INT32 windowedModes[MAXWINMODES][2] = -{ - {1920,1200}, // 1.60,6.00 - {1920,1080}, // 1.66 - {1680,1050}, // 1.60,5.25 - {1600,1200}, // 1.33 - {1600, 900}, // 1.66 - {1366, 768}, // 1.66 - {1440, 900}, // 1.60,4.50 - {1280,1024}, // 1.33? - {1280, 960}, // 1.33,4.00 - {1280, 800}, // 1.60,4.00 - {1280, 720}, // 1.66 - {1152, 864}, // 1.33,3.60 - {1024, 768}, // 1.33,3.20 - { 800, 600}, // 1.33,2.50 - { 640, 480}, // 1.33,2.00 - { 640, 400}, // 1.60,2.00 - { 320, 240}, // 1.33,1.00 - { 320, 200}, // 1.60,1.00 -}; - static char vidModeName[MAXWINMODES][32]; static const char *fallback_resolution_name = "Fallback"; @@ -644,7 +618,14 @@ static void VID_Command_Mode_f (void) CONS_Printf(M_GetText("Video mode not present\n")); else { - setmodeneeded = modenum + 1; // request vid mode change + if (modenum < 0) + modenum = 0; + if (modenum >= MAXWINMODES) + modenum = MAXWINMODES-1; + + vid.change.width = windowedModes[modenum][0]; + vid.change.height = windowedModes[modenum][1]; + vid.change.set = VID_RESOLUTION_CHANGED; } } @@ -690,6 +671,7 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt) case SDL_WINDOWEVENT_MAXIMIZED: break; case SDL_WINDOWEVENT_SIZE_CHANGED: + SCR_SetWindowSize(evt.data1, evt.data2); break; } @@ -1386,10 +1368,10 @@ void VID_CheckGLLoaded(rendermode_t oldrender) rendermode = oldrender; if (chosenrendermode == render_opengl) // fallback to software rendermode = render_soft; - if (setrenderneeded) + if (vid.change.renderer != -1) { CV_StealthSetValue(&cv_renderer, oldrender); - setrenderneeded = 0; + vid.change.renderer = 0; } } #endif @@ -1408,9 +1390,9 @@ boolean VID_CheckRenderer(void) if (dedicated) return 0; - if (setrenderneeded) + if (vid.change.renderer != -1) { - rendermode = setrenderneeded; + rendermode = vid.change.renderer; rendererchanged = true; #ifdef HWRENDER @@ -1426,12 +1408,10 @@ boolean VID_CheckRenderer(void) } #endif - setrenderneeded = 0; + vid.change.renderer = -1; } - SDL_bool center = setmodeneeded ? SDL_TRUE : SDL_FALSE; - - if (SDLSetMode(vid.width, vid.height, USE_FULLSCREEN, center) == SDL_FALSE) + if (SDLSetMode(vid.width, vid.height, USE_FULLSCREEN, vid.change.set != VID_RESOLUTION_RESIZED_WINDOW) == SDL_FALSE) { if (!graphics_started) { @@ -1497,30 +1477,24 @@ void VID_GetNativeResolution(INT32 *width, INT32 *height) } #endif -INT32 VID_SetMode(INT32 modeNum) +void VID_SetSize(INT32 width, INT32 height) { SDLdoUngrabMouse(); vid.recalc = true; - vid.bpp = 1; - if (modeNum < 0) - modeNum = 0; - if (modeNum >= MAXWINMODES) - modeNum = MAXWINMODES-1; - - vid.width = windowedModes[modeNum][0]; - vid.height = windowedModes[modeNum][1]; - vid.modenum = modeNum; + if (width > 0 && height > 0 && SCR_IsValidResolution(width, height)) + { + vid.width = width; + vid.height = height; + } VID_CheckRenderer(); - - return SDL_TRUE; } static SDL_bool Impl_CreateWindow(SDL_bool fullscreen) { - int flags = 0; + int flags = SDL_WINDOW_RESIZABLE; if (window != NULL) return SDL_TRUE; @@ -1552,6 +1526,8 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen) return SDL_FALSE; } + SDL_SetWindowMinimumSize(window, BASEVIDWIDTH, BASEVIDHEIGHT); + #ifdef USE_WINDOW_ICON Impl_SetWindowIcon(); #endif @@ -1750,14 +1726,9 @@ void I_StartupGraphics(void) vid.recalc = true; vid.direct = NULL; vid.bpp = 1; - vid.WndParent = NULL; // Create window - // Default size for startup - vid.width = BASEVIDWIDTH; - vid.height = BASEVIDHEIGHT; - - VID_SetMode(VID_GetModeForSize(vid.width, vid.height)); + VID_SetSize(BASEVIDWIDTH, BASEVIDHEIGHT); #ifdef HAVE_TTF I_ShutdownTTF(); @@ -1827,10 +1798,10 @@ static void Impl_InitOpenGL(void) vid.glstate = VID_GL_LIBRARY_ERROR; CV_StealthSet(&cv_renderer, "Software"); + rendermode = render_soft; - if (setrenderneeded) - setrenderneeded = 0; + vid.change.renderer = -1; } #endif } diff --git a/src/st_stuff.c b/src/st_stuff.c index c6e6befc6..0018f6206 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -254,10 +254,6 @@ void ST_LoadGraphics(void) { int i; - // SRB2 border patch - // st_borderpatchnum = W_GetNumForName("GFZFLR01"); - // scr_borderpatch = W_CacheLumpNum(st_borderpatchnum, PU_HUDGFX); - // the original Doom uses 'STF' as base name for all face graphics // Graue 04-08-2004: face/name graphics are now indexed by skins // but load them in R_AddSkins, that gets called @@ -425,12 +421,8 @@ void ST_Start(void) } // -// Initializes the status bar, sets the defaults border patch for the window borders. +// Initializes the status bar // - -// used by OpenGL mode, holds lumpnum of flat used to fill space around the viewwindow -lumpnum_t st_borderpatchnum; - void ST_Init(void) { INT32 i; diff --git a/src/st_stuff.h b/src/st_stuff.h index 603be3c30..1bf7c5f22 100644 --- a/src/st_stuff.h +++ b/src/st_stuff.h @@ -69,7 +69,6 @@ extern boolean st_overlay; // sb overlay on or off when fullscreen extern INT32 st_palette; // 0 is default, any others are special palettes. extern INT32 st_translucency; -extern lumpnum_t st_borderpatchnum; // patches, also used in intermission extern patch_t *tallnum[10]; extern patch_t *sboscore;