2021-03-27 11:09:37 +00:00
|
|
|
/*
|
|
|
|
vid_win.c
|
|
|
|
|
|
|
|
Win32 vid component
|
|
|
|
|
|
|
|
Copyright (C) 1996-1997 Id Software, Inc.
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU General Public License
|
|
|
|
as published by the Free Software Foundation; either version 2
|
|
|
|
of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
|
|
|
|
See the GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to:
|
|
|
|
|
|
|
|
Free Software Foundation, Inc.
|
|
|
|
59 Temple Place - Suite 330
|
|
|
|
Boston, MA 02111-1307, USA
|
|
|
|
|
|
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include "config.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "winquake.h"
|
|
|
|
#include <ddraw.h>
|
|
|
|
|
|
|
|
#include "QF/cmd.h"
|
|
|
|
#include "QF/cvar.h"
|
|
|
|
#include "QF/input.h"
|
|
|
|
#include "QF/qargs.h"
|
|
|
|
#include "QF/sys.h"
|
|
|
|
#include "QF/va.h"
|
|
|
|
#include "QF/vid.h"
|
|
|
|
|
|
|
|
#include "context_win.h"
|
|
|
|
#include "r_shared.h"
|
2023-11-24 03:28:06 +00:00
|
|
|
#include "in_win.h"
|
2021-03-27 11:09:37 +00:00
|
|
|
#include "vid_internal.h"
|
|
|
|
#include "vid_sw.h"
|
|
|
|
|
|
|
|
HWND win_mainwindow;
|
|
|
|
HDC win_maindc;
|
2023-11-25 13:03:27 +00:00
|
|
|
HCURSOR win_arrow;
|
|
|
|
bool win_cursor_visible;
|
2021-03-27 11:09:37 +00:00
|
|
|
int win_palettized;
|
2023-11-26 04:40:00 +00:00
|
|
|
bool win_minimized;
|
|
|
|
bool win_focused;
|
|
|
|
bool win_canalttab;
|
2021-03-27 11:09:37 +00:00
|
|
|
sw_ctx_t *win_sw_context;
|
|
|
|
|
|
|
|
#define MODE_WINDOWED 0
|
|
|
|
#define MODE_SETTABLE_WINDOW 2
|
|
|
|
#define NO_MODE (MODE_WINDOWED - 1)
|
|
|
|
#define MODE_FULLSCREEN_DEFAULT (MODE_WINDOWED + 3)
|
|
|
|
|
2023-11-24 03:28:06 +00:00
|
|
|
#define WINDOW_CLASS PACKAGE_NAME "WindowClass"
|
|
|
|
|
[cvar] Make cvars properly typed
This is an extremely extensive patch as it hits every cvar, and every
usage of the cvars. Cvars no longer store the value they control,
instead, they use a cexpr value object to reference the value and
specify the value's type (currently, a null type is used for strings).
Non-string cvars are passed through cexpr, allowing expressions in the
cvars' settings. Also, cvars have returned to an enhanced version of the
original (id quake) registration scheme.
As a minor benefit, relevant code having direct access to the
cvar-controlled variables is probably a slight optimization as it
removed a pointer dereference, and the variables can be located for data
locality.
The static cvar descriptors are made private as an additional safety
layer, though there's nothing stopping external modification via
Cvar_FindVar (which is needed for adding listeners).
While not used yet (partly due to working out the design), cvars can
have a validation function.
Registering a cvar allows a primary listener (and its data) to be
specified: it will always be called first when the cvar is modified. The
combination of proper listeners and direct access to the controlled
variable greatly simplifies the more complex cvar interactions as much
less null checking is required, and there's no need for one cvar's
callback to call another's.
nq-x11 is known to work at least well enough for the demos. More testing
will come.
2022-04-23 03:22:45 +00:00
|
|
|
int vid_ddraw;
|
|
|
|
static cvar_t vid_ddraw_cvar = {
|
|
|
|
.name = "vid_ddraw",
|
|
|
|
.description =
|
|
|
|
"",
|
|
|
|
.default_value = "1",
|
|
|
|
.flags = CVAR_NONE,
|
|
|
|
.value = { .type = &cexpr_int, .value = &vid_ddraw },
|
|
|
|
};
|
2021-03-27 11:09:37 +00:00
|
|
|
|
|
|
|
// Note that 0 is MODE_WINDOWED
|
[cvar] Make cvars properly typed
This is an extremely extensive patch as it hits every cvar, and every
usage of the cvars. Cvars no longer store the value they control,
instead, they use a cexpr value object to reference the value and
specify the value's type (currently, a null type is used for strings).
Non-string cvars are passed through cexpr, allowing expressions in the
cvars' settings. Also, cvars have returned to an enhanced version of the
original (id quake) registration scheme.
As a minor benefit, relevant code having direct access to the
cvar-controlled variables is probably a slight optimization as it
removed a pointer dereference, and the variables can be located for data
locality.
The static cvar descriptors are made private as an additional safety
layer, though there's nothing stopping external modification via
Cvar_FindVar (which is needed for adding listeners).
While not used yet (partly due to working out the design), cvars can
have a validation function.
Registering a cvar allows a primary listener (and its data) to be
specified: it will always be called first when the cvar is modified. The
combination of proper listeners and direct access to the controlled
variable greatly simplifies the more complex cvar interactions as much
less null checking is required, and there's no need for one cvar's
callback to call another's.
nq-x11 is known to work at least well enough for the demos. More testing
will come.
2022-04-23 03:22:45 +00:00
|
|
|
static int vid_mode;
|
|
|
|
static cvar_t vid_mode_cvar = {
|
|
|
|
.name = "vid_mode",
|
|
|
|
.description =
|
|
|
|
"",
|
|
|
|
.default_value = "0",
|
|
|
|
.flags = CVAR_NONE,
|
|
|
|
.value = { .type = &cexpr_int, .value = &vid_mode },
|
|
|
|
};
|
2021-03-27 11:09:37 +00:00
|
|
|
|
|
|
|
// Note that 0 is MODE_WINDOWED
|
2022-04-24 11:04:06 +00:00
|
|
|
int _vid_default_mode;
|
[cvar] Make cvars properly typed
This is an extremely extensive patch as it hits every cvar, and every
usage of the cvars. Cvars no longer store the value they control,
instead, they use a cexpr value object to reference the value and
specify the value's type (currently, a null type is used for strings).
Non-string cvars are passed through cexpr, allowing expressions in the
cvars' settings. Also, cvars have returned to an enhanced version of the
original (id quake) registration scheme.
As a minor benefit, relevant code having direct access to the
cvar-controlled variables is probably a slight optimization as it
removed a pointer dereference, and the variables can be located for data
locality.
The static cvar descriptors are made private as an additional safety
layer, though there's nothing stopping external modification via
Cvar_FindVar (which is needed for adding listeners).
While not used yet (partly due to working out the design), cvars can
have a validation function.
Registering a cvar allows a primary listener (and its data) to be
specified: it will always be called first when the cvar is modified. The
combination of proper listeners and direct access to the controlled
variable greatly simplifies the more complex cvar interactions as much
less null checking is required, and there's no need for one cvar's
callback to call another's.
nq-x11 is known to work at least well enough for the demos. More testing
will come.
2022-04-23 03:22:45 +00:00
|
|
|
static cvar_t _vid_default_mode_cvar = {
|
|
|
|
.name = "_vid_default_mode",
|
|
|
|
.description =
|
|
|
|
"",
|
|
|
|
.default_value = "0",
|
|
|
|
.flags = CVAR_ARCHIVE,
|
2022-04-24 11:04:06 +00:00
|
|
|
.value = { .type = &cexpr_int, .value = &_vid_default_mode },
|
[cvar] Make cvars properly typed
This is an extremely extensive patch as it hits every cvar, and every
usage of the cvars. Cvars no longer store the value they control,
instead, they use a cexpr value object to reference the value and
specify the value's type (currently, a null type is used for strings).
Non-string cvars are passed through cexpr, allowing expressions in the
cvars' settings. Also, cvars have returned to an enhanced version of the
original (id quake) registration scheme.
As a minor benefit, relevant code having direct access to the
cvar-controlled variables is probably a slight optimization as it
removed a pointer dereference, and the variables can be located for data
locality.
The static cvar descriptors are made private as an additional safety
layer, though there's nothing stopping external modification via
Cvar_FindVar (which is needed for adding listeners).
While not used yet (partly due to working out the design), cvars can
have a validation function.
Registering a cvar allows a primary listener (and its data) to be
specified: it will always be called first when the cvar is modified. The
combination of proper listeners and direct access to the controlled
variable greatly simplifies the more complex cvar interactions as much
less null checking is required, and there's no need for one cvar's
callback to call another's.
nq-x11 is known to work at least well enough for the demos. More testing
will come.
2022-04-23 03:22:45 +00:00
|
|
|
};
|
2021-03-27 11:09:37 +00:00
|
|
|
|
|
|
|
// Note that 3 is MODE_FULLSCREEN_DEFAULT
|
[cvar] Make cvars properly typed
This is an extremely extensive patch as it hits every cvar, and every
usage of the cvars. Cvars no longer store the value they control,
instead, they use a cexpr value object to reference the value and
specify the value's type (currently, a null type is used for strings).
Non-string cvars are passed through cexpr, allowing expressions in the
cvars' settings. Also, cvars have returned to an enhanced version of the
original (id quake) registration scheme.
As a minor benefit, relevant code having direct access to the
cvar-controlled variables is probably a slight optimization as it
removed a pointer dereference, and the variables can be located for data
locality.
The static cvar descriptors are made private as an additional safety
layer, though there's nothing stopping external modification via
Cvar_FindVar (which is needed for adding listeners).
While not used yet (partly due to working out the design), cvars can
have a validation function.
Registering a cvar allows a primary listener (and its data) to be
specified: it will always be called first when the cvar is modified. The
combination of proper listeners and direct access to the controlled
variable greatly simplifies the more complex cvar interactions as much
less null checking is required, and there's no need for one cvar's
callback to call another's.
nq-x11 is known to work at least well enough for the demos. More testing
will come.
2022-04-23 03:22:45 +00:00
|
|
|
static int _vid_default_mode_win;
|
|
|
|
static cvar_t _vid_default_mode_win_cvar = {
|
|
|
|
.name = "_vid_default_mode_win",
|
|
|
|
.description =
|
|
|
|
"",
|
|
|
|
.default_value = "3",
|
|
|
|
.flags = CVAR_ARCHIVE,
|
|
|
|
.value = { .type = &cexpr_int, .value = &_vid_default_mode_win },
|
|
|
|
};
|
2022-04-24 11:04:06 +00:00
|
|
|
int vid_wait;
|
[cvar] Make cvars properly typed
This is an extremely extensive patch as it hits every cvar, and every
usage of the cvars. Cvars no longer store the value they control,
instead, they use a cexpr value object to reference the value and
specify the value's type (currently, a null type is used for strings).
Non-string cvars are passed through cexpr, allowing expressions in the
cvars' settings. Also, cvars have returned to an enhanced version of the
original (id quake) registration scheme.
As a minor benefit, relevant code having direct access to the
cvar-controlled variables is probably a slight optimization as it
removed a pointer dereference, and the variables can be located for data
locality.
The static cvar descriptors are made private as an additional safety
layer, though there's nothing stopping external modification via
Cvar_FindVar (which is needed for adding listeners).
While not used yet (partly due to working out the design), cvars can
have a validation function.
Registering a cvar allows a primary listener (and its data) to be
specified: it will always be called first when the cvar is modified. The
combination of proper listeners and direct access to the controlled
variable greatly simplifies the more complex cvar interactions as much
less null checking is required, and there's no need for one cvar's
callback to call another's.
nq-x11 is known to work at least well enough for the demos. More testing
will come.
2022-04-23 03:22:45 +00:00
|
|
|
static cvar_t vid_wait_cvar = {
|
|
|
|
.name = "vid_wait",
|
|
|
|
.description =
|
|
|
|
"",
|
|
|
|
.default_value = "0",
|
|
|
|
.flags = CVAR_NONE,
|
2022-04-24 11:04:06 +00:00
|
|
|
.value = { .type = &cexpr_int, .value = &vid_wait },
|
[cvar] Make cvars properly typed
This is an extremely extensive patch as it hits every cvar, and every
usage of the cvars. Cvars no longer store the value they control,
instead, they use a cexpr value object to reference the value and
specify the value's type (currently, a null type is used for strings).
Non-string cvars are passed through cexpr, allowing expressions in the
cvars' settings. Also, cvars have returned to an enhanced version of the
original (id quake) registration scheme.
As a minor benefit, relevant code having direct access to the
cvar-controlled variables is probably a slight optimization as it
removed a pointer dereference, and the variables can be located for data
locality.
The static cvar descriptors are made private as an additional safety
layer, though there's nothing stopping external modification via
Cvar_FindVar (which is needed for adding listeners).
While not used yet (partly due to working out the design), cvars can
have a validation function.
Registering a cvar allows a primary listener (and its data) to be
specified: it will always be called first when the cvar is modified. The
combination of proper listeners and direct access to the controlled
variable greatly simplifies the more complex cvar interactions as much
less null checking is required, and there's no need for one cvar's
callback to call another's.
nq-x11 is known to work at least well enough for the demos. More testing
will come.
2022-04-23 03:22:45 +00:00
|
|
|
};
|
2022-04-24 11:04:06 +00:00
|
|
|
int vid_nopageflip;
|
[cvar] Make cvars properly typed
This is an extremely extensive patch as it hits every cvar, and every
usage of the cvars. Cvars no longer store the value they control,
instead, they use a cexpr value object to reference the value and
specify the value's type (currently, a null type is used for strings).
Non-string cvars are passed through cexpr, allowing expressions in the
cvars' settings. Also, cvars have returned to an enhanced version of the
original (id quake) registration scheme.
As a minor benefit, relevant code having direct access to the
cvar-controlled variables is probably a slight optimization as it
removed a pointer dereference, and the variables can be located for data
locality.
The static cvar descriptors are made private as an additional safety
layer, though there's nothing stopping external modification via
Cvar_FindVar (which is needed for adding listeners).
While not used yet (partly due to working out the design), cvars can
have a validation function.
Registering a cvar allows a primary listener (and its data) to be
specified: it will always be called first when the cvar is modified. The
combination of proper listeners and direct access to the controlled
variable greatly simplifies the more complex cvar interactions as much
less null checking is required, and there's no need for one cvar's
callback to call another's.
nq-x11 is known to work at least well enough for the demos. More testing
will come.
2022-04-23 03:22:45 +00:00
|
|
|
static cvar_t vid_nopageflip_cvar = {
|
|
|
|
.name = "vid_nopageflip",
|
|
|
|
.description =
|
|
|
|
"",
|
|
|
|
.default_value = "0",
|
|
|
|
.flags = CVAR_ARCHIVE,
|
2022-04-24 11:04:06 +00:00
|
|
|
.value = { .type = &cexpr_int, .value = &vid_nopageflip },
|
[cvar] Make cvars properly typed
This is an extremely extensive patch as it hits every cvar, and every
usage of the cvars. Cvars no longer store the value they control,
instead, they use a cexpr value object to reference the value and
specify the value's type (currently, a null type is used for strings).
Non-string cvars are passed through cexpr, allowing expressions in the
cvars' settings. Also, cvars have returned to an enhanced version of the
original (id quake) registration scheme.
As a minor benefit, relevant code having direct access to the
cvar-controlled variables is probably a slight optimization as it
removed a pointer dereference, and the variables can be located for data
locality.
The static cvar descriptors are made private as an additional safety
layer, though there's nothing stopping external modification via
Cvar_FindVar (which is needed for adding listeners).
While not used yet (partly due to working out the design), cvars can
have a validation function.
Registering a cvar allows a primary listener (and its data) to be
specified: it will always be called first when the cvar is modified. The
combination of proper listeners and direct access to the controlled
variable greatly simplifies the more complex cvar interactions as much
less null checking is required, and there's no need for one cvar's
callback to call another's.
nq-x11 is known to work at least well enough for the demos. More testing
will come.
2022-04-23 03:22:45 +00:00
|
|
|
};
|
2022-04-24 11:04:06 +00:00
|
|
|
int _vid_wait_override;
|
[cvar] Make cvars properly typed
This is an extremely extensive patch as it hits every cvar, and every
usage of the cvars. Cvars no longer store the value they control,
instead, they use a cexpr value object to reference the value and
specify the value's type (currently, a null type is used for strings).
Non-string cvars are passed through cexpr, allowing expressions in the
cvars' settings. Also, cvars have returned to an enhanced version of the
original (id quake) registration scheme.
As a minor benefit, relevant code having direct access to the
cvar-controlled variables is probably a slight optimization as it
removed a pointer dereference, and the variables can be located for data
locality.
The static cvar descriptors are made private as an additional safety
layer, though there's nothing stopping external modification via
Cvar_FindVar (which is needed for adding listeners).
While not used yet (partly due to working out the design), cvars can
have a validation function.
Registering a cvar allows a primary listener (and its data) to be
specified: it will always be called first when the cvar is modified. The
combination of proper listeners and direct access to the controlled
variable greatly simplifies the more complex cvar interactions as much
less null checking is required, and there's no need for one cvar's
callback to call another's.
nq-x11 is known to work at least well enough for the demos. More testing
will come.
2022-04-23 03:22:45 +00:00
|
|
|
static cvar_t _vid_wait_override_cvar = {
|
|
|
|
.name = "_vid_wait_override",
|
|
|
|
.description =
|
|
|
|
"",
|
|
|
|
.default_value = "0",
|
|
|
|
.flags = CVAR_ARCHIVE,
|
2022-04-24 11:04:06 +00:00
|
|
|
.value = { .type = &cexpr_int, .value = &_vid_wait_override },
|
[cvar] Make cvars properly typed
This is an extremely extensive patch as it hits every cvar, and every
usage of the cvars. Cvars no longer store the value they control,
instead, they use a cexpr value object to reference the value and
specify the value's type (currently, a null type is used for strings).
Non-string cvars are passed through cexpr, allowing expressions in the
cvars' settings. Also, cvars have returned to an enhanced version of the
original (id quake) registration scheme.
As a minor benefit, relevant code having direct access to the
cvar-controlled variables is probably a slight optimization as it
removed a pointer dereference, and the variables can be located for data
locality.
The static cvar descriptors are made private as an additional safety
layer, though there's nothing stopping external modification via
Cvar_FindVar (which is needed for adding listeners).
While not used yet (partly due to working out the design), cvars can
have a validation function.
Registering a cvar allows a primary listener (and its data) to be
specified: it will always be called first when the cvar is modified. The
combination of proper listeners and direct access to the controlled
variable greatly simplifies the more complex cvar interactions as much
less null checking is required, and there's no need for one cvar's
callback to call another's.
nq-x11 is known to work at least well enough for the demos. More testing
will come.
2022-04-23 03:22:45 +00:00
|
|
|
};
|
2022-04-24 11:04:06 +00:00
|
|
|
int vid_config_x;
|
[cvar] Make cvars properly typed
This is an extremely extensive patch as it hits every cvar, and every
usage of the cvars. Cvars no longer store the value they control,
instead, they use a cexpr value object to reference the value and
specify the value's type (currently, a null type is used for strings).
Non-string cvars are passed through cexpr, allowing expressions in the
cvars' settings. Also, cvars have returned to an enhanced version of the
original (id quake) registration scheme.
As a minor benefit, relevant code having direct access to the
cvar-controlled variables is probably a slight optimization as it
removed a pointer dereference, and the variables can be located for data
locality.
The static cvar descriptors are made private as an additional safety
layer, though there's nothing stopping external modification via
Cvar_FindVar (which is needed for adding listeners).
While not used yet (partly due to working out the design), cvars can
have a validation function.
Registering a cvar allows a primary listener (and its data) to be
specified: it will always be called first when the cvar is modified. The
combination of proper listeners and direct access to the controlled
variable greatly simplifies the more complex cvar interactions as much
less null checking is required, and there's no need for one cvar's
callback to call another's.
nq-x11 is known to work at least well enough for the demos. More testing
will come.
2022-04-23 03:22:45 +00:00
|
|
|
static cvar_t vid_config_x_cvar = {
|
|
|
|
.name = "vid_config_x",
|
|
|
|
.description =
|
|
|
|
"",
|
|
|
|
.default_value = "800",
|
|
|
|
.flags = CVAR_ARCHIVE,
|
2022-04-24 11:04:06 +00:00
|
|
|
.value = { .type = &cexpr_int, .value = &vid_config_x },
|
[cvar] Make cvars properly typed
This is an extremely extensive patch as it hits every cvar, and every
usage of the cvars. Cvars no longer store the value they control,
instead, they use a cexpr value object to reference the value and
specify the value's type (currently, a null type is used for strings).
Non-string cvars are passed through cexpr, allowing expressions in the
cvars' settings. Also, cvars have returned to an enhanced version of the
original (id quake) registration scheme.
As a minor benefit, relevant code having direct access to the
cvar-controlled variables is probably a slight optimization as it
removed a pointer dereference, and the variables can be located for data
locality.
The static cvar descriptors are made private as an additional safety
layer, though there's nothing stopping external modification via
Cvar_FindVar (which is needed for adding listeners).
While not used yet (partly due to working out the design), cvars can
have a validation function.
Registering a cvar allows a primary listener (and its data) to be
specified: it will always be called first when the cvar is modified. The
combination of proper listeners and direct access to the controlled
variable greatly simplifies the more complex cvar interactions as much
less null checking is required, and there's no need for one cvar's
callback to call another's.
nq-x11 is known to work at least well enough for the demos. More testing
will come.
2022-04-23 03:22:45 +00:00
|
|
|
};
|
2022-04-24 11:04:06 +00:00
|
|
|
int vid_config_y;
|
[cvar] Make cvars properly typed
This is an extremely extensive patch as it hits every cvar, and every
usage of the cvars. Cvars no longer store the value they control,
instead, they use a cexpr value object to reference the value and
specify the value's type (currently, a null type is used for strings).
Non-string cvars are passed through cexpr, allowing expressions in the
cvars' settings. Also, cvars have returned to an enhanced version of the
original (id quake) registration scheme.
As a minor benefit, relevant code having direct access to the
cvar-controlled variables is probably a slight optimization as it
removed a pointer dereference, and the variables can be located for data
locality.
The static cvar descriptors are made private as an additional safety
layer, though there's nothing stopping external modification via
Cvar_FindVar (which is needed for adding listeners).
While not used yet (partly due to working out the design), cvars can
have a validation function.
Registering a cvar allows a primary listener (and its data) to be
specified: it will always be called first when the cvar is modified. The
combination of proper listeners and direct access to the controlled
variable greatly simplifies the more complex cvar interactions as much
less null checking is required, and there's no need for one cvar's
callback to call another's.
nq-x11 is known to work at least well enough for the demos. More testing
will come.
2022-04-23 03:22:45 +00:00
|
|
|
static cvar_t vid_config_y_cvar = {
|
|
|
|
.name = "vid_config_y",
|
|
|
|
.description =
|
|
|
|
"",
|
|
|
|
.default_value = "600",
|
|
|
|
.flags = CVAR_ARCHIVE,
|
2022-04-24 11:04:06 +00:00
|
|
|
.value = { .type = &cexpr_int, .value = &vid_config_y },
|
[cvar] Make cvars properly typed
This is an extremely extensive patch as it hits every cvar, and every
usage of the cvars. Cvars no longer store the value they control,
instead, they use a cexpr value object to reference the value and
specify the value's type (currently, a null type is used for strings).
Non-string cvars are passed through cexpr, allowing expressions in the
cvars' settings. Also, cvars have returned to an enhanced version of the
original (id quake) registration scheme.
As a minor benefit, relevant code having direct access to the
cvar-controlled variables is probably a slight optimization as it
removed a pointer dereference, and the variables can be located for data
locality.
The static cvar descriptors are made private as an additional safety
layer, though there's nothing stopping external modification via
Cvar_FindVar (which is needed for adding listeners).
While not used yet (partly due to working out the design), cvars can
have a validation function.
Registering a cvar allows a primary listener (and its data) to be
specified: it will always be called first when the cvar is modified. The
combination of proper listeners and direct access to the controlled
variable greatly simplifies the more complex cvar interactions as much
less null checking is required, and there's no need for one cvar's
callback to call another's.
nq-x11 is known to work at least well enough for the demos. More testing
will come.
2022-04-23 03:22:45 +00:00
|
|
|
};
|
2022-04-24 11:04:06 +00:00
|
|
|
int vid_stretch_by_2;
|
[cvar] Make cvars properly typed
This is an extremely extensive patch as it hits every cvar, and every
usage of the cvars. Cvars no longer store the value they control,
instead, they use a cexpr value object to reference the value and
specify the value's type (currently, a null type is used for strings).
Non-string cvars are passed through cexpr, allowing expressions in the
cvars' settings. Also, cvars have returned to an enhanced version of the
original (id quake) registration scheme.
As a minor benefit, relevant code having direct access to the
cvar-controlled variables is probably a slight optimization as it
removed a pointer dereference, and the variables can be located for data
locality.
The static cvar descriptors are made private as an additional safety
layer, though there's nothing stopping external modification via
Cvar_FindVar (which is needed for adding listeners).
While not used yet (partly due to working out the design), cvars can
have a validation function.
Registering a cvar allows a primary listener (and its data) to be
specified: it will always be called first when the cvar is modified. The
combination of proper listeners and direct access to the controlled
variable greatly simplifies the more complex cvar interactions as much
less null checking is required, and there's no need for one cvar's
callback to call another's.
nq-x11 is known to work at least well enough for the demos. More testing
will come.
2022-04-23 03:22:45 +00:00
|
|
|
static cvar_t vid_stretch_by_2_cvar = {
|
|
|
|
.name = "vid_stretch_by_2",
|
|
|
|
.description =
|
|
|
|
"",
|
|
|
|
.default_value = "1",
|
|
|
|
.flags = CVAR_ARCHIVE,
|
2022-04-24 11:04:06 +00:00
|
|
|
.value = { .type = &cexpr_int, .value = &vid_stretch_by_2 },
|
[cvar] Make cvars properly typed
This is an extremely extensive patch as it hits every cvar, and every
usage of the cvars. Cvars no longer store the value they control,
instead, they use a cexpr value object to reference the value and
specify the value's type (currently, a null type is used for strings).
Non-string cvars are passed through cexpr, allowing expressions in the
cvars' settings. Also, cvars have returned to an enhanced version of the
original (id quake) registration scheme.
As a minor benefit, relevant code having direct access to the
cvar-controlled variables is probably a slight optimization as it
removed a pointer dereference, and the variables can be located for data
locality.
The static cvar descriptors are made private as an additional safety
layer, though there's nothing stopping external modification via
Cvar_FindVar (which is needed for adding listeners).
While not used yet (partly due to working out the design), cvars can
have a validation function.
Registering a cvar allows a primary listener (and its data) to be
specified: it will always be called first when the cvar is modified. The
combination of proper listeners and direct access to the controlled
variable greatly simplifies the more complex cvar interactions as much
less null checking is required, and there's no need for one cvar's
callback to call another's.
nq-x11 is known to work at least well enough for the demos. More testing
will come.
2022-04-23 03:22:45 +00:00
|
|
|
};
|
|
|
|
static int _windowed_mouse;
|
|
|
|
static cvar_t _windowed_mouse_cvar = {
|
|
|
|
.name = "_windowed_mouse",
|
|
|
|
.description =
|
|
|
|
"",
|
|
|
|
.default_value = "0",
|
|
|
|
.flags = CVAR_ARCHIVE,
|
|
|
|
.value = { .type = &cexpr_int, .value = &_windowed_mouse },
|
|
|
|
};
|
|
|
|
static int vid_fullscreen_mode;
|
|
|
|
static cvar_t vid_fullscreen_mode_cvar = {
|
|
|
|
.name = "vid_fullscreen_mode",
|
|
|
|
.description =
|
|
|
|
"",
|
|
|
|
.default_value = "3",
|
|
|
|
.flags = CVAR_ARCHIVE,
|
|
|
|
.value = { .type = &cexpr_int, .value = &vid_fullscreen_mode },
|
|
|
|
};
|
|
|
|
static int vid_windowed_mode;
|
|
|
|
static cvar_t vid_windowed_mode_cvar = {
|
|
|
|
.name = "vid_windowed_mode",
|
|
|
|
.description =
|
|
|
|
"",
|
|
|
|
.default_value = "0",
|
|
|
|
.flags = CVAR_ARCHIVE,
|
|
|
|
.value = { .type = &cexpr_int, .value = &vid_windowed_mode },
|
|
|
|
};
|
2022-04-24 11:04:06 +00:00
|
|
|
int block_switch;
|
[cvar] Make cvars properly typed
This is an extremely extensive patch as it hits every cvar, and every
usage of the cvars. Cvars no longer store the value they control,
instead, they use a cexpr value object to reference the value and
specify the value's type (currently, a null type is used for strings).
Non-string cvars are passed through cexpr, allowing expressions in the
cvars' settings. Also, cvars have returned to an enhanced version of the
original (id quake) registration scheme.
As a minor benefit, relevant code having direct access to the
cvar-controlled variables is probably a slight optimization as it
removed a pointer dereference, and the variables can be located for data
locality.
The static cvar descriptors are made private as an additional safety
layer, though there's nothing stopping external modification via
Cvar_FindVar (which is needed for adding listeners).
While not used yet (partly due to working out the design), cvars can
have a validation function.
Registering a cvar allows a primary listener (and its data) to be
specified: it will always be called first when the cvar is modified. The
combination of proper listeners and direct access to the controlled
variable greatly simplifies the more complex cvar interactions as much
less null checking is required, and there's no need for one cvar's
callback to call another's.
nq-x11 is known to work at least well enough for the demos. More testing
will come.
2022-04-23 03:22:45 +00:00
|
|
|
static cvar_t block_switch_cvar = {
|
|
|
|
.name = "block_switch",
|
|
|
|
.description =
|
|
|
|
"",
|
|
|
|
.default_value = "0",
|
|
|
|
.flags = CVAR_ARCHIVE,
|
2022-04-24 11:04:06 +00:00
|
|
|
.value = { .type = &cexpr_int, .value = &block_switch },
|
[cvar] Make cvars properly typed
This is an extremely extensive patch as it hits every cvar, and every
usage of the cvars. Cvars no longer store the value they control,
instead, they use a cexpr value object to reference the value and
specify the value's type (currently, a null type is used for strings).
Non-string cvars are passed through cexpr, allowing expressions in the
cvars' settings. Also, cvars have returned to an enhanced version of the
original (id quake) registration scheme.
As a minor benefit, relevant code having direct access to the
cvar-controlled variables is probably a slight optimization as it
removed a pointer dereference, and the variables can be located for data
locality.
The static cvar descriptors are made private as an additional safety
layer, though there's nothing stopping external modification via
Cvar_FindVar (which is needed for adding listeners).
While not used yet (partly due to working out the design), cvars can
have a validation function.
Registering a cvar allows a primary listener (and its data) to be
specified: it will always be called first when the cvar is modified. The
combination of proper listeners and direct access to the controlled
variable greatly simplifies the more complex cvar interactions as much
less null checking is required, and there's no need for one cvar's
callback to call another's.
nq-x11 is known to work at least well enough for the demos. More testing
will come.
2022-04-23 03:22:45 +00:00
|
|
|
};
|
|
|
|
static int vid_window_x;
|
|
|
|
static cvar_t vid_window_x_cvar = {
|
|
|
|
.name = "vid_window_x",
|
|
|
|
.description =
|
|
|
|
"",
|
|
|
|
.default_value = "0",
|
|
|
|
.flags = CVAR_ARCHIVE,
|
|
|
|
.value = { .type = &cexpr_int, .value = &vid_window_x },
|
|
|
|
};
|
|
|
|
static int vid_window_y;
|
|
|
|
static cvar_t vid_window_y_cvar = {
|
|
|
|
.name = "vid_window_y",
|
|
|
|
.description =
|
|
|
|
"",
|
|
|
|
.default_value = "0",
|
|
|
|
.flags = CVAR_ARCHIVE,
|
|
|
|
.value = { .type = &cexpr_int, .value = &vid_window_y },
|
|
|
|
};
|
2021-03-27 11:09:37 +00:00
|
|
|
|
|
|
|
//FIXME?int yeahimconsoled;
|
|
|
|
|
|
|
|
#define MAX_MODE_LIST 36
|
|
|
|
#define VID_ROW_SIZE 3
|
|
|
|
|
2021-03-31 01:36:30 +00:00
|
|
|
static DWORD WindowStyle, ExWindowStyle;
|
2021-03-27 11:09:37 +00:00
|
|
|
|
2021-03-31 04:32:17 +00:00
|
|
|
int win_center_x, win_center_y;
|
2023-11-24 13:59:48 +00:00
|
|
|
int win_pos_x, win_pos_y;
|
|
|
|
int win_len_x, win_len_y;
|
2021-03-31 04:32:17 +00:00
|
|
|
RECT win_rect;
|
2021-03-27 11:09:37 +00:00
|
|
|
|
|
|
|
DEVMODE win_gdevmode;
|
|
|
|
|
|
|
|
int vid_modenum = NO_MODE;
|
|
|
|
int vid_testingmode, vid_realmode;
|
|
|
|
double vid_testendtime;
|
|
|
|
int vid_default = MODE_WINDOWED;
|
|
|
|
|
|
|
|
modestate_t modestate = MS_UNINIT;
|
|
|
|
|
|
|
|
byte vid_curpal[256 * 3];
|
|
|
|
|
|
|
|
int mode;
|
|
|
|
|
|
|
|
int aPage; // Current active display page
|
|
|
|
int vPage; // Current visible display page
|
|
|
|
int waitVRT = true; // True to wait for retrace on flip
|
|
|
|
|
2023-11-24 03:28:06 +00:00
|
|
|
static LONG (*event_handlers[WM_USER])(HWND, UINT, WPARAM, LPARAM);
|
|
|
|
|
|
|
|
bool
|
|
|
|
Win_AddEvent (UINT event, LONG (*event_handler)(HWND, UINT, WPARAM, LPARAM))
|
|
|
|
{
|
|
|
|
if (event >= WM_USER) {
|
|
|
|
Sys_MaskPrintf (SYS_vid, "event: %d, WM_USER: %d\n", event, WM_USER);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (event_handlers[event]) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
event_handlers[event] = event_handler;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
Win_RemoveEvent (UINT event)
|
|
|
|
{
|
|
|
|
if (event >= WM_USER) {
|
|
|
|
Sys_MaskPrintf (SYS_vid, "event: %d, WM_USER: %d\n", event, WM_USER);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
event_handlers[event] = 0;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static LONG WINAPI
|
|
|
|
Win_EventHandler (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
|
|
{
|
|
|
|
if (uMsg < WM_USER && event_handlers[uMsg]) {
|
|
|
|
return event_handlers[uMsg] (hWnd, uMsg, wParam, lParam);
|
|
|
|
}
|
|
|
|
return DefWindowProc (hWnd, uMsg, wParam, lParam);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2023-11-24 13:59:48 +00:00
|
|
|
Win_UpdateWindowStatus ()
|
2021-03-27 11:09:37 +00:00
|
|
|
{
|
2023-11-24 13:59:48 +00:00
|
|
|
win_rect.left = win_pos_x;
|
|
|
|
win_rect.top = win_pos_y;
|
|
|
|
win_rect.right = win_pos_x + win_len_x;
|
|
|
|
win_rect.bottom = win_pos_y + win_len_y;
|
2021-03-31 04:32:17 +00:00
|
|
|
win_center_x = (win_rect.left + win_rect.right) / 2;
|
|
|
|
win_center_y = (win_rect.top + win_rect.bottom) / 2;
|
2023-11-24 13:59:48 +00:00
|
|
|
VID_SetWindow (win_pos_x, win_pos_y, win_len_x, win_len_y);
|
2021-03-27 11:09:37 +00:00
|
|
|
IN_UpdateClipCursor ();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
VID_InitModes (HINSTANCE hInstance)
|
|
|
|
{
|
2023-11-25 13:03:27 +00:00
|
|
|
WNDCLASS wc = {
|
|
|
|
.style = CS_OWNDC,
|
|
|
|
.lpfnWndProc = (WNDPROC) Win_EventHandler,
|
|
|
|
.hInstance = hInstance,
|
|
|
|
.lpszClassName = WINDOW_CLASS,
|
|
|
|
};
|
2021-03-27 11:09:37 +00:00
|
|
|
|
2023-11-25 13:03:27 +00:00
|
|
|
win_arrow = LoadCursor (NULL, IDC_ARROW);
|
|
|
|
|
2021-03-27 11:09:37 +00:00
|
|
|
//FIXME hIcon = LoadIcon (hInstance, MAKEINTRESOURCE (IDI_ICON2));
|
|
|
|
|
|
|
|
/* Register the frame class */
|
|
|
|
|
|
|
|
if (!RegisterClass (&wc))
|
|
|
|
Sys_Error ("Couldn't register window class");
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Win_OpenDisplay (void)
|
|
|
|
{
|
2023-11-24 03:28:06 +00:00
|
|
|
global_hInstance = GetModuleHandle (0);
|
2021-03-27 11:09:37 +00:00
|
|
|
VID_InitModes (global_hInstance);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Win_CloseDisplay (void)
|
|
|
|
{
|
|
|
|
if (viddef.initialized) {
|
|
|
|
PostMessage (HWND_BROADCAST, WM_PALETTECHANGED, (WPARAM) win_mainwindow,
|
|
|
|
(LPARAM) 0);
|
|
|
|
PostMessage (HWND_BROADCAST, WM_SYSCOLORCHANGE, (WPARAM) 0, (LPARAM) 0);
|
|
|
|
|
|
|
|
vid_testingmode = 0;
|
|
|
|
viddef.initialized = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-26 05:18:54 +00:00
|
|
|
static RECT window_rect;
|
2021-03-27 11:09:37 +00:00
|
|
|
void
|
2023-11-26 05:18:54 +00:00
|
|
|
Win_UpdateFullscreen (int fullscreen)
|
|
|
|
{
|
|
|
|
if (fullscreen) {
|
|
|
|
GetWindowRect (win_mainwindow, &window_rect);
|
|
|
|
SetWindowLongW (win_mainwindow, GWL_STYLE, 0);
|
|
|
|
HMONITOR monitor = MonitorFromWindow (win_mainwindow, MONITOR_DEFAULTTONEAREST);
|
|
|
|
MONITORINFO info = {
|
|
|
|
.cbSize = sizeof (info),
|
|
|
|
};
|
|
|
|
GetMonitorInfoW (monitor, &info);
|
|
|
|
SetWindowPos (win_mainwindow, HWND_TOP,
|
|
|
|
info.rcMonitor.left,
|
|
|
|
info.rcMonitor.top,
|
|
|
|
info.rcMonitor.right - info.rcMonitor.left,
|
|
|
|
info.rcMonitor.bottom - info.rcMonitor.top,
|
|
|
|
SWP_FRAMECHANGED | SWP_NOACTIVATE);
|
|
|
|
ShowWindow (win_mainwindow, SW_MAXIMIZE);
|
2021-03-30 11:09:13 +00:00
|
|
|
} else {
|
2023-11-26 05:18:54 +00:00
|
|
|
SetWindowLongW (win_mainwindow, GWL_STYLE, WindowStyle);
|
|
|
|
SetWindowPos (win_mainwindow, HWND_NOTOPMOST,
|
|
|
|
window_rect.left,
|
|
|
|
window_rect.top,
|
|
|
|
window_rect.right - window_rect.left,
|
|
|
|
window_rect.bottom - window_rect.top,
|
|
|
|
SWP_FRAMECHANGED | SWP_NOACTIVATE);
|
|
|
|
ShowWindow (win_mainwindow, SW_NORMAL);
|
2021-03-30 11:09:13 +00:00
|
|
|
}
|
2021-03-27 11:09:37 +00:00
|
|
|
}
|
|
|
|
|
2023-11-24 03:28:06 +00:00
|
|
|
static long
|
|
|
|
notify_create (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static long
|
|
|
|
notify_destroy (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
|
|
{
|
|
|
|
if (win_mainwindow) {
|
|
|
|
DestroyWindow (win_mainwindow);
|
2023-11-25 01:51:50 +00:00
|
|
|
win_mainwindow = 0;
|
2023-11-24 03:28:06 +00:00
|
|
|
}
|
|
|
|
PostQuitMessage (0);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static long
|
|
|
|
notify_move (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
|
|
{
|
2023-11-25 12:03:51 +00:00
|
|
|
win_pos_x = (short) LOWORD (lParam);
|
|
|
|
win_pos_y = (short) HIWORD (lParam);
|
2023-11-24 13:59:48 +00:00
|
|
|
Sys_MaskPrintf (SYS_vid, "notify_move: %d %d\n", win_pos_x, win_pos_y);
|
|
|
|
Win_UpdateWindowStatus ();
|
2023-11-24 03:28:06 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static long
|
|
|
|
notify_size (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
|
|
{
|
2023-11-25 12:03:51 +00:00
|
|
|
win_len_x = (short) LOWORD (lParam);
|
|
|
|
win_len_y = (short) HIWORD (lParam);
|
2023-11-24 13:59:48 +00:00
|
|
|
Sys_MaskPrintf (SYS_vid, "notify_size: %d %d\n", win_pos_x, win_pos_y);
|
|
|
|
Win_UpdateWindowStatus ();
|
2023-11-24 03:28:06 +00:00
|
|
|
return 1;
|
|
|
|
}
|
2021-03-27 11:09:37 +00:00
|
|
|
|
2021-03-31 06:50:10 +00:00
|
|
|
void
|
|
|
|
Win_CreateWindow (int width, int height)
|
|
|
|
{
|
2023-11-24 03:28:06 +00:00
|
|
|
IN_Win_Preinit ();
|
|
|
|
|
|
|
|
Win_AddEvent (WM_CREATE, notify_create);
|
|
|
|
Win_AddEvent (WM_DESTROY, notify_destroy);
|
|
|
|
Win_AddEvent (WM_MOVE, notify_move);
|
|
|
|
Win_AddEvent (WM_SIZE, notify_size);
|
|
|
|
|
|
|
|
|
2021-03-31 06:50:10 +00:00
|
|
|
RECT rect = {
|
2023-11-24 13:59:48 +00:00
|
|
|
.top = win_pos_x = 0,
|
|
|
|
.left = win_pos_y = 0,
|
|
|
|
.right = win_len_x = width,
|
|
|
|
.bottom = win_len_y = height,
|
2021-03-31 06:50:10 +00:00
|
|
|
};
|
2023-11-25 12:03:51 +00:00
|
|
|
WindowStyle = WS_OVERLAPPEDWINDOW | WS_CAPTION | WS_SYSMENU | WS_SIZEBOX |
|
|
|
|
WS_MINIMIZEBOX | WS_MAXIMIZEBOX;
|
2021-03-31 06:50:10 +00:00
|
|
|
AdjustWindowRectEx (&rect, WindowStyle, FALSE, 0);
|
|
|
|
// sound initialization has to go here, preceded by a windowed mode set,
|
|
|
|
// so there's a window for DirectSound to work with but we're not yet
|
|
|
|
// fullscreen so the "hardware already in use" dialog is visible if it
|
|
|
|
// gets displayed
|
|
|
|
// keep the window minimized until we're ready for the first real mode set
|
2023-11-24 03:28:06 +00:00
|
|
|
win_mainwindow = CreateWindowExA (ExWindowStyle,
|
|
|
|
WINDOW_CLASS,
|
|
|
|
PACKAGE_STRING,
|
2023-11-25 12:03:51 +00:00
|
|
|
WindowStyle,
|
2021-03-31 06:50:10 +00:00
|
|
|
0, 0,
|
|
|
|
rect.right - rect.left,
|
|
|
|
rect.bottom - rect.top,
|
|
|
|
NULL, NULL, global_hInstance, NULL);
|
|
|
|
|
|
|
|
if (!win_mainwindow)
|
2023-11-26 05:18:54 +00:00
|
|
|
Sys_Error ("Couldn't create window");
|
2021-03-31 06:50:10 +00:00
|
|
|
|
|
|
|
// done
|
2023-11-24 13:59:48 +00:00
|
|
|
Win_UpdateWindowStatus ();
|
2021-03-31 06:50:10 +00:00
|
|
|
|
|
|
|
HDC hdc = GetDC (NULL);
|
|
|
|
if (GetDeviceCaps (hdc, RASTERCAPS) & RC_PALETTE) {
|
|
|
|
win_palettized = true;
|
|
|
|
} else {
|
|
|
|
win_palettized = false;
|
|
|
|
}
|
|
|
|
ReleaseDC (NULL, hdc);
|
|
|
|
|
|
|
|
MSG msg;
|
|
|
|
while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) {
|
|
|
|
TranslateMessage (&msg);
|
|
|
|
DispatchMessage (&msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
Sleep (100);
|
|
|
|
|
2023-11-26 05:18:54 +00:00
|
|
|
SetWindowPos (win_mainwindow, HWND_TOP, 0, 0, 0, 0,
|
|
|
|
SWP_DRAWFRAME | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW |
|
|
|
|
SWP_NOCOPYBITS);
|
|
|
|
SetForegroundWindow (win_mainwindow);
|
2021-03-31 06:50:10 +00:00
|
|
|
|
|
|
|
viddef.recalc_refdef = 1;
|
|
|
|
}
|
|
|
|
|
2021-03-27 11:09:37 +00:00
|
|
|
void
|
|
|
|
Win_SetCaption (const char *text)
|
|
|
|
{
|
|
|
|
if (win_mainwindow) {
|
2023-11-24 03:28:06 +00:00
|
|
|
SetWindowTextA (win_mainwindow, text);
|
2021-03-27 11:09:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//static WORD systemgammaramps[3][256];
|
|
|
|
static WORD currentgammaramps[3][256];
|
|
|
|
|
2023-06-13 09:06:11 +00:00
|
|
|
bool
|
2021-03-27 11:09:37 +00:00
|
|
|
Win_SetGamma (double gamma)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
HDC hdc = GetDC (NULL);
|
|
|
|
|
|
|
|
for (i = 0; i < 256; i++) {
|
|
|
|
currentgammaramps[2][i] = currentgammaramps[1][i] =
|
|
|
|
currentgammaramps[0][i] = viddef.gammatable[i] * 256;
|
|
|
|
}
|
|
|
|
|
|
|
|
i = SetDeviceGammaRamp (hdc, ¤tgammaramps[0][0]);
|
|
|
|
ReleaseDC (NULL, hdc);
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Win_Init_Cvars (void)
|
|
|
|
{
|
[cvar] Make cvars properly typed
This is an extremely extensive patch as it hits every cvar, and every
usage of the cvars. Cvars no longer store the value they control,
instead, they use a cexpr value object to reference the value and
specify the value's type (currently, a null type is used for strings).
Non-string cvars are passed through cexpr, allowing expressions in the
cvars' settings. Also, cvars have returned to an enhanced version of the
original (id quake) registration scheme.
As a minor benefit, relevant code having direct access to the
cvar-controlled variables is probably a slight optimization as it
removed a pointer dereference, and the variables can be located for data
locality.
The static cvar descriptors are made private as an additional safety
layer, though there's nothing stopping external modification via
Cvar_FindVar (which is needed for adding listeners).
While not used yet (partly due to working out the design), cvars can
have a validation function.
Registering a cvar allows a primary listener (and its data) to be
specified: it will always be called first when the cvar is modified. The
combination of proper listeners and direct access to the controlled
variable greatly simplifies the more complex cvar interactions as much
less null checking is required, and there's no need for one cvar's
callback to call another's.
nq-x11 is known to work at least well enough for the demos. More testing
will come.
2022-04-23 03:22:45 +00:00
|
|
|
Cvar_Register (&vid_ddraw_cvar, 0, 0);
|
|
|
|
Cvar_Register (&vid_mode_cvar, 0, 0);
|
|
|
|
Cvar_Register (&vid_wait_cvar, 0, 0);
|
|
|
|
Cvar_Register (&vid_nopageflip_cvar, 0, 0);
|
|
|
|
Cvar_Register (&_vid_wait_override_cvar, 0, 0);
|
|
|
|
Cvar_Register (&_vid_default_mode_cvar, 0, 0);
|
|
|
|
Cvar_Register (&_vid_default_mode_win_cvar, 0, 0);
|
|
|
|
Cvar_Register (&vid_config_x_cvar, 0, 0);
|
|
|
|
Cvar_Register (&vid_config_y_cvar, 0, 0);
|
|
|
|
Cvar_Register (&vid_stretch_by_2_cvar, 0, 0);
|
|
|
|
Cvar_Register (&_windowed_mouse_cvar, 0, 0);
|
|
|
|
Cvar_Register (&vid_fullscreen_mode_cvar, 0, 0);
|
|
|
|
Cvar_Register (&vid_windowed_mode_cvar, 0, 0);
|
|
|
|
Cvar_Register (&block_switch_cvar, 0, 0);
|
|
|
|
Cvar_Register (&vid_window_x_cvar, 0, 0);
|
|
|
|
Cvar_Register (&vid_window_y_cvar, 0, 0);
|
2021-03-27 11:09:37 +00:00
|
|
|
}
|
2021-09-28 03:48:47 +00:00
|
|
|
|
|
|
|
extern int win_force_link;
|
|
|
|
static __attribute__((used)) int *context_win_force_link = &win_force_link;
|