diff --git a/neo/d3xp/PlayerView.cpp b/neo/d3xp/PlayerView.cpp index 750e20d0..9e3d4f09 100644 --- a/neo/d3xp/PlayerView.cpp +++ b/neo/d3xp/PlayerView.cpp @@ -694,8 +694,44 @@ void idPlayerView::RenderPlayerView( idUserInterface *hud ) { ScreenFade(); if ( net_clientLagOMeter.GetBool() && lagoMaterial && gameLocal.isClient ) { - renderSystem->SetColor4( 1.0f, 1.0f, 1.0f, 1.0f ); - renderSystem->DrawStretchPic( 10.0f, 380.0f, 64.0f, 64.0f, 0.0f, 0.0f, 1.0f, 1.0f, lagoMaterial ); + //#modified-fva; BEGIN + float x = 10.0f; + float y = 380.0f; + float w = 64.0f; + float h = 64.0f; + if (cvarSystem->GetCVarBool("cst_hudAdjustAspect")) { + // similar to CST_ANCHOR_BOTTOM_LEFT + int glWidth, glHeight; + renderSystem->GetGLSettings(glWidth, glHeight); + if (glWidth > 0 && glHeight > 0) { + float glAspectRatio = (float)glWidth / (float)glHeight; + + const float vidWidth = SCREEN_WIDTH; + const float vidHeight = SCREEN_HEIGHT; + const float vidAspectRatio = (float)SCREEN_WIDTH / (float)SCREEN_HEIGHT; + + float modWidth = vidWidth; + float modHeight = vidHeight; + if (glAspectRatio >= vidAspectRatio) { + modWidth = modHeight * glAspectRatio; + } else { + modHeight = modWidth / glAspectRatio; + } + + float xScale = vidWidth / modWidth; + float yScale = vidHeight / modHeight; + float xOffset = 0.0f; + float yOffset = vidHeight * (1.0f - yScale); + + x = x * xScale + xOffset; + y = y * yScale + yOffset; + w *= xScale; + h *= yScale; + } + } + renderSystem->SetColor4(1.0f, 1.0f, 1.0f, 1.0f); + renderSystem->DrawStretchPic(x, y, w, h, 0.0f, 0.0f, 1.0f, 1.0f, lagoMaterial); + //#modified-fva; END } } diff --git a/neo/framework/Licensee.h b/neo/framework/Licensee.h index 53bb4374..ddcff1db 100644 --- a/neo/framework/Licensee.h +++ b/neo/framework/Licensee.h @@ -93,7 +93,8 @@ If you have questions concerning this license or the applicable additional terms // NOTE: a seperate core savegame version and game savegame version could be useful // 16: Doom v1.1 // 17: Doom v1.2 / D3XP. Can still read old v16 with defaults for new data -#define SAVEGAME_VERSION 17 +// 18: dhewm3 with CstDoom3 anchored window support - can still read v16 and v17, unless gamedata changed +#define SAVEGAME_VERSION 18 // <= Doom v1.1: 1. no DS_VERSION token ( default ) // Doom v1.2: 2 diff --git a/neo/framework/Session.cpp b/neo/framework/Session.cpp index 65f205e8..713132fa 100644 --- a/neo/framework/Session.cpp +++ b/neo/framework/Session.cpp @@ -2130,8 +2130,7 @@ bool idSessionLocal::LoadGame( const char *saveName ) { // check the version, if it doesn't match, cancel the loadgame, // but still load the map with the persistant playerInfo from the header // so that the player doesn't lose too much progress. - if ( savegameVersion != SAVEGAME_VERSION && - !( savegameVersion == 16 && SAVEGAME_VERSION == 17 ) ) { // handle savegame v16 in v17 + if ( savegameVersion < 16 || savegameVersion > SAVEGAME_VERSION ) { // dhewm3 supports savegames with v16 - v18 common->Warning( "Savegame Version mismatch: aborting loadgame and starting level with persistent data" ); loadingSaveGame = false; fileSystem->CloseFile( savegameFile ); diff --git a/neo/game/PlayerView.cpp b/neo/game/PlayerView.cpp index 549ce3ab..16dc8094 100644 --- a/neo/game/PlayerView.cpp +++ b/neo/game/PlayerView.cpp @@ -721,7 +721,43 @@ void idPlayerView::RenderPlayerView( idUserInterface *hud ) { } if ( net_clientLagOMeter.GetBool() && lagoMaterial && gameLocal.isClient ) { - renderSystem->SetColor4( 1.0f, 1.0f, 1.0f, 1.0f ); - renderSystem->DrawStretchPic( 10.0f, 380.0f, 64.0f, 64.0f, 0.0f, 0.0f, 1.0f, 1.0f, lagoMaterial ); + //#modified-fva; BEGIN + float x = 10.0f; + float y = 380.0f; + float w = 64.0f; + float h = 64.0f; + if (cvarSystem->GetCVarBool("cst_hudAdjustAspect")) { + // similar to CST_ANCHOR_BOTTOM_LEFT + int glWidth, glHeight; + renderSystem->GetGLSettings(glWidth, glHeight); + if (glWidth > 0 && glHeight > 0) { + float glAspectRatio = (float)glWidth / (float)glHeight; + + const float vidWidth = SCREEN_WIDTH; + const float vidHeight = SCREEN_HEIGHT; + const float vidAspectRatio = (float)SCREEN_WIDTH / (float)SCREEN_HEIGHT; + + float modWidth = vidWidth; + float modHeight = vidHeight; + if (glAspectRatio >= vidAspectRatio) { + modWidth = modHeight * glAspectRatio; + } else { + modHeight = modWidth / glAspectRatio; + } + + float xScale = vidWidth / modWidth; + float yScale = vidHeight / modHeight; + float xOffset = 0.0f; + float yOffset = vidHeight * (1.0f - yScale); + + x = x * xScale + xOffset; + y = y * yScale + yOffset; + w *= xScale; + h *= yScale; + } + } + renderSystem->SetColor4(1.0f, 1.0f, 1.0f, 1.0f); + renderSystem->DrawStretchPic(x, y, w, h, 0.0f, 0.0f, 1.0f, 1.0f, lagoMaterial); + //#modified-fva; END } } diff --git a/neo/ui/DeviceContext.cpp b/neo/ui/DeviceContext.cpp index 6a5db6da..7ab11320 100644 --- a/neo/ui/DeviceContext.cpp +++ b/neo/ui/DeviceContext.cpp @@ -291,16 +291,20 @@ void idDeviceContext::SetMenuScaleFix(bool enable) { } } +// DG: Note: not sure if AdjustCoords() works entirely as it should, but it seems +// good enough for the idRenderWindow with the mars globe in the main menu void idDeviceContext::AdjustCoords(float *x, float *y, float *w, float *h) { - + // TODO: not sure about cst_*Offset if (x) { *x *= xScale; + *x += cst_xOffset; // DG: for CstDoom3 anchored windows *x *= fixScaleForMenu.x; // DG: for "render menus as 4:3" hack *x += fixOffsetForMenu.x; } if (y) { *y *= yScale; + *y += cst_yOffset; // DG: for CstDoom3 anchored windows *y *= fixScaleForMenu.y; // DG: for "render menus as 4:3" hack *y += fixOffsetForMenu.y; @@ -317,23 +321,10 @@ void idDeviceContext::AdjustCoords(float *x, float *y, float *w, float *h) { } } -// DG: same as AdjustCoords, but ignore fixupMenus because for the cursor that must be handled seperately -void idDeviceContext::AdjustCursorCoords(float *x, float *y, float *w, float *h) { - if (x) { - *x *= xScale; - } - if (y) { - *y *= yScale; - } - if (w) { - *w *= xScale; - } - if (h) { - *h *= yScale; - } -} - -void idDeviceContext::DrawStretchPic(float x, float y, float w, float h, float s1, float t1, float s2, float t2, const idMaterial *shader) { +// fva/DG: added adjustCoords argument for CstDoom3 anchored GUIs and our old +// scale-menus-to-4:3-fix, it basically replaces calling AdjustCoords(&x, &y, &w, &h) +// before calling this +void idDeviceContext::DrawStretchPic(float x, float y, float w, float h, float s1, float t1, float s2, float t2, const idMaterial *shader, bool adjustCoords) { idDrawVert verts[4]; glIndex_t indexes[6]; indexes[0] = 3; @@ -415,6 +406,18 @@ void idDeviceContext::DrawStretchPic(float x, float y, float w, float h, float s verts[3].xyz += origin; } + //#modified-fva; BEGIN + if (adjustCoords) { + for( int i=0; i<4; ++i) { + // Note: if cstAdjustCoords == false; cst_*Offset is 0, so that doesn't require special handling + float x = verts[i].xyz[0] * xScale + cst_xOffset; + float y = verts[i].xyz[1] * yScale + cst_yOffset; + verts[i].xyz[0] = x * fixScaleForMenu.x + fixOffsetForMenu.x; + verts[i].xyz[1] = y * fixScaleForMenu.y + fixOffsetForMenu.y; + } + } + //#modified-fva; END + renderSystem->DrawStretchPic( &verts[0], &indexes[0], 4, 6, shader, ident ); } @@ -462,9 +465,14 @@ void idDeviceContext::DrawMaterial(float x, float y, float w, float h, const idM return; } + //#modified-fva; BEGIN + /* AdjustCoords(&x, &y, &w, &h); DrawStretchPic( x, y, w, h, s0, t0, s1, t1, mat); + */ + DrawStretchPic(x, y, w, h, s0, t0, s1, t1, mat, true); + //#modified-fva; END } void idDeviceContext::DrawMaterialRotated(float x, float y, float w, float h, const idMaterial *mat, const idVec4 &color, float scalex, float scaley, float angle) { @@ -509,12 +517,20 @@ void idDeviceContext::DrawMaterialRotated(float x, float y, float w, float h, co return; } + //#modified-fva; BEGIN + /* AdjustCoords(&x, &y, &w, &h); DrawStretchPicRotated( x, y, w, h, s0, t0, s1, t1, mat, angle); + */ + DrawStretchPicRotated(x, y, w, h, s0, t0, s1, t1, mat, angle, true); + //#modified-fva; END } -void idDeviceContext::DrawStretchPicRotated(float x, float y, float w, float h, float s1, float t1, float s2, float t2, const idMaterial *shader, float angle) { +// fva/DG: added adjustCoords argument for CstDoom3 anchored GUIs and our old +// scale-menus-to-4:3-fix, it basically replaces calling AdjustCoords(&x, &y, &w, &h) +// before calling this +void idDeviceContext::DrawStretchPicRotated(float x, float y, float w, float h, float s1, float t1, float s2, float t2, const idMaterial *shader, float angle, bool adjustCoords) { idDrawVert verts[4]; glIndex_t indexes[6]; @@ -624,6 +640,17 @@ void idDeviceContext::DrawStretchPicRotated(float x, float y, float w, float h, verts[i].xyz += origTrans; } + //#modified-fva; BEGIN + if (adjustCoords) { + for( int i=0; i<4; ++i) { + // Note: if cstAdjustCoords == false; cst_*Offset is 0, so that doesn't require special handling + float x = verts[i].xyz[0] * xScale + cst_xOffset; + float y = verts[i].xyz[1] * yScale + cst_yOffset; + verts[i].xyz[0] = x * fixScaleForMenu.x + fixOffsetForMenu.x; + verts[i].xyz[1] = y * fixScaleForMenu.y + fixOffsetForMenu.y; + } + } + //#modified-fva; END renderSystem->DrawStretchPic( &verts[0], &indexes[0], 4, 6, shader, (angle == 0.0) ? false : true ); } @@ -640,8 +667,13 @@ void idDeviceContext::DrawFilledRect( float x, float y, float w, float h, const return; } + //#modified-fva; BEGIN + /* AdjustCoords(&x, &y, &w, &h); DrawStretchPic( x, y, w, h, 0, 0, 0, 0, whiteImage); + */ + DrawStretchPic(x, y, w, h, 0, 0, 0, 0, whiteImage, true); + //#modified-fva; END } @@ -657,11 +689,19 @@ void idDeviceContext::DrawRect( float x, float y, float w, float h, float size, return; } + //#modified-fva; BEGIN + /* AdjustCoords(&x, &y, &w, &h); DrawStretchPic( x, y, size, h, 0, 0, 0, 0, whiteImage ); DrawStretchPic( x + w - size, y, size, h, 0, 0, 0, 0, whiteImage ); DrawStretchPic( x, y, w, size, 0, 0, 0, 0, whiteImage ); DrawStretchPic( x, y + h - size, w, size, 0, 0, 0, 0, whiteImage ); + */ + DrawStretchPic(x, y + size, size, h - 2.0f * size, 0, 0, 0, 0, whiteImage, true); + DrawStretchPic(x + w - size, y + size, size, h - 2.0f * size, 0, 0, 0, 0, whiteImage, true); + DrawStretchPic(x, y, w, size, 0, 0, 0, 0, whiteImage, true); + DrawStretchPic(x, y + h - size, w, size, 0, 0, 0, 0, whiteImage, true); + //#modified-fva; END } void idDeviceContext::DrawMaterialRect( float x, float y, float w, float h, float size, const idMaterial *mat, const idVec4 &color) { @@ -701,9 +741,21 @@ void idDeviceContext::DrawCursor(float *x, float *y, float size) { renderSystem->SetColor(colorWhite); - // DG: I use this instead of plain AdjustCursorCoords and the following lines - // to scale menus and other fullscreen GUIs to 4:3 aspect ratio - AdjustCursorCoords(x, y, &size, &size); + // DG: originally, this just called AdjustCoords() and then DrawStretchPic(). + // It had to be adjusted to scale menus and other fullscreen GUIs to 4:3 aspect ratio + // and for the CstDoom3 anchored GUIs, so all that is now done here + + // the following block used to be Adjust(Cursor)Coords() + // (no point in keeping that function when it's only used here) + *x *= xScale; + *y *= yScale; + size *= xScale; + // TODO: not sure if scaling it by both is the right thing to do.. + // but OTOH, probably one of them is always 1, at least when not using an anchor + // (and why would a cursor use an anchor) + size *= yScale; + + // the *actual* sizes used (but not set to *x and *y) need to apply the menu fixes float sizeW = size * fixScaleForMenu.x; float sizeH = size * fixScaleForMenu.y; float fixedX = *x * fixScaleForMenu.x + fixOffsetForMenu.x; @@ -725,8 +777,13 @@ void idDeviceContext::PaintChar(float x,float y,float width,float height,float s return; } + //#modified-fva; BEGIN + /* AdjustCoords(&x, &y, &w, &h); DrawStretchPic(x, y, w, h, s, t, s2, t2, hShader); + */ + DrawStretchPic(x, y, w, h, s, t, s2, t2, hShader, true); + //#modified-fva; END } @@ -818,13 +875,182 @@ int idDeviceContext::DrawText(float x, float y, float scale, idVec4 color, const void idDeviceContext::SetSize(float width, float height) { vidWidth = VIRTUAL_WIDTH; vidHeight = VIRTUAL_HEIGHT; - xScale = yScale = 0.0f; - if ( width != 0.0f && height != 0.0f ) { + xScale = yScale = 1.0f; // DG: I think this was also changed by fva + //#modified-fva; BEGIN + cst_xOffset = cst_yOffset = 0.0f; + cstAdjustCoords = false; + if ((width != vidWidth || height != vidHeight) && width > 0.0f && height > 0.0f) { + cstAdjustCoords = true; + //#modified-fva; END xScale = vidWidth * ( 1.0f / width ); yScale = vidHeight * ( 1.0f / height ); } } +//#modified-fva; BEGIN +// =============== +static bool CstGetVidScale(float &_xScale, float &_yScale) { + int glWidth, glHeight; + renderSystem->GetGLSettings(glWidth, glHeight); + if (glWidth <= 0 || glHeight <= 0) { + return false; + } + + float glAspectRatio = (float)glWidth / (float)glHeight; + + const float vidWidth = VIRTUAL_WIDTH; + const float vidHeight = VIRTUAL_HEIGHT; + const float vidAspectRatio = (float)VIRTUAL_WIDTH / (float)VIRTUAL_HEIGHT; + + float modWidth = vidWidth; + float modHeight = vidHeight; + if (glAspectRatio >= vidAspectRatio) { + modWidth = modHeight * glAspectRatio; + } else { + modHeight = modWidth / glAspectRatio; + } + + _xScale = vidWidth / modWidth; + _yScale = vidHeight / modHeight; + return true; +} + + +static void CstAdjustParmsForAnchor(int anchor, float &_xScale, float &_yScale, float &_xOffset, float &_yOffset) { + const float vidWidth = VIRTUAL_WIDTH; + const float vidHeight = VIRTUAL_HEIGHT; + + switch (anchor) { + case idDeviceContext::CST_ANCHOR_TOP_LEFT: { + _xOffset = 0.0f; + _yOffset = 0.0f; + break; + } + case idDeviceContext::CST_ANCHOR_TOP_CENTER: { + _xOffset = (vidWidth * 0.5f) * (1.0f - _xScale); + _yOffset = 0.0f; + break; + } + case idDeviceContext::CST_ANCHOR_TOP_RIGHT: { + _xOffset = vidWidth * (1.0f - _xScale); + _yOffset = 0.0f; + break; + } + case idDeviceContext::CST_ANCHOR_CENTER_LEFT: { + _xOffset = 0.0f; + _yOffset = (vidHeight * 0.5f) * (1.0f - _yScale); + break; + } + case idDeviceContext::CST_ANCHOR_CENTER_CENTER: { + _xOffset = (vidWidth * 0.5f) * (1.0f - _xScale); + _yOffset = (vidHeight * 0.5f) * (1.0f - _yScale); + break; + } + case idDeviceContext::CST_ANCHOR_CENTER_RIGHT: { + _xOffset = vidWidth * (1.0f - _xScale); + _yOffset = (vidHeight * 0.5f) * (1.0f - _yScale); + break; + } + case idDeviceContext::CST_ANCHOR_BOTTOM_LEFT: { + _xOffset = 0.0f; + _yOffset = vidHeight * (1.0f - _yScale); + break; + } + case idDeviceContext::CST_ANCHOR_BOTTOM_CENTER: { + _xOffset = (vidWidth * 0.5f) * (1.0f - _xScale); + _yOffset = vidHeight * (1.0f - _yScale); + break; + } + case idDeviceContext::CST_ANCHOR_BOTTOM_RIGHT: { + _xOffset = vidWidth * (1.0f - _xScale); + _yOffset = vidHeight * (1.0f - _yScale); + break; + } + case idDeviceContext::CST_ANCHOR_TOP: { + _xScale = 1.0f; // no horizontal scaling + _xOffset = 0.0f; + _yOffset = 0.0f; + break; + } + case idDeviceContext::CST_ANCHOR_VCENTER: { + _xScale = 1.0f; // no horizontal scaling + _xOffset = 0.0f; + _yOffset = (vidHeight * 0.5f) * (1.0f - _yScale); + break; + } + case idDeviceContext::CST_ANCHOR_BOTTOM: { + _xScale = 1.0f; // no horizontal scaling + _xOffset = 0.0f; + _yOffset = vidHeight * (1.0f - _yScale); + break; + } + case idDeviceContext::CST_ANCHOR_LEFT: { + _yScale = 1.0f; // no vertical scaling + _xOffset = 0.0f; + _yOffset = 0.0f; + break; + } + case idDeviceContext::CST_ANCHOR_HCENTER: { + _yScale = 1.0f; // no vertical scaling + _xOffset = (vidWidth * 0.5f) * (1.0f - _xScale); + _yOffset = 0.0f; + break; + } + case idDeviceContext::CST_ANCHOR_RIGHT: { + _yScale = 1.0f; // no vertical scaling + _xOffset = vidWidth * (1.0f - _xScale); + _yOffset = 0.0f; + break; + } + default: { + _xOffset = 0.0f; + _yOffset = 0.0f; + break; + } + } +} + + +void idDeviceContext::CstSetSize(int anchor, int anchorTo, float factor) { + vidWidth = VIRTUAL_WIDTH; + vidHeight = VIRTUAL_HEIGHT; + xScale = 1.0f; + yScale = 1.0f; + cst_xOffset = 0.0f; + cst_yOffset = 0.0f; + cstAdjustCoords = false; + + if (!CstGetVidScale(xScale, yScale)) { + return; + } + + if (anchorTo == idDeviceContext::CST_ANCHOR_NONE) { + CstAdjustParmsForAnchor(anchor, xScale, yScale, cst_xOffset, cst_yOffset); + } else { + float from_xScale = xScale; + float from_yScale = yScale; + float from_xOffset = 0.0f; + float from_yOffset = 0.0f; + CstAdjustParmsForAnchor(anchor, from_xScale, from_yScale, from_xOffset, from_yOffset); + + float to_xScale = xScale; + float to_yScale = yScale; + float to_xOffset = 0.0f; + float to_yOffset = 0.0f; + CstAdjustParmsForAnchor(anchorTo, to_xScale, to_yScale, to_xOffset, to_yOffset); + + factor = idMath::ClampFloat(0.0f, 1.0f, factor); + + xScale = from_xScale * (1.0f - factor) + to_xScale * factor; + yScale = from_yScale * (1.0f - factor) + to_yScale * factor; + + cst_xOffset = from_xOffset * (1.0f - factor) + to_xOffset * factor; + cst_yOffset = from_yOffset * (1.0f - factor) + to_yOffset * factor; + } + cstAdjustCoords = true; +} +//#modified-fva; END + int idDeviceContext::CharWidth( const char c, float scale ) { glyphInfo_t *glyph; float useScale; diff --git a/neo/ui/DeviceContext.h b/neo/ui/DeviceContext.h index 93d70343..e57d0f78 100644 --- a/neo/ui/DeviceContext.h +++ b/neo/ui/DeviceContext.h @@ -58,10 +58,12 @@ public: void DrawFilledRect(float x, float y, float width, float height, const idVec4 &color); int DrawText(const char *text, float textScale, int textAlign, idVec4 color, idRectangle rectDraw, bool wrap, int cursor = -1, bool calcOnly = false, idList *breaks = NULL, int limit = 0 ); void DrawMaterialRect( float x, float y, float w, float h, float size, const idMaterial *mat, const idVec4 &color); - void DrawStretchPic(float x, float y, float w, float h, float s0, float t0, float s1, float t1, const idMaterial *mat); + // fva/DG: added adjustCoords argument for CstDoom3 anchored GUIs and our old scale-menus-to-4:3-fix + void DrawStretchPic(float x, float y, float w, float h, float s0, float t0, float s1, float t1, const idMaterial *mat, bool adjustCoords = false); void DrawMaterialRotated(float x, float y, float w, float h, const idMaterial *mat, const idVec4 &color, float scalex = 1.0, float scaley = 1.0, float angle = 0.0f); - void DrawStretchPicRotated(float x, float y, float w, float h, float s0, float t0, float s1, float t1, const idMaterial *mat, float angle = 0.0f); + // fva/DG: added adjustCoords argument for CstDoom3 anchored GUIs and our old scale-menus-to-4:3-fix + void DrawStretchPicRotated(float x, float y, float w, float h, float s0, float t0, float s1, float t1, const idMaterial *mat, float angle = 0.0f, bool adjustCoords = false); int CharWidth( const char c, float scale ); int TextWidth(const char *text, float scale, int limit); @@ -76,13 +78,17 @@ public: void SetSize(float width, float height); + //#modified-fva; BEGIN + void CstSetSize(int anchor, int anchorTo, float factor); + //#modified-fva; END + const idMaterial *GetScrollBarImage(int index); void DrawCursor(float *x, float *y, float size); void SetCursor(int n); - + // DG: Note: not sure if AdjustCoords() works entirely as it should, but it seems + // good enough for the idRenderWindow with the mars globe in the main menu void AdjustCoords(float *x, float *y, float *w, float *h); - void AdjustCursorCoords(float *x, float *y, float *w, float *h); // DG: added for "render menus as 4:3" hack bool ClippedCoords(float *x, float *y, float *w, float *h); bool ClippedCoords(float *x, float *y, float *w, float *h, float *s1, float *t1, float *s2, float *t2); @@ -128,6 +134,27 @@ public: SCROLLBAR_COUNT }; + //#modified-fva; BEGIN + enum { + CST_ANCHOR_NONE = -1, + CST_ANCHOR_TOP_LEFT, + CST_ANCHOR_TOP_CENTER, + CST_ANCHOR_TOP_RIGHT, + CST_ANCHOR_CENTER_LEFT, + CST_ANCHOR_CENTER_CENTER, + CST_ANCHOR_CENTER_RIGHT, + CST_ANCHOR_BOTTOM_LEFT, + CST_ANCHOR_BOTTOM_CENTER, + CST_ANCHOR_BOTTOM_RIGHT, + CST_ANCHOR_TOP, + CST_ANCHOR_VCENTER, + CST_ANCHOR_BOTTOM, + CST_ANCHOR_LEFT, + CST_ANCHOR_HCENTER, + CST_ANCHOR_RIGHT + }; + //#modified-fva; END + static idVec4 colorPurple; static idVec4 colorOrange; static idVec4 colorYellow; @@ -153,6 +180,12 @@ private: float xScale; float yScale; + //#modified-fva; BEGIN + float cst_xOffset; + float cst_yOffset; + bool cstAdjustCoords; + //#modified-fva; END + float vidHeight; float vidWidth; diff --git a/neo/ui/SimpleWindow.cpp b/neo/ui/SimpleWindow.cpp index d8884cee..b5099b2e 100644 --- a/neo/ui/SimpleWindow.cpp +++ b/neo/ui/SimpleWindow.cpp @@ -27,6 +27,7 @@ If you have questions concerning this license or the applicable additional terms */ #include "sys/platform.h" +#include "framework/Session.h" #include "ui/DeviceContext.h" #include "ui/Window.h" #include "ui/UserInterfaceLocal.h" @@ -77,6 +78,13 @@ idSimpleWindow::idSimpleWindow(idWindow *win) { hideCursor = win->hideCursor; + //#modified-fva; BEGIN + cstAnchor = win->cstAnchor; + cstAnchorTo = win->cstAnchorTo; + cstAnchorFactor = win->cstAnchorFactor; + cstNoClipBackground = win->cstNoClipBackground; + //#modified-fva; END + idWindow *parent = win->GetParent(); if (parent) { if (text.NeedsUpdate()) { @@ -112,6 +120,18 @@ idSimpleWindow::idSimpleWindow(idWindow *win) { if (backGroundName.NeedsUpdate()) { parent->AddUpdateVar(&backGroundName); } + + //#modified-fva; BEGIN + if (cstAnchor.NeedsUpdate()) { + parent->AddUpdateVar(&cstAnchor); + } + if (cstAnchorTo.NeedsUpdate()) { + parent->AddUpdateVar(&cstAnchorTo); + } + if (cstAnchorFactor.NeedsUpdate()) { + parent->AddUpdateVar(&cstAnchorFactor); + } + //#modified-fva; END } } @@ -223,14 +243,41 @@ void idSimpleWindow::Redraw(float x, float y) { CalcClientRect(0, 0); dc->SetFont(fontNum); + + //#modified-fva; BEGIN + if (mParent && mParent->cstAnchor != idDeviceContext::CST_ANCHOR_NONE) { + cstAnchor = mParent->cstAnchor; + cstAnchorTo = mParent->cstAnchorTo; + cstAnchorFactor = mParent->cstAnchorFactor; + } + extern idCVar cst_hudAdjustAspect; + if (!cst_hudAdjustAspect.GetBool() || cstAnchor == idDeviceContext::CST_ANCHOR_NONE) { + if (mParent) { + dc->SetSize(mParent->forceAspectWidth, mParent->forceAspectHeight); + } else { + dc->SetSize(VIRTUAL_WIDTH, VIRTUAL_HEIGHT); + } + } else { + dc->CstSetSize(cstAnchor, cstAnchorTo, cstAnchorFactor); + } + //#modified-fva; END + drawRect.Offset(x, y); clientRect.Offset(x, y); textRect.Offset(x, y); SetupTransforms(x, y); - if ( flags & WIN_NOCLIP ) { + // fva's cst: added cstNoClipBackground + if ((flags & WIN_NOCLIP) || cstNoClipBackground) { dc->EnableClipping( false ); } DrawBackground(drawRect); + + //#modified-fva; BEGIN + if (!(flags & WIN_NOCLIP) && cstNoClipBackground) { + dc->EnableClipping(true); + } + //#modified-fva; END + DrawBorderAndCaption(drawRect); if ( textShadow ) { idStr shadowText = text; @@ -283,6 +330,12 @@ intptr_t idSimpleWindow::GetWinVarOffset( idWinVar *wv, drawWin_t* owner) { ret = (ptrdiff_t)&this->rotate - (ptrdiff_t)this; } + //#modified-fva; BEGIN + if (wv == &cstAnchorFactor) { + ret = (ptrdiff_t)&this->cstAnchorFactor - (ptrdiff_t)this; + } + //#modified-fva; END + if ( ret != -1 ) { owner->simp = this; } @@ -324,6 +377,17 @@ idWinVar *idSimpleWindow::GetWinVarByName(const char *_name) { if (idStr::Icmp(_name, "text") == 0) { retVar = &text; } + + //#modified-fva; BEGIN + if (idStr::Icmp(_name, "cstAnchor") == 0) { + retVar = &cstAnchor; + } else if (idStr::Icmp(_name, "cstAnchorTo") == 0) { + retVar = &cstAnchorTo; + } else if (idStr::Icmp(_name, "cstAnchorFactor") == 0) { + retVar = &cstAnchorFactor; + } + //#modified-fva; END + return retVar; } @@ -359,6 +423,13 @@ void idSimpleWindow::WriteToSaveGame( idFile *savefile ) { rotate.WriteToSaveGame( savefile ); shear.WriteToSaveGame( savefile ); backGroundName.WriteToSaveGame( savefile ); + + //#modified-fva; BEGIN // FIXME: savegame version? + cstAnchor.WriteToSaveGame(savefile); + cstAnchorTo.WriteToSaveGame(savefile); + cstAnchorFactor.WriteToSaveGame(savefile); + savefile->Write(&cstNoClipBackground, sizeof(cstNoClipBackground)); + //#modified-fva; END int stringLen; @@ -406,6 +477,16 @@ void idSimpleWindow::ReadFromSaveGame( idFile *savefile ) { shear.ReadFromSaveGame( savefile ); backGroundName.ReadFromSaveGame( savefile ); + //#modified-fva; BEGIN + // TODO: why does this have to be read from the savegame anyway, does it change? + if ( session->GetSaveGameVersion() >= 18 ) { + cstAnchor.ReadFromSaveGame(savefile); + cstAnchorTo.ReadFromSaveGame(savefile); + cstAnchorFactor.ReadFromSaveGame(savefile); + savefile->Read(&cstNoClipBackground, sizeof(cstNoClipBackground)); + } // else keep default values, I guess + //#modified-fva; END + int stringLen; savefile->Read( &stringLen, sizeof( stringLen ) ); diff --git a/neo/ui/SimpleWindow.h b/neo/ui/SimpleWindow.h index 0268cc6d..3256d8b7 100644 --- a/neo/ui/SimpleWindow.h +++ b/neo/ui/SimpleWindow.h @@ -98,6 +98,13 @@ protected: idWindow * mParent; idWinBool hideCursor; + + //#modified-fva; BEGIN + idWinInt cstAnchor; + idWinInt cstAnchorTo; // for anchor transitions + idWinFloat cstAnchorFactor; // for anchor transitions + bool cstNoClipBackground; + //#modified-fva; END }; #endif /* !__SIMPLEWIN_H__ */ diff --git a/neo/ui/Window.cpp b/neo/ui/Window.cpp index 3948cea3..bf900ae8 100644 --- a/neo/ui/Window.cpp +++ b/neo/ui/Window.cpp @@ -54,6 +54,9 @@ bool idWindow::registerIsTemporary[MAX_EXPRESSION_REGISTERS]; // statics to ass idCVar idWindow::gui_debug( "gui_debug", "0", CVAR_GUI | CVAR_BOOL, "" ); idCVar idWindow::gui_edit( "gui_edit", "0", CVAR_GUI | CVAR_BOOL, "" ); +//#modified-fva; BEGIN +idCVar cst_hudAdjustAspect("cst_hudAdjustAspect", "1", CVAR_GUI | CVAR_BOOL | CVAR_ARCHIVE, "adjust the HUD's aspect when the screen aspect ratio isn't 4:3"); +//#modified-fva; END extern idCVar r_skipGuiShaders; // 1 = don't render any gui elements on surfaces extern idCVar r_scaleMenusTo43; @@ -80,6 +83,15 @@ const idRegEntry idWindow::RegisterVars[] = { { "choices", idRegister::STRING }, { "choiceVar", idRegister::STRING }, { "bind", idRegister::STRING }, + //#modified-fva; BEGIN - FIXME: why not at the end of the list? + { "cstLayer", idRegister::INT }, + { "cstPseudoBit", idRegister::INT }, + { "cstResetScrollbar", idRegister::BOOL }, + { "cstWriteTop", idRegister::BOOL }, + { "cstAnchor", idRegister::INT }, + { "cstAnchorTo", idRegister::INT }, + { "cstAnchorFactor", idRegister::FLOAT }, + //#modified-fva; END { "modelRotate", idRegister::VEC4 }, { "modelOrigin", idRegister::VEC4 }, { "lightOrigin", idRegister::VEC4 }, @@ -154,6 +166,13 @@ void idWindow::CommonInit() { } hideCursor = false; + + //#modified-fva; BEGIN + cstAnchor = idDeviceContext::CST_ANCHOR_NONE; + cstAnchorTo = idDeviceContext::CST_ANCHOR_NONE; + cstAnchorFactor = 0.0f; + cstNoClipBackground = false; + //#modified-fva; END } /* @@ -1247,10 +1266,29 @@ void idWindow::Redraw(float x, float y) { CalcClientRect(0, 0); SetFont(); + + //#modified-fva; BEGIN + /* //if (flags & WIN_DESKTOP) { // see if this window forces a new aspect ratio dc->SetSize(forceAspectWidth, forceAspectHeight); //} + */ + if (parent && parent->cstAnchor != idDeviceContext::CST_ANCHOR_NONE) { + cstAnchor = parent->cstAnchor; + cstAnchorTo = parent->cstAnchorTo; + cstAnchorFactor = parent->cstAnchorFactor; + } + if (!cst_hudAdjustAspect.GetBool() || cstAnchor == idDeviceContext::CST_ANCHOR_NONE) { + dc->SetSize(forceAspectWidth, forceAspectHeight); + } else { + // DG: if this Window uses anchors, it already is aspect-ratio-aware + // so a potentially active menuscalefix must be disabled + // (else it's "fixed" twice => wrong ratio in other direction) + dc->SetMenuScaleFix(false); + dc->CstSetSize(cstAnchor, cstAnchorTo, cstAnchorFactor); + } + //#modified-fva; END //FIXME: go to screen coord tracking drawRect.Offset(x, y); @@ -1265,7 +1303,19 @@ void idWindow::Redraw(float x, float y) { dc->GetTransformInfo( oldOrg, oldTrans ); SetupTransforms(x, y); + //#modified-fva; BEGIN + if (cstNoClipBackground) { + dc->EnableClipping(false); + } + //#modified-fva; END + DrawBackground(drawRect); + + //#modified-fva; BEGIN + if (cstNoClipBackground) { + dc->EnableClipping(true); + } + //#modified-fva; END DrawBorderAndCaption(drawRect); if ( !( flags & WIN_NOCLIP) ) { @@ -1328,6 +1378,15 @@ void idWindow::SetDC(idDeviceContext *d) { //if (flags & WIN_DESKTOP) { dc->SetSize(forceAspectWidth, forceAspectHeight); //} + + //#modified-fva; BEGIN + if (parent && parent->cstAnchor != idDeviceContext::CST_ANCHOR_NONE) { + cstAnchor = parent->cstAnchor; + cstAnchorTo = parent->cstAnchorTo; + cstAnchorFactor = parent->cstAnchorFactor; + } + //#modified-fva; END + int c = children.Num(); for (int i = 0; i < c; i++) { children[i]->SetDC(d); @@ -1774,6 +1833,12 @@ intptr_t idWindow::GetWinVarOffset( idWinVar *wv, drawWin_t* owner) { ret = (ptrdiff_t)&this->rotate - (ptrdiff_t)this; } + //#modified-fva; BEGIN + if (wv == &cstAnchorFactor) { + ret = (ptrdiff_t)&this->cstAnchorFactor - (ptrdiff_t)this; + } + //#modified-fva; END + if ( ret != -1 ) { owner->win = this; return ret; @@ -1807,7 +1872,7 @@ idWinVar *idWindow::GetWinVarByName(const char *_name, bool fixup, drawWin_t** o if (idStr::Icmp(_name, "notime") == 0) { retVar = &noTime; - } + } // FIXME: why does all this code not use "else if"?! if (idStr::Icmp(_name, "background") == 0) { retVar = &backGroundName; } @@ -1850,6 +1915,15 @@ idWinVar *idWindow::GetWinVarByName(const char *_name, bool fixup, drawWin_t** o if (idStr::Icmp(_name, "hidecursor") == 0) { retVar = &hideCursor; } + //#modified-fva; BEGIN + if (idStr::Icmp(_name, "cstAnchor") == 0) { + retVar = &cstAnchor; + } else if (idStr::Icmp(_name, "cstAnchorTo") == 0) { + retVar = &cstAnchorTo; + } else if (idStr::Icmp(_name, "cstAnchorFactor") == 0) { + retVar = &cstAnchorFactor; + } + //#modified-fva; END idStr key = _name; bool guiVar = (key.Find(VAR_GUIPREFIX) >= 0); @@ -2075,6 +2149,14 @@ bool idWindow::ParseInternalVar(const char *_name, idParser *src) { fontNum = dc->FindFont( fontStr ); return true; } + + //#modified-fva; BEGIN + if (idStr::Icmp(_name, "cstNoClipBackground") == 0) { + cstNoClipBackground = src->ParseBool(); + return true; + } + //#modified-fva; END + return false; } @@ -3543,6 +3625,13 @@ void idWindow::WriteToSaveGame( idFile *savefile ) { backGroundName.WriteToSaveGame( savefile ); hideCursor.WriteToSaveGame(savefile); + //#modified-fva; BEGIN // FIXME: savegame version? + cstAnchor.WriteToSaveGame(savefile); + cstAnchorTo.WriteToSaveGame(savefile); + cstAnchorFactor.WriteToSaveGame(savefile); + savefile->Write(&cstNoClipBackground, sizeof(cstNoClipBackground)); + //#modified-fva; END + // Defined Vars for ( i = 0; i < definedVars.Num(); i++ ) { definedVars[i]->WriteToSaveGame( savefile ); @@ -3693,6 +3782,16 @@ void idWindow::ReadFromSaveGame( idFile *savefile ) { hideCursor = false; } + //#modified-fva; BEGIN + // TODO: why does this have to be read from the savegame anyway, does it change? + if ( session->GetSaveGameVersion() >= 18 ) { + cstAnchor.ReadFromSaveGame(savefile); + cstAnchorTo.ReadFromSaveGame(savefile); + cstAnchorFactor.ReadFromSaveGame(savefile); + savefile->Read(&cstNoClipBackground, sizeof(cstNoClipBackground)); + } // else keep default values, I guess + //#modified-fva; END + // Defined Vars for ( i = 0; i < definedVars.Num(); i++ ) { definedVars[i]->ReadFromSaveGame( savefile ); @@ -3825,6 +3924,11 @@ void idWindow::FixupTransitions() { } else if ( transitions[i].offset == (ptrdiff_t)&this->rotate - (ptrdiff_t)this ) { transitions[i].data = &dw->win->rotate; } + //#modified-fva; BEGIN + else if ( transitions[i].offset == (ptrdiff_t)&this->cstAnchorFactor - (ptrdiff_t)this ) { + transitions[i].data = &dw->win->cstAnchorFactor; + } + //#modified-fva; END } else { if ( transitions[i].offset == (ptrdiff_t)&this->rect - (ptrdiff_t)this ) { transitions[i].data = &dw->simp->rect; @@ -3841,6 +3945,11 @@ void idWindow::FixupTransitions() { } else if ( transitions[i].offset == (ptrdiff_t)&this->rotate - (ptrdiff_t)this ) { transitions[i].data = &dw->simp->rotate; } + //#modified-fva; BEGIN + else if ( transitions[i].offset == (ptrdiff_t)&this->cstAnchorFactor - (ptrdiff_t)this ) { + transitions[i].data = &dw->simp->cstAnchorFactor; + } + //#modified-fva; END } } if ( transitions[i].data == NULL ) { diff --git a/neo/ui/Window.h b/neo/ui/Window.h index 96f6534e..1cf29f85 100644 --- a/neo/ui/Window.h +++ b/neo/ui/Window.h @@ -452,6 +452,13 @@ protected: idRegisterList regList; idWinBool hideCursor; + + //#modified-fva; BEGIN + idWinInt cstAnchor; + idWinInt cstAnchorTo; // for anchor transitions + idWinFloat cstAnchorFactor; // for anchor transitions + bool cstNoClipBackground; + //#modified-fva; END }; ID_INLINE void idWindow::AddDefinedVar( idWinVar* var ) {