Merge pull request #641 from DanielGibson/cst-ui

Support CstDoom3 GUIs for aspect-ratio-independent HUD
This commit is contained in:
Daniel Gibson 2025-01-22 01:55:58 +01:00 committed by GitHub
commit 63b84a8b8e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 572 additions and 37 deletions

View file

@ -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
}
}

View file

@ -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

View file

@ -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 );

View file

@ -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
}
}

View file

@ -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;

View file

@ -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<int> *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;

View file

@ -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 ) );

View file

@ -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__ */

View file

@ -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 ) {

View file

@ -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 ) {