mirror of
https://github.com/dhewm/dhewm3.git
synced 2025-03-13 22:32:32 +00:00
Scale "Menu" GUIs (incl. PDA + fullscreen vids) to 4:3
So stuff doesn't look so distorted in widescreen resolutions. Implies that there are black bars on the left/right then.. Can be disabled with "r_scaleMenusTo43 0" Does *not* affect the HUD (incl. crosshair) - scaling it automagically would be very hard (or impossible), because it doesn't only render the crosshair, healthpoints etc, but also fullscreen effects like the screen turning red when the player is hit - and fullscreen effects would look very shitty if they didn't cover the whole screen but had "empty" bars on left/right. (Mostly) fixes #188 and #189
This commit is contained in:
parent
7a8f0e9fdb
commit
e41bf2b147
6 changed files with 142 additions and 11 deletions
|
@ -223,6 +223,9 @@ idCVar r_materialOverride( "r_materialOverride", "", CVAR_RENDERER, "overrides a
|
|||
|
||||
idCVar r_debugRenderToTexture( "r_debugRenderToTexture", "0", CVAR_RENDERER | CVAR_INTEGER, "" );
|
||||
|
||||
// DG: let users disable the "scale menus to 4:3" hack
|
||||
idCVar r_scaleMenusTo43( "r_scaleMenusTo43", "1", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_BOOL, "Scale menus, fullscreen videos and PDA to 4:3 aspect ratio" );
|
||||
|
||||
// define qgl functions
|
||||
#define QGLPROC(name, rettype, args) rettype (APIENTRYP q##name) args;
|
||||
#include "renderer/qgl_proc.h"
|
||||
|
|
|
@ -135,6 +135,10 @@ void idDeviceContext::Init() {
|
|||
mat.Identity();
|
||||
origin.Zero();
|
||||
initialized = true;
|
||||
|
||||
// DG: this is used for the "make sure menus are rendered as 4:3" hack
|
||||
fixScaleForMenu.Set(1, 1);
|
||||
fixOffsetForMenu.Set(0, 0);
|
||||
}
|
||||
|
||||
void idDeviceContext::Shutdown() {
|
||||
|
@ -254,8 +258,67 @@ bool idDeviceContext::ClippedCoords(float *x, float *y, float *w, float *h, floa
|
|||
return (*w == 0 || *h == 0) ? true : false;
|
||||
}
|
||||
|
||||
// DG: this is used for the "make sure menus are rendered as 4:3" hack
|
||||
void idDeviceContext::SetMenuScaleFix(bool enable) {
|
||||
if(enable) {
|
||||
float w = renderSystem->GetScreenWidth();
|
||||
float h = renderSystem->GetScreenHeight();
|
||||
float aspectRatio = w/h;
|
||||
static const float virtualAspectRatio = float(VIRTUAL_WIDTH)/float(VIRTUAL_HEIGHT); // 4:3
|
||||
if(aspectRatio > 1.4f) {
|
||||
// widescreen (4:3 is 1.333 3:2 is 1.5, 16:10 is 1.6, 16:9 is 1.7778)
|
||||
// => we need to scale and offset X
|
||||
// All the coordinates here assume 640x480 (VIRTUAL_WIDTH x VIRTUAL_HEIGHT)
|
||||
// screensize, so to fit a 4:3 menu into 640x480 stretched to a widescreen,
|
||||
// we need do decrease the width to something smaller than 640 and center
|
||||
// the result with an offset
|
||||
float scaleX = virtualAspectRatio/aspectRatio;
|
||||
float offsetX = (1.0f-scaleX)*(VIRTUAL_WIDTH*0.5f); // (640 - scale*640)/2
|
||||
fixScaleForMenu.Set(scaleX, 1);
|
||||
fixOffsetForMenu.Set(offsetX, 0);
|
||||
} else if(aspectRatio < 1.24f) {
|
||||
// portrait-mode, "thinner" than 5:4 (which is 1.25)
|
||||
// => we need to scale and offset Y
|
||||
// it's analogue to the other case, but inverted and with height and Y
|
||||
float scaleY = aspectRatio/virtualAspectRatio;
|
||||
float offsetY = (1.0f - scaleY)*(VIRTUAL_HEIGHT*0.5f); // (480 - scale*480)/2
|
||||
fixScaleForMenu.Set(1, scaleY);
|
||||
fixOffsetForMenu.Set(0, offsetY);
|
||||
}
|
||||
} else {
|
||||
fixScaleForMenu.Set(1, 1);
|
||||
fixOffsetForMenu.Set(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void idDeviceContext::AdjustCoords(float *x, float *y, float *w, float *h) {
|
||||
|
||||
if (x) {
|
||||
*x *= xScale;
|
||||
|
||||
*x *= fixScaleForMenu.x; // DG: for "render menus as 4:3" hack
|
||||
*x += fixOffsetForMenu.x;
|
||||
}
|
||||
if (y) {
|
||||
*y *= yScale;
|
||||
|
||||
*y *= fixScaleForMenu.y; // DG: for "render menus as 4:3" hack
|
||||
*y += fixOffsetForMenu.y;
|
||||
}
|
||||
if (w) {
|
||||
*w *= xScale;
|
||||
|
||||
*w *= fixScaleForMenu.x; // DG: for "render menus as 4:3" hack
|
||||
}
|
||||
if (h) {
|
||||
*h *= yScale;
|
||||
|
||||
*h *= fixScaleForMenu.y; // DG: for "render menus as 4:3" hack
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
@ -637,8 +700,16 @@ void idDeviceContext::DrawCursor(float *x, float *y, float size) {
|
|||
}
|
||||
|
||||
renderSystem->SetColor(colorWhite);
|
||||
AdjustCoords(x, y, &size, &size);
|
||||
DrawStretchPic( *x, *y, size, size, 0, 0, 1, 1, cursorImages[cursor]);
|
||||
|
||||
// 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);
|
||||
float sizeW = size * fixScaleForMenu.x;
|
||||
float sizeH = size * fixScaleForMenu.y;
|
||||
float fixedX = *x * fixScaleForMenu.x + fixOffsetForMenu.x;
|
||||
float fixedY = *y * fixScaleForMenu.y + fixOffsetForMenu.y;
|
||||
|
||||
DrawStretchPic(fixedX, fixedY, sizeW, sizeH, 0, 0, 1, 1, cursorImages[cursor]);
|
||||
}
|
||||
/*
|
||||
=======================================================================================================================
|
||||
|
|
|
@ -82,6 +82,7 @@ public:
|
|||
void SetCursor(int n);
|
||||
|
||||
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);
|
||||
|
||||
|
@ -98,6 +99,12 @@ public:
|
|||
|
||||
void DrawEditCursor(float x, float y, float scale);
|
||||
|
||||
// DG: this is used for the "make sure menus are rendered as 4:3" hack
|
||||
void SetMenuScaleFix(bool enable);
|
||||
bool IsMenuScaleFixActive() const {
|
||||
return fixOffsetForMenu.x != 0.0f || fixOffsetForMenu.y != 0.0f;
|
||||
}
|
||||
|
||||
enum {
|
||||
CURSOR_ARROW,
|
||||
CURSOR_HAND,
|
||||
|
@ -165,6 +172,10 @@ private:
|
|||
bool initialized;
|
||||
|
||||
bool mbcs;
|
||||
|
||||
// DG: this is used for the "make sure menus are rendered as 4:3" hack
|
||||
idVec2 fixScaleForMenu;
|
||||
idVec2 fixOffsetForMenu;
|
||||
};
|
||||
|
||||
#endif /* !__DEVICECONTEXT_H__ */
|
||||
|
|
|
@ -140,7 +140,7 @@ void idRenderWindow::Render( int time ) {
|
|||
|
||||
|
||||
|
||||
void idRenderWindow::Draw(int time, float x, float y) {
|
||||
void idRenderWindow::Draw(int time, float x_, float y_) {
|
||||
PreRender();
|
||||
Render(time);
|
||||
|
||||
|
@ -154,10 +154,20 @@ void idRenderWindow::Draw(int time, float x, float y) {
|
|||
refdef.shaderParms[2] = 1;
|
||||
refdef.shaderParms[3] = 1;
|
||||
|
||||
refdef.x = drawRect.x;
|
||||
refdef.y = drawRect.y;
|
||||
refdef.width = drawRect.w;
|
||||
refdef.height = drawRect.h;
|
||||
// DG: for scaling menus to 4:3 (like that spinning mars globe in the main menu)
|
||||
float x = drawRect.x;
|
||||
float y = drawRect.y;
|
||||
float w = drawRect.w;
|
||||
float h = drawRect.h;
|
||||
if(dc->IsMenuScaleFixActive()) {
|
||||
dc->AdjustCoords(&x, &y, &w, &h);
|
||||
}
|
||||
|
||||
refdef.x = x;
|
||||
refdef.y = y;
|
||||
refdef.width = w;
|
||||
refdef.height = h;
|
||||
// DG end
|
||||
refdef.fov_x = 90;
|
||||
refdef.fov_y = 2 * atan((float)drawRect.h / drawRect.w) * idMath::M_RAD2DEG;
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ If you have questions concerning this license or the applicable additional terms
|
|||
#include "ui/UserInterfaceLocal.h"
|
||||
|
||||
extern idCVar r_skipGuiShaders; // 1 = don't render any gui elements on surfaces
|
||||
extern idCVar r_scaleMenusTo43; // DG: for the "scale menus to 4:3" hack
|
||||
|
||||
idUserInterfaceManagerLocal uiManagerLocal;
|
||||
idUserInterfaceManager * uiManager = &uiManagerLocal;
|
||||
|
@ -349,11 +350,30 @@ const char *idUserInterfaceLocal::HandleEvent( const sysEvent_t *event, int _tim
|
|||
float w = renderSystem->GetScreenWidth();
|
||||
float h = renderSystem->GetScreenHeight();
|
||||
if( w <= 0.0f || h <= 0.0f ) {
|
||||
w = 640.0f;
|
||||
h = 480.0f;
|
||||
w = VIRTUAL_WIDTH;
|
||||
h = VIRTUAL_HEIGHT;
|
||||
}
|
||||
cursorX += event->evValue * (640.0f/w);
|
||||
cursorY += event->evValue2 * (480.0f/h);
|
||||
|
||||
if(r_scaleMenusTo43.GetBool()) {
|
||||
// in case we're scaling menus to 4:3, we need to take that into account
|
||||
// when scaling the mouse events.
|
||||
// no, we can't just call uiManagerLocal.dc.GetFixScaleForMenu() or sth like that,
|
||||
// because when we're here dc.SetMenuScaleFix(true) is not active and it'd just return (1, 1)!
|
||||
float aspectRatio = w/h;
|
||||
static const float virtualAspectRatio = float(VIRTUAL_WIDTH)/float(VIRTUAL_HEIGHT); // 4:3
|
||||
if(aspectRatio > 1.4f) {
|
||||
// widescreen (4:3 is 1.333 3:2 is 1.5, 16:10 is 1.6, 16:9 is 1.7778)
|
||||
// => we need to modify cursorX scaling, by modifying w
|
||||
w *= virtualAspectRatio/aspectRatio;
|
||||
} else if(aspectRatio < 1.24f) {
|
||||
// portrait-mode, "thinner" than 5:4 (which is 1.25)
|
||||
// => we need to scale cursorY via h
|
||||
h *= aspectRatio/virtualAspectRatio;
|
||||
}
|
||||
}
|
||||
|
||||
cursorX += event->evValue * (float(VIRTUAL_WIDTH)/w);
|
||||
cursorY += event->evValue2 * (float(VIRTUAL_HEIGHT)/h);
|
||||
} else {
|
||||
// not a fullscreen GUI but some ingame thing - no scaling needed
|
||||
cursorX += event->evValue;
|
||||
|
|
|
@ -56,6 +56,7 @@ idCVar idWindow::gui_debug( "gui_debug", "0", CVAR_GUI | CVAR_BOOL, "" );
|
|||
idCVar idWindow::gui_edit( "gui_edit", "0", CVAR_GUI | CVAR_BOOL, "" );
|
||||
|
||||
extern idCVar r_skipGuiShaders; // 1 = don't render any gui elements on surfaces
|
||||
extern idCVar r_scaleMenusTo43;
|
||||
|
||||
// made RegisterVars a member of idWindow
|
||||
const idRegEntry idWindow::RegisterVars[] = {
|
||||
|
@ -1207,6 +1208,14 @@ void idWindow::Redraw(float x, float y) {
|
|||
return;
|
||||
}
|
||||
|
||||
// DG: allow scaling menus to 4:3
|
||||
bool fixupFor43 = false;
|
||||
if ( (flags & (WIN_MENUGUI | WIN_DESKTOP)) == (WIN_MENUGUI | WIN_DESKTOP)
|
||||
&& r_scaleMenusTo43.GetBool() ) {
|
||||
fixupFor43 = true;
|
||||
dc->SetMenuScaleFix(true);
|
||||
}
|
||||
|
||||
if ( flags & WIN_SHOWTIME ) {
|
||||
dc->DrawText(va(" %0.1f seconds\n%s", (float)(time - timeLine) / 1000, gui->State().GetString("name")), 0.35f, 0, dc->colorWhite, idRectangle(100, 0, 80, 80), false);
|
||||
}
|
||||
|
@ -1219,6 +1228,9 @@ void idWindow::Redraw(float x, float y) {
|
|||
}
|
||||
|
||||
if (!visible) {
|
||||
if (fixupFor43) { // DG: gotta reset that before returning this function
|
||||
dc->SetMenuScaleFix(false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1287,6 +1299,10 @@ void idWindow::Redraw(float x, float y) {
|
|||
dc->EnableClipping(true);
|
||||
}
|
||||
|
||||
if (fixupFor43) { // DG: gotta reset that before returning this function
|
||||
dc->SetMenuScaleFix(false);
|
||||
}
|
||||
|
||||
drawRect.Offset(-x, -y);
|
||||
clientRect.Offset(-x, -y);
|
||||
textRect.Offset(-x, -y);
|
||||
|
|
Loading…
Reference in a new issue