diff --git a/Makefile.am b/Makefile.am index c869a6f3a..176c52434 100644 --- a/Makefile.am +++ b/Makefile.am @@ -26,7 +26,7 @@ NOCONV_DIST= \ BUILT_SOURCES = $(top_srcdir)/.version #AM_CFLAGS= @PREFER_NON_PIC@ -AM_CPPFLAGS= -I$(top_srcdir)/include $(PTHREAD_CFLAGS) +AM_CPPFLAGS= -I$(top_srcdir)/include $(PTHREAD_CFLAGS) $(FNM_FLAGS) $(NCURSES_CFLAGS) common_ldflags= -export-dynamic @PTHREAD_LDFLAGS@ @@ -69,6 +69,8 @@ XMMS_LIBS= @XMMS_LIBS@ PAK=$(top_builddir)/pak$(EXEEXT) QFCC_DEP=qfcc$(EXEEXT) QFCC=$(top_builddir)/$(QFCC_DEP) +QWAQ_CURSES=$(top_builddir)/ruamoko/qwaq/qwaq-curses$(EXEEXT) + GZ=@progs_gz@ V_QFCC = $(V_QFCC_@AM_V@) diff --git a/config.d/build_control.m4 b/config.d/build_control.m4 index 74b28afcd..fdd4ce698 100644 --- a/config.d/build_control.m4 +++ b/config.d/build_control.m4 @@ -224,52 +224,52 @@ if test "x$ENABLE_servers_qw" = xyes; then fi if test "x$ENABLE_tools_bsp2img" = xyes; then - BSP2IMG_TARGETS=bsp2img + BSP2IMG_TARGETS="bsp2img\$(EXEEXT)" QF_NEED(tools,[bsp2img]) QF_NEED(libs,[image util]) fi if test "x$ENABLE_tools_carne" = xyes; then - CARNE_TARGETS=carne + CARNE_TARGETS="carne\$(EXEEXT)" QF_NEED(tools,[carne]) QF_NEED(libs,[gib ruamoko gamecode util]) fi if test "x$ENABLE_tools_pak" = xyes; then - PAK_TARGETS=pak + PAK_TARGETS="pak\$(EXEEXT)" QF_NEED(tools,[pak]) QF_NEED(libs,[util]) fi if test "x$ENABLE_tools_qfbsp" = xyes; then - QFBSP_TARGETS=qfbsp + QFBSP_TARGETS="qfbsp\$(EXEEXT)" QF_NEED(tools,[qfbsp]) QF_NEED(libs,[models image util]) fi if test "x$ENABLE_tools_qfcc" = xyes; then - QFCC_TARGETS=qfcc qfprogs + QFCC_TARGETS="qfcc qfprogs\$(EXEEXT)" QF_NEED(tools,[qfcc]) QF_NEED(libs,[gamecode util]) fi if test "x$ENABLE_tools_qflight" = xyes; then - QFLIGHT_TARGETS=qflight + QFLIGHT_TARGETS="qflight\$(EXEEXT)" QF_NEED(tools,[qflight]) QF_NEED(libs,[util]) fi if test "x$ENABLE_tools_qflmp" = xyes; then - QFLMP_TARGETS=qflmp + QFLMP_TARGETS="qflmp\$(EXEEXT)" QF_NEED(tools,[qflmp]) QF_NEED(libs,[util]) fi if test "x$ENABLE_tools_qfmodelgen" = xyes; then - QFMODELGEN_TARGETS=qfmodelgen + QFMODELGEN_TARGETS="qfmodelgen\$(EXEEXT)" QF_NEED(tools,[qfmodelgen]) QF_NEED(libs,[util]) fi if test "x$ENABLE_tools_qfspritegen" = xyes; then - QFSPRITEGEN_TARGETS=qfspritegen + QFSPRITEGEN_TARGETS="qfspritegen\$(EXEEXT)" QF_NEED(tools,[qfspritegen]) QF_NEED(libs,[util]) fi if test "x$ENABLE_tools_qfvis" = xyes; then - QFVIS_TARGETS=qfvis + QFVIS_TARGETS="qfvis\$(EXEEXT)" QF_NEED(tools,[qfvis]) QF_NEED(libs,[util]) fi @@ -282,12 +282,12 @@ if test "x$ENABLE_tools_qwaq" = xyes; then QF_NEED(libs,[ruamoko gamecode util]) fi if test "x$ENABLE_tools_wad" = xyes; then - WAD_TARGETS=wad + WAD_TARGETS="wad\$(EXEEXT)" QF_NEED(tools,[wad]) QF_NEED(libs,[image util]) fi if test "x$ENABLE_tools_wav" = xyes; then - WAV_TARGETS=qfwavinfo + WAV_TARGETS="qfwavinfo\$(EXEEXT)" QF_NEED(tools,[wav]) QF_NEED(libs,[util]) fi diff --git a/config.d/compiling.m4 b/config.d/compiling.m4 index 7a4908efa..f5042ae0f 100644 --- a/config.d/compiling.m4 +++ b/config.d/compiling.m4 @@ -27,8 +27,7 @@ AC_TRY_LINK( AC_MSG_RESULT(yes) ) AH_VERBATIM([HAVE_C99INLINE], -[/* Define this if the GCC __attribute__ keyword is available */ -#undef HAVE_C99INLINE +[#undef HAVE_C99INLINE #ifdef HAVE_C99INLINE # define GNU89INLINE #else diff --git a/config.d/curses.m4 b/config.d/curses.m4 index 02d9ce7f4..6a5757cc1 100644 --- a/config.d/curses.m4 +++ b/config.d/curses.m4 @@ -2,44 +2,52 @@ AC_ARG_ENABLE(curses, [ --disable-curses disable curses support] ) if test "x$enable_curses" != "xno"; then - AC_CHECK_HEADER([curses.h], - [AC_DEFINE([HAVE_CURSES_H], [1], - [Define to 1 if you have .])]) + if test "x$PKG_CONFIG" != "x"; then + PKG_CHECK_MODULES([NCURSES], [ncurses], HAVE_NCURSES=yes, HAVE_NCURSES=no) + else + AC_CHECK_HEADER([curses.h], [], + [AC_CHECK_HEADER([ncurses/curses.h], + [NCURSES_CFLAGS=-I${prefix}/include/ncurses])]) AC_CHECK_LIB(ncurses, initscr, - CURSES_LIBS=-lncurses, + NCURSES_LIBS=-lncurses, AC_CHECK_LIB(pdcurses, initscr, - CURSES_LIBS=-lpdcurses, + NCURSES_LIBS=-lpdcurses, AC_CHECK_LIB(curses, initscr, - CURSES_LIBS=-lcurses, - CURSES_LIBS= + NCURSES_LIBS=-lcurses, + NCURSES_LIBS= ) ) ) - if test "x$CURSES_LIBS" != "x"; then + if test "x$NCURSES_LIBS" != "x"; then AC_DEFINE(HAVE_CURSES, 1, [Define if you have the ncurses library]) HAVE_CURSES=yes else HAVE_CURSES=no fi + fi else HAVE_CURSES=no - CURSES_LIBS= + NCURSES_LIBS= fi -AC_SUBST(CURSES_LIBS) +AC_SUBST(NCURSES_LIBS) -if test "x$HAVE_CURSES" == "xyes"; then - AC_CHECK_HEADER(panel.h, - [AC_CHECK_LIB(panel, new_panel, - [AC_DEFINE(HAVE_PANEL, 1, - [Define if you have the ncurses panel library]) - PANEL_LIBS=-lpanel - HAVE_PANEL=yes], +if test "x$HAVE_NCURSES" == "xyes"; then + if test "x$PKG_CONFIG" != "x"; then + PKG_CHECK_MODULES([PANEL], [panel], HAVE_PANEL=yes, HAVE_PANEL=no) + else + AC_CHECK_HEADER(panel.h, + [AC_CHECK_LIB(panel, new_panel, + [AC_DEFINE(HAVE_PANEL, 1, + [Define if you have the ncurses panel library]) + PANEL_LIBS=-lpanel + HAVE_PANEL=yes], + [HAVE_PANEL=no], + $NCURSES_LIBS + )], [HAVE_PANEL=no], - $CURSES_LIBS - )], - HAVE_PANEL=no, - [] - ) + [$NCURSES_CFLAGS] + ) + fi else PANEL_LIBS= fi diff --git a/config.d/header_files.m4 b/config.d/header_files.m4 index afb4cd37f..2e4e9a7ed 100644 --- a/config.d/header_files.m4 +++ b/config.d/header_files.m4 @@ -50,6 +50,15 @@ AC_TRY_COMPILE( AC_MSG_RESULT(no) ) +AC_MSG_CHECKING(for strndup in string.h) +AC_TRY_COMPILE( + [#include "string.h"], + [int (*foo)() = strndup;], + AC_DEFINE(HAVE_STRNDUP_PROTO, 1, [Define this if strndup is prototyped in string.h]) + AC_MSG_RESULT(yes), + AC_MSG_RESULT(no) +) + AC_MSG_CHECKING(for strcasestr in string.h) AC_TRY_COMPILE( [#include "string.h"], diff --git a/config.d/library_functions.m4 b/config.d/library_functions.m4 index ba76c574e..f4bebf3c0 100644 --- a/config.d/library_functions.m4 +++ b/config.d/library_functions.m4 @@ -10,9 +10,10 @@ AC_FUNC_VPRINTF AC_CHECK_FUNCS( access _access connect dlopen execvp fcntl ftime _ftime getaddrinfo \ gethostbyname gethostname getnameinfo getpagesize gettimeofday getuid \ - getwd ioctl mkdir _mkdir mprotect putenv select snprintf _snprintf \ - socket stat strcasestr strerror strnlen strsep strstr vsnprintf \ - _vsnprintf wait + getwd ioctl mkdir _mkdir mprotect putenv qsort_r select sigaction \ + snprintf _snprintf socket stat strcasestr strerror strerror_r strndup \ + strnlen \ + strsep strstr vsnprintf _vsnprintf wait ) AC_FUNC_VA_COPY diff --git a/config.d/vulkan.m4 b/config.d/vulkan.m4 index 0c780e98a..85ed9d3f0 100644 --- a/config.d/vulkan.m4 +++ b/config.d/vulkan.m4 @@ -19,3 +19,4 @@ AC_SUBST(VULKAN_LIBS) AC_SUBST(GLSLANGVALIDATOR, [$glslangvalidator]) AM_CONDITIONAL(X11_VULKAN, test "x$HAVE_VULKAN" = "xyes") +AM_CONDITIONAL(WIN_VULKAN, test "x$HAVE_VULKAN" = "xyes") diff --git a/configure.ac b/configure.ac index db59908b8..c19200755 100644 --- a/configure.ac +++ b/configure.ac @@ -74,9 +74,10 @@ dnl Checks for system type dnl ================================================================== dnl Checks for which system driver to use +echo ${host} AC_MSG_CHECKING(for system driver) case "${host}" in - i?86-*-mingw32*|x86_64-w64-mingw32) + i?86-*-mingw32*|x86_64-w64-mingw32*) SYSTYPE=WIN32 AC_MSG_RESULT([Win32 driver]) WIN32_LIBS=' $(NET_LIBS)' diff --git a/include/QF/Vulkan/debug.h b/include/QF/Vulkan/debug.h index 3250d5aca..c5fa70a7b 100644 --- a/include/QF/Vulkan/debug.h +++ b/include/QF/Vulkan/debug.h @@ -86,7 +86,7 @@ if (dfunc->vkSetDebugUtilsObjectNameEXT) { \ VkDebugUtilsObjectNameInfoEXT nameInfo = { \ VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT, 0, \ - type, (uint64_t) handle, name \ + type, (VkObjectType) handle, name \ }; \ dfunc->vkSetDebugUtilsObjectNameEXT (device->dev, &nameInfo); \ } \ diff --git a/include/context_win.h b/include/context_win.h new file mode 100644 index 000000000..879ea41c1 --- /dev/null +++ b/include/context_win.h @@ -0,0 +1,76 @@ +/* + context_win.h + + (description) + + Copyright (C) 1996-1997 Id Software, Inc. + Copyright (C) 1999,2000 contributors of the QuakeForge project + Please see the file "AUTHORS" for a list of contributors + + 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 + +*/ + +#ifndef __context_win_h +#define __context_win_h + +#include "QF/qtypes.h" +#include "winquake.h" + +extern HWND win_mainwindow; +extern HDC win_maindc; +extern HDC win_dib_section; +extern int win_using_ddraw; +extern int win_palettized; +extern int win_canalttab; +extern DEVMODE win_gdevmode; +extern LPDIRECTDRAWSURFACE win_dd_frontbuffer; +extern LPDIRECTDRAWSURFACE win_dd_backbuffer; +extern RECT win_src_rect; +extern RECT win_dst_rect; +extern RECT win_window_rect; +extern HDC win_gdi; +extern struct sw_ctx_s *win_sw_context; + +void Win_UnloadAllDrivers (void); +void Win_CreateDriver (void); +void Win_OpenDisplay (void); +void Win_CloseDisplay (void); +void Win_SetVidMode (int width, int height, const byte *palette); +void Win_Init_Cvars (void); +void Win_UpdateWindowStatus (int x, int y); +void Win_SetCaption (const char *text); +qboolean Win_SetGamma (double gamma); + +struct gl_ctx_s *Win_GL_Context (void); +void Win_GL_Init_Cvars (void); + +struct sw_ctx_s *Win_SW_Context (void); +void Win_SW_Init_Cvars (void); + +struct vulkan_ctx_s *Win_Vulkan_Context (void); +void Win_Vulkan_Init_Cvars (void); + +void IN_UpdateClipCursor (void); +void IN_ShowMouse (void); +void IN_HideMouse (void); +void IN_ActivateMouse (void); +void IN_DeactivateMouse (void); + +#endif // __context_win_h diff --git a/include/net_wins.h b/include/net_wins.h index c4954f9ac..56c7fdddb 100644 --- a/include/net_wins.h +++ b/include/net_wins.h @@ -54,7 +54,7 @@ const char *WINS_AddrToString (netadr_t *addr); int WINS_GetSocketAddr (int socket, netadr_t *addr); int WINS_GetNameFromAddr (netadr_t *addr, char *name); int WINS_GetAddrFromName (const char *name, netadr_t *addr); -int WINS_AddrCompare (netadr_t *addr1, netadr_t *addr2); +int WINS_AddrCompare (netadr_t *addr1, netadr_t *addr2) __attribute__((pure)); int WINS_GetSocketPort (netadr_t *addr); int WINS_SetSocketPort (netadr_t *addr, int port); diff --git a/include/vid_gl.h b/include/vid_gl.h index 2561af575..7ad9378b1 100644 --- a/include/vid_gl.h +++ b/include/vid_gl.h @@ -1,11 +1,11 @@ #ifndef __vid_gl_h #define __vid_gl_h -// GLXContext is a pointer to opaque data -typedef struct __GLXcontextRec *GLXContext; +// GL_context is a pointer to opaque data +typedef struct GL_context *GL_context; typedef struct gl_ctx_s { - GLXContext context; + GL_context context; void (*load_gl) (void); void (*choose_visual) (struct gl_ctx_s *ctx); void (*create_context) (struct gl_ctx_s *ctx); diff --git a/include/vid_sw.h b/include/vid_sw.h index 2a5ab20a5..e57d3ee0d 100644 --- a/include/vid_sw.h +++ b/include/vid_sw.h @@ -1,11 +1,8 @@ #ifndef __vid_sw_h #define __vid_sw_h -// GLXContext is a pointer to opaque data -typedef struct __GLXcontextRec *GLXContext; struct vrect_s; typedef struct sw_ctx_s { - GLXContext context; void (*choose_visual) (struct sw_ctx_s *ctx); void (*create_context) (struct sw_ctx_s *ctx); void (*set_palette) (const byte *palette); diff --git a/include/win32/fnmatch.h b/include/win32/fnmatch.h index 7dd238d67..af8cd3670 100644 --- a/include/win32/fnmatch.h +++ b/include/win32/fnmatch.h @@ -61,7 +61,7 @@ extern "C" { /* Match STRING against the filename pattern PATTERN, returning zero if it matches, FNM_NOMATCH if not. */ extern int fnmatch __P ((const char *__pattern, const char *__string, - int __flags)); + int __flags)) __attribute__((pure)); #ifdef __cplusplus } diff --git a/include/win32/stdint.h b/include/win32/stdint.h deleted file mode 100644 index 495cadcba..000000000 --- a/include/win32/stdint.h +++ /dev/null @@ -1,2 +0,0 @@ -/* stub for compilers not supporting stdint.h */ -#include "pstdint.h" diff --git a/include/winquake.h b/include/winquake.h index 82d73f083..8786d6633 100644 --- a/include/winquake.h +++ b/include/winquake.h @@ -30,6 +30,8 @@ #ifdef _WIN32 +#include + #ifndef __GNUC__ # pragma warning( disable : 4229 ) /* mgraph gets this */ #endif @@ -76,20 +78,14 @@ extern LPDIRECTDRAWSURFACE lpBackBuffer; extern LPDIRECTDRAWPALETTE lpDDPal; #endif -void VID_LockBuffer (void); -void VID_UnlockBuffer (void); -void VID_UpdateWindowStatus (int window_x, int window_y); - typedef enum {MS_WINDOWED, MS_FULLSCREEN, MS_FULLDIB, MS_UNINIT} modestate_t; extern modestate_t modestate; -extern HWND mainwindow; extern qboolean ActiveApp, Minimized; extern qboolean WinNT; -void VID_ForceLockState (int lk); extern qboolean winsock_lib_initialized; extern int window_center_x, window_center_y; diff --git a/libs/audio/cd_win.c b/libs/audio/cd_win.c index 93f29e624..5c297adc0 100644 --- a/libs/audio/cd_win.c +++ b/libs/audio/cd_win.c @@ -28,8 +28,6 @@ # include "config.h" #endif -#include "winquake.h" - #include "QF/cdaudio.h" #include "QF/cmd.h" #include "QF/cvar.h" @@ -41,6 +39,7 @@ #include "QF/plugin/cd.h" #include "compat.h" +#include "context_win.h" static plugin_t plugin_info; static plugin_data_t plugin_info_data; @@ -181,7 +180,7 @@ I_CDAudio_Pause (void) if (!playing) return; - mciGenericParms.dwCallback = (DWORD_PTR) mainwindow; + mciGenericParms.dwCallback = (DWORD_PTR) win_mainwindow; dwReturn = mciSendCommand (wDeviceID, MCI_PAUSE, 0, (DWORD_PTR) (LPVOID) & mciGenericParms); @@ -254,7 +253,7 @@ I_CDAudio_Play (int track, qboolean looping) mciPlayParms.dwFrom = MCI_MAKE_TMSF (track, 0, 0, 0); mciPlayParms.dwTo = (mciStatusParms.dwReturn << 8) | track; - mciPlayParms.dwCallback = (DWORD_PTR) mainwindow; + mciPlayParms.dwCallback = (DWORD_PTR) win_mainwindow; dwReturn = mciSendCommand (wDeviceID, MCI_PLAY, MCI_NOTIFY | MCI_FROM | MCI_TO, (DWORD_PTR) (LPVOID) & mciPlayParms); @@ -286,7 +285,7 @@ I_CDAudio_Resume (void) mciPlayParms.dwFrom = MCI_MAKE_TMSF (playTrack, 0, 0, 0); mciPlayParms.dwTo = MCI_MAKE_TMSF (playTrack + 1, 0, 0, 0); - mciPlayParms.dwCallback = (DWORD_PTR) mainwindow; + mciPlayParms.dwCallback = (DWORD_PTR) win_mainwindow; dwReturn = mciSendCommand (wDeviceID, MCI_PLAY, MCI_TO | MCI_NOTIFY, (DWORD_PTR) (LPVOID) & mciPlayParms); diff --git a/libs/audio/targets/snd_dx.c b/libs/audio/targets/snd_dx.c index 3852a17a5..27618487e 100644 --- a/libs/audio/targets/snd_dx.c +++ b/libs/audio/targets/snd_dx.c @@ -30,12 +30,12 @@ #define CINTERFACE -#include "winquake.h" #include "QF/cvar.h" #include "QF/qargs.h" #include "QF/sys.h" #include "snd_internal.h" +#include "context_win.h" #define iDirectSoundCreate(a,b,c) pDirectSoundCreate(a,b,c) @@ -131,7 +131,7 @@ FreeSound (void) } if (pDS) { - IDirectSound_SetCooperativeLevel (pDS, mainwindow, DSSCL_NORMAL); + IDirectSound_SetCooperativeLevel (pDS, win_mainwindow, DSSCL_NORMAL); IDirectSound_Release (pDS); } pDS = NULL; @@ -219,7 +219,8 @@ SNDDMA_InitDirect (void) } if (DS_OK != - IDirectSound_SetCooperativeLevel (pDS, mainwindow, DSSCL_EXCLUSIVE)) { + IDirectSound_SetCooperativeLevel (pDS, win_mainwindow, + DSSCL_EXCLUSIVE)) { Sys_Printf ("Set coop level failed\n"); FreeSound (); return SIS_FAILURE; @@ -276,7 +277,7 @@ SNDDMA_InitDirect (void) } } else { if (DS_OK != - IDirectSound_SetCooperativeLevel (pDS, mainwindow, + IDirectSound_SetCooperativeLevel (pDS, win_mainwindow, DSSCL_WRITEPRIMARY)) { Sys_Printf ("Set coop level failed\n"); FreeSound (); diff --git a/libs/console/Makemodule.am b/libs/console/Makemodule.am index bd745a2e2..97586f514 100644 --- a/libs/console/Makemodule.am +++ b/libs/console/Makemodule.am @@ -28,6 +28,6 @@ libs_console_console_client_la_DEPENDENCIES= $(client_deps) libs_console_console_client_la_SOURCES= $(client_sources) libs_console_console_server_la_LDFLAGS= $(plugin_ldflags) -libs_console_console_server_la_LIBADD= $(server_deps) $(CURSES_LIBS) $(plugin_libadd) +libs_console_console_server_la_LIBADD= $(server_deps) $(NCURSES_LIBS) $(plugin_libadd) libs_console_console_server_la_DEPENDENCIES= $(server_deps) libs_console_console_server_la_SOURCES= $(server_sources) diff --git a/libs/console/server.c b/libs/console/server.c index 201842d27..a621bcc2b 100644 --- a/libs/console/server.c +++ b/libs/console/server.c @@ -31,7 +31,7 @@ # include "config.h" #endif -#ifdef HAVE_CURSES_H +#ifdef HAVE_CURSES # include #endif #ifdef HAVE_STRING_H @@ -84,7 +84,7 @@ static cvar_t *sv_conmode; static void C_KeyEvent (knum_t key, short unicode, qboolean down); -#ifdef HAVE_CURSES_H +#ifdef HAVE_CURSES enum { sv_resize_x = 1, @@ -682,7 +682,7 @@ sv_conmode_f (cvar_t *var) static void C_Init (void) { -#ifdef HAVE_CURSES_H +#ifdef HAVE_CURSES cvar_t *curses = Cvar_Get ("sv_use_curses", "0", CVAR_ROM, NULL, "Set to 1 to enable curses server console."); use_curses = curses->int_val; @@ -705,7 +705,7 @@ C_shutdown (void) Qclose (log_file); log_file = 0; } -#ifdef HAVE_CURSES_H +#ifdef HAVE_CURSES if (use_curses) endwin (); #endif @@ -725,7 +725,7 @@ C_Print (const char *fmt, va_list args) Qputs (log_file, buffer->str); Qflush (log_file); } -#ifdef HAVE_CURSES_H +#ifdef HAVE_CURSES if (use_curses) { print (buffer->str); } else @@ -741,7 +741,7 @@ C_Print (const char *fmt, va_list args) static void C_ProcessInput (void) { -#ifdef HAVE_CURSES_H +#ifdef HAVE_CURSES if (use_curses) { process_input (); } else @@ -757,7 +757,7 @@ C_ProcessInput (void) static void C_KeyEvent (knum_t key, short unicode, qboolean down) { -#ifdef HAVE_CURSES_H +#ifdef HAVE_CURSES key_event (key, unicode, down); #endif } diff --git a/libs/net/nm/net_dgrm.c b/libs/net/nm/net_dgrm.c index f69b246b6..7d9c88ab4 100644 --- a/libs/net/nm/net_dgrm.c +++ b/libs/net/nm/net_dgrm.c @@ -120,7 +120,7 @@ NET_Ban_f (void) switch (Cmd_Argc ()) { case 1: - if (((struct in_addr *) &banAddr)->s_addr) { + if (banAddr) { struct in_addr t; t.s_addr = banAddr; strcpy (addrStr, inet_ntoa (t)); diff --git a/libs/net/nm/net_wins.c b/libs/net/nm/net_wins.c index 77eaccc21..299509a18 100644 --- a/libs/net/nm/net_wins.c +++ b/libs/net/nm/net_wins.c @@ -437,10 +437,11 @@ PartialIPAddress (const char *in, netadr_t *hostaddr) return 0; } //============================================================================= - +static int WINS_Connect_called; int WINS_Connect (int socket, netadr_t *addr) { + WINS_Connect_called++; return 0; } @@ -543,6 +544,10 @@ WINS_AddrToString (netadr_t *addr) { static dstring_t *buffer; + if (!buffer) { + buffer = dstring_new (); + } + dsprintf (buffer, "%d.%d.%d.%d:%d", addr->ip[0], addr->ip[1], addr->ip[2], addr->ip[3], ntohs (addr->port)); diff --git a/libs/util/cmem.c b/libs/util/cmem.c index 1879f7ea3..5ff1898f5 100644 --- a/libs/util/cmem.c +++ b/libs/util/cmem.c @@ -25,10 +25,20 @@ */ #include +#include #include "QF/alloc.h" #include "QF/cmem.h" +#ifdef _WIN32 +#define aligned_alloc(align, size) _aligned_malloc(size, align) +#define _SC_PAGESIZE 1 +static size_t sysconf (int key) +{ + return 1024; +} +#endif + static size_t __attribute__((const)) ilog2 (size_t x) { diff --git a/libs/util/sys.c b/libs/util/sys.c index 6e36c4545..f448a6f55 100644 --- a/libs/util/sys.c +++ b/libs/util/sys.c @@ -103,19 +103,6 @@ int sys_checksum; static sys_printf_t sys_std_printf_function = Sys_StdPrintf; static sys_printf_t sys_err_printf_function = Sys_ErrPrintf; -#ifndef _WIN32 -static struct sigaction save_hup; -static struct sigaction save_quit; -static struct sigaction save_trap; -static struct sigaction save_iot; -static struct sigaction save_bus; -#endif -static struct sigaction save_int; -static struct sigaction save_ill; -static struct sigaction save_segv; -static struct sigaction save_term; -static struct sigaction save_fpe; - typedef struct shutdown_list_s { struct shutdown_list_s *next; void (*func) (void *); @@ -635,11 +622,18 @@ Sys_PageIn (void *ptr, size_t size) VISIBLE void * Sys_Alloc (size_t size) { +#ifdef _WIN32 + size_t page_size = 4096; + size_t page_mask = page_size - 1; + size = (size + page_mask) & ~page_mask; + return VirtualAlloc (0, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); +#else size_t page_size = sysconf (_SC_PAGESIZE); size_t page_mask = page_size - 1; size = (size + page_mask) & ~page_mask; return mmap (0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); +#endif } VISIBLE void @@ -831,9 +825,69 @@ static void __attribute__((noreturn)) aiee (int sig) { printf ("AIEE, signal %d in shutdown code, giving up\n", sig); +#ifdef _WIN32 + longjmp (aiee_abort, 1); +#else siglongjmp (aiee_abort, 1); +#endif } +#ifdef _WIN32 +static void +signal_handler (int sig) +{ + int volatile recover = 0; // volatile for longjump + static volatile int in_signal_handler = 0; + + if (in_signal_handler) { + aiee (sig); + } + printf ("Received signal %d, exiting...\n", sig); + + switch (sig) { + case SIGINT: + case SIGTERM: + signal (SIGINT, SIG_DFL); + signal (SIGTERM, SIG_DFL); + Sys_Quit (); + default: + if (!setjmp (aiee_abort)) { + if (signal_hook) + recover = signal_hook (sig, signal_hook_data); + Sys_Shutdown (); + } + + if (!recover) { + signal (SIGILL, SIG_DFL); + signal (SIGSEGV, SIG_DFL); + signal (SIGFPE, SIG_DFL); + } + } +} + +static void +hook_signlas (void) +{ + // catch signals + signal (SIGINT, signal_handler); + signal (SIGILL, signal_handler); + signal (SIGSEGV, signal_handler); + signal (SIGTERM, signal_handler); + signal (SIGFPE, signal_handler); +} +#else + +static struct sigaction save_hup; +static struct sigaction save_quit; +static struct sigaction save_trap; +static struct sigaction save_iot; +static struct sigaction save_bus; +static struct sigaction save_int; +static struct sigaction save_ill; +static struct sigaction save_segv; +static struct sigaction save_term; +static struct sigaction save_fpe; + static void signal_handler (int sig, siginfo_t *info, void *ucontext) { @@ -848,10 +902,8 @@ signal_handler (int sig, siginfo_t *info, void *ucontext) switch (sig) { case SIGINT: case SIGTERM: -#ifndef _WIN32 case SIGHUP: sigaction (SIGHUP, &save_hup, 0); -#endif sigaction (SIGINT, &save_int, 0); sigaction (SIGTERM, &save_term, 0); Sys_Quit (); @@ -863,12 +915,10 @@ signal_handler (int sig, siginfo_t *info, void *ucontext) } if (!recover) { -#ifndef _WIN32 sigaction (SIGQUIT, &save_quit, 0); sigaction (SIGTRAP, &save_trap, 0); sigaction (SIGIOT, &save_iot, 0); sigaction (SIGBUS, &save_bus, 0); -#endif sigaction (SIGILL, &save_ill, 0); sigaction (SIGSEGV, &save_segv, 0); sigaction (SIGFPE, &save_fpe, 0); @@ -876,8 +926,8 @@ signal_handler (int sig, siginfo_t *info, void *ucontext) } } -VISIBLE void -Sys_Init (void) +static void +hook_signlas (void) { // catch signals struct sigaction action = {}; @@ -895,6 +945,13 @@ Sys_Init (void) sigaction (SIGSEGV, &action, &save_segv); sigaction (SIGTERM, &action, &save_term); sigaction (SIGFPE, &action, &save_fpe); +} +#endif + +VISIBLE void +Sys_Init (void) +{ + hook_signlas (); Cvar_Init_Hash (); Cmd_Init_Hash (); diff --git a/libs/video/renderer/Makemodule.am b/libs/video/renderer/Makemodule.am index 54fa0a2e3..562a9bebc 100644 --- a/libs/video/renderer/Makemodule.am +++ b/libs/video/renderer/Makemodule.am @@ -395,7 +395,7 @@ V_VKGEN_0 = @echo " VKGEN " $@; V_VKGEN_1 = $(vkparse_cinc): $(vkgen) $(qwaq_curses) $(vkparse_plist) - $(V_VKGEN)$(qwaq_curses) $(vkgen) -- $(vkparse_plist) $(vkparse_cinc).t $(vkparse_hinc).t &&\ + $(V_VKGEN)$(QWAQ_CURSES) $(vkgen) -- $(vkparse_plist) $(vkparse_cinc).t $(vkparse_hinc).t &&\ $(am__mv) $(vkparse_cinc).t $(vkparse_cinc) &&\ $(am__mv) $(vkparse_hinc).t $(vkparse_hinc) diff --git a/libs/video/targets/Makemodule.am b/libs/video/targets/Makemodule.am index 22425f7c4..710a77c82 100644 --- a/libs/video/targets/Makemodule.am +++ b/libs/video/targets/Makemodule.am @@ -8,10 +8,11 @@ EXTRA_LTLIBRARIES += \ libs/video/targets/libQFsvga.la \ libs/video/targets/libQFx11.la \ libs/video/targets/libQFsdl.la \ - libs/video/targets/libQFwgl.la \ + libs/video/targets/libQFwin.la \ libs/video/targets/libvid_common.la \ libs/video/targets/libvid_sdl.la \ libs/video/targets/libvid_svga.la \ + libs/video/targets/libvid_win.la \ libs/video/targets/libvid_x11.la joy_linux_src= libs/video/targets/joy_linux.c @@ -27,6 +28,15 @@ joy_src= $(joy_null_src) endif endif +win_gl_src = libs/video/targets/vid_win_gl.c +win_sw_src = libs/video/targets/vid_win_sw.c +win_vulkan_src = libs/video/targets/vid_win_vulkan.c +if WIN_VULKAN +win_src = $(win_gl_src) $(win_sw_src) $(win_vulkan_src) +else +win_src = $(win_gl_src) $(win_sw_src) +endif + x11_gl_src = libs/video/targets/vid_x11_gl.c x11_sw_src = libs/video/targets/vid_x11_sw.c x11_vulkan_src = libs/video/targets/vid_x11_vulkan.c @@ -64,6 +74,14 @@ libs_video_targets_libvid_x11_la_CFLAGS= @PREFER_NON_PIC@ $(X_CFLAGS) libs_video_targets_libvid_x11_la_LDFLAGS= @STATIC@ EXTRA_libs_video_targets_libvid_x11_la_SOURCES= $(x11_vulkan_src) +libs_video_targets_libvid_win_la_SOURCES = \ + libs/video/targets/in_win.c \ + libs/video/targets/context_win.c \ + $(win_src) +libs_video_targets_libvid_win_la_CFLAGS= @PREFER_NON_PIC@ $(X_CFLAGS) +libs_video_targets_libvid_win_la_LDFLAGS= @STATIC@ +EXTRA_libs_video_targets_libvid_win_la_SOURCES= $(win_vulkan_src) + libs_video_targets_libvid_svga_la_SOURCES= libs/video/targets/in_svgalib.c libs_video_targets_libvid_svga_la_CFLAGS= @PREFER_NON_PIC@ $(SVGA_CFLAGS) libs_video_targets_libvid_svga_la_LDFLAGS= @STATIC@ @@ -117,16 +135,14 @@ libs_video_targets_libQFsvga_la_LIBADD= $(svga_libs) libs_video_targets_libQFsvga_la_DEPENDENCIES= $(svga_libs) # -# OpenGL in Win32 +# MS Windows # -wgl_libs=libs/video/targets/libvid_common.la libs/video/targets/libvid_gl.la -libs_video_targets_libQFwgl_la_CFLAGS= @PREFER_NON_PIC@ $(WGL_CFLAGS) -libs_video_targets_libQFwgl_la_SOURCES = \ - libs/video/targets/in_win.c \ - libs/video/targets/vid_wgl.c -libs_video_targets_libQFwgl_la_LDFLAGS= @STATIC@ -libs_video_targets_libQFwgl_la_LIBADD= $(wgl_libs) -libs_video_targets_libQFwgl_la_DEPENDENCIES= $(wgl_libs) +win_libs=libs/video/targets/libvid_common.la libs/video/targets/libvid_win.la +libs_video_targets_libQFwin_la_CFLAGS= @PREFER_NON_PIC@ $(WGL_CFLAGS) +libs_video_targets_libQFwin_la_SOURCES= libs/video/targets/vid_win.c +libs_video_targets_libQFwin_la_LDFLAGS= @STATIC@ +libs_video_targets_libQFwin_la_LIBADD= $(win_libs) +libs_video_targets_libQFwin_la_DEPENDENCIES= $(win_libs) # # X11 software rendering diff --git a/libs/video/targets/context_win.c b/libs/video/targets/context_win.c new file mode 100644 index 000000000..d0bd49db2 --- /dev/null +++ b/libs/video/targets/context_win.c @@ -0,0 +1,1403 @@ +/* + 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 + +#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" +#include "vid_internal.h" +#include "vid_sw.h" + +HWND win_mainwindow; +HDC win_maindc; +HDC win_dib_section; +int win_using_ddraw; +int win_palettized; +LPDIRECTDRAWSURFACE win_dd_frontbuffer; +LPDIRECTDRAWSURFACE win_dd_backbuffer; +RECT win_src_rect; +RECT win_dst_rect; +RECT win_window_rect; +HDC win_gdi; +int win_canalttab = 0; +int win_palettized; +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) + +static cvar_t *vid_ddraw; + +// Note that 0 is MODE_WINDOWED +static cvar_t *vid_mode; + +// Note that 0 is MODE_WINDOWED +static cvar_t *_vid_default_mode; + +// Note that 3 is MODE_FULLSCREEN_DEFAULT +static cvar_t *_vid_default_mode_win; +static cvar_t *vid_wait; +static cvar_t *vid_nopageflip; +static cvar_t *_vid_wait_override; +static cvar_t *vid_config_x; +static cvar_t *vid_config_y; +static cvar_t *vid_stretch_by_2; +static cvar_t *_windowed_mouse; +static cvar_t *vid_fullscreen_mode; +static cvar_t *vid_windowed_mode; +static cvar_t *block_switch; +static cvar_t *vid_window_x; +static cvar_t *vid_window_y; + +//FIXME?int yeahimconsoled; + +#define MAX_MODE_LIST 36 +#define VID_ROW_SIZE 3 + +extern qboolean Minimized; + +HWND WINAPI InitializeWindow (HINSTANCE hInstance, int nCmdShow); + +int DIBWidth, DIBHeight; +RECT WindowRect; +DWORD WindowStyle, ExWindowStyle; + +int window_center_x, window_center_y, window_width, window_height; +RECT window_rect; + +DEVMODE win_gdevmode; +static qboolean startwindowed = 0, windowed_mode_set; +static qboolean vid_palettized; +static int vid_fulldib_on_focus_mode; +static qboolean force_minimized, in_mode_set, force_mode_set; +static qboolean vid_mode_set; +static HICON hIcon; + + +int vid_modenum = NO_MODE; +int vid_testingmode, vid_realmode; +double vid_testendtime; +int vid_default = MODE_WINDOWED; +static int windowed_default; + +modestate_t modestate = MS_UNINIT; + +byte vid_curpal[256 * 3]; + +unsigned short d_8to16table[256]; + +int mode; + +typedef struct { + modestate_t type; + int width; + int height; + int modenum; + int fullscreen; + char modedesc[13]; +} vmode_t; + +static vmode_t modelist[MAX_MODE_LIST]; +static int nummodes; + +int aPage; // Current active display page +int vPage; // Current visible display page +int waitVRT = true; // True to wait for retrace on flip + +static vmode_t badmode; + +/* +============================================================================= + + DIRECTDRAW VIDEO DRIVER + +============================================================================= +*/ + +LPDIRECTDRAW dd_Object = NULL; +HINSTANCE hInstDDraw = NULL; + +LPDIRECTDRAWCLIPPER dd_Clipper = NULL; + +typedef HRESULT (WINAPI *ddCreateProc_t) (GUID FAR *, + LPDIRECTDRAW FAR *, + IUnknown FAR *); +ddCreateProc_t ddCreate = NULL; + +unsigned ddpal[256]; + +byte *vidbuf = NULL; + + +int dd_window_width = 640; +int dd_window_height = 480; + +static void +DD_UpdateRects (int width, int height) +{ + POINT p = { .x = 0, .y = 0 }; + // first we need to figure out where on the primary surface our window + // lives + ClientToScreen (win_mainwindow, &p); + GetClientRect (win_mainwindow, &win_dst_rect); + OffsetRect (&win_dst_rect, p.x, p.y); + SetRect (&win_src_rect, 0, 0, width, height); +} + + +static void +VID_CreateDDrawDriver (int width, int height, const byte *palette, + void **buffer, int *rowbytes) +{ + DDSURFACEDESC ddsd; + + win_using_ddraw = false; + dd_window_width = width; + dd_window_height = height; + + vidbuf = (byte *) malloc (width * height); + buffer[0] = vidbuf; + rowbytes[0] = width; + + if (!(hInstDDraw = LoadLibrary ("ddraw.dll"))) { + return; + } + if (!(ddCreate = (ddCreateProc_t) GetProcAddress (hInstDDraw, + "DirectDrawCreate"))) { + return; + } + + if (FAILED (ddCreate (NULL, &dd_Object, NULL))) { + return; + } + if (FAILED (dd_Object->lpVtbl->SetCooperativeLevel (dd_Object, + win_mainwindow, + DDSCL_NORMAL))) { + return; + } + + // the primary surface in windowed mode is the full screen + memset (&ddsd, 0, sizeof (ddsd)); + ddsd.dwSize = sizeof (ddsd); + ddsd.dwFlags = DDSD_CAPS; + ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_VIDEOMEMORY; + + // ...and create it + if (FAILED (dd_Object->lpVtbl->CreateSurface (dd_Object, &ddsd, + &win_dd_frontbuffer, NULL))) { + return; + } + + // not using a clipper will slow things down and switch aero off + if (FAILED (IDirectDraw_CreateClipper (dd_Object, 0, &dd_Clipper, NULL))) { + return; + } + if (FAILED (IDirectDrawClipper_SetHWnd (dd_Clipper, 0, win_mainwindow))) { + return; + } + if (FAILED (IDirectDrawSurface_SetClipper (win_dd_frontbuffer, + dd_Clipper))) { + return; + } + + // the secondary surface is an offscreen surface that is the currect + // dimensions + // this will be blitted to the correct location on the primary surface + // (which is the full screen) during our draw op + memset (&ddsd, 0, sizeof (ddsd)); + ddsd.dwSize = sizeof (ddsd); + ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY; + ddsd.dwWidth = width; + ddsd.dwHeight = height; + + if (FAILED (IDirectDraw_CreateSurface (dd_Object, &ddsd, + &win_dd_backbuffer, NULL))) { + return; + } + + // direct draw is working now + win_using_ddraw = true; + + // create a palette + VID_InitGamma (palette); + viddef.vid_internal->set_palette (palette); + + // create initial rects + DD_UpdateRects (dd_window_width, dd_window_height); +} + + +/* +===================================================================== + + GDI VIDEO DRIVER + +===================================================================== +*/ + +// common bitmap definition +typedef struct dibinfo { + BITMAPINFOHEADER header; + RGBQUAD acolors[256]; +} dibinfo_t; + + +static HGDIOBJ previously_selected_GDI_obj = NULL; +HBITMAP hDIBSection; +byte *pDIBBase = NULL; +HDC hdcDIBSection = NULL; +HDC hdcGDI = NULL; + + +static void +VID_CreateGDIDriver (int width, int height, const byte *palette, void **buffer, + int *rowbytes) +{ + dibinfo_t dibheader; + BITMAPINFO *pbmiDIB = (BITMAPINFO *) & dibheader; + int i; + + hdcGDI = GetDC (win_mainwindow); + memset (&dibheader, 0, sizeof (dibheader)); + + // fill in the bitmap info + pbmiDIB->bmiHeader.biSize = sizeof (BITMAPINFOHEADER); + pbmiDIB->bmiHeader.biWidth = width; + pbmiDIB->bmiHeader.biHeight = height; + pbmiDIB->bmiHeader.biPlanes = 1; + pbmiDIB->bmiHeader.biCompression = BI_RGB; + pbmiDIB->bmiHeader.biSizeImage = 0; + pbmiDIB->bmiHeader.biXPelsPerMeter = 0; + pbmiDIB->bmiHeader.biYPelsPerMeter = 0; + pbmiDIB->bmiHeader.biClrUsed = 256; + pbmiDIB->bmiHeader.biClrImportant = 256; + pbmiDIB->bmiHeader.biBitCount = 8; + + // fill in the palette + for (i = 0; i < 256; i++) { + // d_8to24table isn't filled in yet so this is just for testing + dibheader.acolors[i].rgbRed = palette[i * 3]; + dibheader.acolors[i].rgbGreen = palette[i * 3 + 1]; + dibheader.acolors[i].rgbBlue = palette[i * 3 + 2]; + } + + // create the DIB section + hDIBSection = CreateDIBSection (hdcGDI, + pbmiDIB, + DIB_RGB_COLORS, + (void **) &pDIBBase, NULL, 0); + + // set video buffers + if (pbmiDIB->bmiHeader.biHeight > 0) { + // bottom up + buffer[0] = pDIBBase + (height - 1) * width; + rowbytes[0] = -width; + } else { + // top down + buffer[0] = pDIBBase; + rowbytes[0] = width; + } + + // clear the buffer + memset (pDIBBase, 0xff, width * height); + + if ((hdcDIBSection = CreateCompatibleDC (hdcGDI)) == NULL) + Sys_Error ("DIB_Init() - CreateCompatibleDC failed\n"); + + if ((previously_selected_GDI_obj = + SelectObject (hdcDIBSection, hDIBSection)) == NULL) + Sys_Error ("DIB_Init() - SelectObject failed\n"); + + // create a palette + VID_InitGamma (palette); + viddef.vid_internal->set_palette (palette); +} + +void +Win_CreateDriver (void) +{ + if (vid_ddraw->int_val) { + VID_CreateDDrawDriver (DIBWidth, DIBHeight, viddef.palette, + &viddef.buffer, &viddef.rowbytes); + } + if (!win_using_ddraw) { + // directdraw failed or was not requested + // + // if directdraw failed, it may be partially initialized, so make sure + // the slate is clean + Win_UnloadAllDrivers (); + + VID_CreateGDIDriver (DIBWidth, DIBHeight, viddef.palette, + &viddef.buffer, &viddef.rowbytes); + } +} + +void +Win_UnloadAllDrivers (void) +{ + // shut down ddraw + if (vidbuf) { + free (vidbuf); + vidbuf = NULL; + } + + if (dd_Clipper) { + IDirectDrawClipper_Release (dd_Clipper); + dd_Clipper = NULL; + } + + if (win_dd_frontbuffer) { + IDirectDrawSurface_Release (win_dd_frontbuffer); + win_dd_frontbuffer = NULL; + } + + if (win_dd_backbuffer) { + IDirectDrawSurface_Release (win_dd_backbuffer); + win_dd_backbuffer = NULL; + } + + if (dd_Object) { + IDirectDraw_Release (dd_Object); + dd_Object = NULL; + } + + if (hInstDDraw) { + FreeLibrary (hInstDDraw); + hInstDDraw = NULL; + } + + ddCreate = NULL; + + // shut down gdi + if (hdcDIBSection) { + SelectObject (hdcDIBSection, previously_selected_GDI_obj); + DeleteDC (hdcDIBSection); + hdcDIBSection = NULL; + } + + if (hDIBSection) { + DeleteObject (hDIBSection); + hDIBSection = NULL; + pDIBBase = NULL; + } + + if (hdcGDI) { + // if hdcGDI exists then win_mainwindow must also be valid + ReleaseDC (win_mainwindow, hdcGDI); + hdcGDI = NULL; + } + // not using ddraw now + win_using_ddraw = false; +} + + + +// compatibility +qboolean DDActive; + +void VID_MenuDraw (void); +void VID_MenuKey (int key); + +LONG WINAPI MainWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); +void AppActivate (BOOL fActive, BOOL minimize); + +static int VID_SetMode (int modenum, const byte *palette); + + +/* +================ +VID_RememberWindowPos +================ +*/ +static void __attribute__ ((used)) +VID_RememberWindowPos (void) +{ + RECT rect; + + if (GetWindowRect (win_mainwindow, &rect)) { + if ((rect.left < GetSystemMetrics (SM_CXSCREEN)) && + (rect.top < GetSystemMetrics (SM_CYSCREEN)) && + (rect.right > 0) && (rect.bottom > 0)) { + Cvar_SetValue (vid_window_x, (float) rect.left); + Cvar_SetValue (vid_window_y, (float) rect.top); + } + } +} + + +/* +================ +VID_CheckWindowXY +================ +*/ +static void +VID_CheckWindowXY (void) +{ + if ((vid_window_x->int_val > (GetSystemMetrics (SM_CXSCREEN) - 160)) || + (vid_window_y->int_val > (GetSystemMetrics (SM_CYSCREEN) - 120)) || + (vid_window_x->int_val < 0) || (vid_window_y->int_val < 0)) { + Cvar_SetValue (vid_window_x, 0.0); + Cvar_SetValue (vid_window_y, 0.0); + } +} + + +/* +================ +VID_UpdateWindowStatus +================ +*/ +void +Win_UpdateWindowStatus (int window_x, int window_y) +{ + window_rect.left = window_x; + window_rect.top = window_y; + window_rect.right = window_x + window_width; + window_rect.bottom = window_y + window_height; + window_center_x = (window_rect.left + window_rect.right) / 2; + window_center_y = (window_rect.top + window_rect.bottom) / 2; + IN_UpdateClipCursor (); +} + + +/* +================ +ClearAllStates +================ +*/ +static void +ClearAllStates (void) +{ + int i; + + // send an up event for each key, to make sure the server clears them all + for (i = 0; i < 256; i++) { + Key_Event (i, 0, false); + } + + Key_ClearStates (); + IN_ClearStates (); +} + + +/* +================ +VID_CheckAdequateMem +================ +*/ +static qboolean +VID_CheckAdequateMem (int width, int height) +{ + // there will always be enough ;) + return true; +} + + +static void +VID_InitModes (HINSTANCE hInstance) +{ + WNDCLASS wc; + HDC hdc; + +//FIXME hIcon = LoadIcon (hInstance, MAKEINTRESOURCE (IDI_ICON2)); + + /* Register the frame class */ + wc.style = CS_OWNDC; + wc.lpfnWndProc = (WNDPROC) MainWndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInstance; + wc.hIcon = 0; + wc.hCursor = LoadCursor (NULL, IDC_ARROW); + wc.hbrBackground = NULL; + wc.lpszMenuName = 0; + wc.lpszClassName = "WinQuake"; + + if (!RegisterClass (&wc)) + Sys_Error ("Couldn't register window class"); + + modelist[0].type = MS_WINDOWED; + modelist[0].width = 320; + modelist[0].height = 240; + strcpy (modelist[0].modedesc, "320x240"); + modelist[0].modenum = MODE_WINDOWED; + modelist[0].fullscreen = 0; + + modelist[1].type = MS_WINDOWED; + modelist[1].width = 640; + modelist[1].height = 480; + strcpy (modelist[1].modedesc, "640x480"); + modelist[1].modenum = MODE_WINDOWED + 1; + modelist[1].fullscreen = 0; + + modelist[2].type = MS_WINDOWED; + modelist[2].width = 800; + modelist[2].height = 600; + strcpy (modelist[2].modedesc, "800x600"); + modelist[2].modenum = MODE_WINDOWED + 2; + modelist[2].fullscreen = 0; + + // automatically stretch the default mode up if > 640x480 desktop + // resolution + hdc = GetDC (NULL); + + if ((GetDeviceCaps (hdc, HORZRES) > 800) + && !COM_CheckParm ("-noautostretch")) { + vid_default = MODE_WINDOWED + 2; + } else if ((GetDeviceCaps (hdc, HORZRES) > 640) + && !COM_CheckParm ("-noautostretch")) { + vid_default = MODE_WINDOWED + 1; + } else { + vid_default = MODE_WINDOWED; + } + + // always start at the lowest mode then switch to the higher one if + // selected + vid_default = MODE_WINDOWED; + + windowed_default = vid_default; + ReleaseDC (NULL, hdc); + nummodes = 3; // reserve space for windowed mode +} + + +/* +================= +VID_GetDisplayModes +================= +*/ +static void +VID_GetDisplayModes (void) +{ + DEVMODE devmode; + int i, modenum, existingmode, originalnummodes, lowestres; + BOOL stat; + + // enumerate > 8 bpp modes + originalnummodes = nummodes; + modenum = 0; + lowestres = 99999; + + do { + stat = EnumDisplaySettings (NULL, modenum, &devmode); + + if ((devmode.dmPelsWidth <= MAXWIDTH) + && (devmode.dmPelsHeight <= MAXHEIGHT) + && (devmode.dmPelsWidth >= 320) + && (devmode.dmPelsHeight >= 240) + && (nummodes < MAX_MODE_LIST)) { + devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; + + if (ChangeDisplaySettings (&devmode, CDS_TEST | CDS_FULLSCREEN) == + DISP_CHANGE_SUCCESSFUL) { + modelist[nummodes].type = MS_FULLDIB; + modelist[nummodes].width = devmode.dmPelsWidth; + modelist[nummodes].height = devmode.dmPelsHeight; + modelist[nummodes].modenum = 0; + modelist[nummodes].fullscreen = 1; + sprintf (modelist[nummodes].modedesc, "%dx%d", + (int) devmode.dmPelsWidth, + (int) devmode.dmPelsHeight); + + // see is the mode already there + // (same dimensions but different refresh rate) + for (i = originalnummodes, existingmode = 0; + i < nummodes; i++) { + if ((modelist[nummodes].width == modelist[i].width) + && (modelist[nummodes].height == modelist[i].height)) { + existingmode = 1; + break; + } + } + + // if it's not add it to the list + if (!existingmode) { + if (modelist[nummodes].width < lowestres) + lowestres = modelist[nummodes].width; + + nummodes++; + } + } + } + + modenum++; + } while (stat); + + if (nummodes != originalnummodes) + vid_default = MODE_FULLSCREEN_DEFAULT; + else + Sys_Printf ("No fullscreen DIB modes found\n"); +} + +void +Win_OpenDisplay (void) +{ + VID_InitModes (global_hInstance); + VID_GetDisplayModes (); + + vid_testingmode = 0; + + // if (COM_CheckParm("-startwindowed")) + { + startwindowed = 1; + vid_default = windowed_default; + } + +//FIXME? if (hwnd_dialog) +//FIXME? DestroyWindow (hwnd_dialog); + + // 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 + win_mainwindow = CreateWindowEx (ExWindowStyle, + "WinQuake", + "WinQuake", + WindowStyle, + 0, 0, + WindowRect.right - WindowRect.left, + WindowRect.bottom - WindowRect.top, + NULL, NULL, global_hInstance, NULL); + + if (!win_mainwindow) + Sys_Error ("Couldn't create DIB window"); + + // done + vid_mode_set = true; +//FIXME if (firsttime) S_Init (); +} + +void +Win_CloseDisplay (void) +{ + if (viddef.initialized) { + if (modestate == MS_FULLDIB) { + ChangeDisplaySettings (NULL, CDS_FULLSCREEN); + } + + PostMessage (HWND_BROADCAST, WM_PALETTECHANGED, (WPARAM) win_mainwindow, + (LPARAM) 0); + PostMessage (HWND_BROADCAST, WM_SYSCOLORCHANGE, (WPARAM) 0, (LPARAM) 0); + AppActivate (false, false); + +//FIXME? if (hwnd_dialog) DestroyWindow (hwnd_dialog); + if (win_mainwindow) + DestroyWindow (win_mainwindow); + + vid_testingmode = 0; + viddef.initialized = false; + } +} + +void +Win_SetVidMode (int width, int height, const byte *palette) +{ +//FIXME SCR_StretchInit(); + + force_mode_set = true; + VID_SetMode (vid_default, palette); + force_mode_set = false; + vid_realmode = vid_modenum; + strcpy (badmode.modedesc, "Bad mode"); +} + +static void +VID_DestroyWindow (void) +{ + if (modestate == MS_FULLDIB) + ChangeDisplaySettings (NULL, CDS_FULLSCREEN); + + Win_UnloadAllDrivers (); +} + +static void +VID_CheckModedescFixup (int mode) +{ +} + +static qboolean +VID_SetWindowedMode (int modenum) +{ + if (!windowed_mode_set) { + if (COM_CheckParm ("-resetwinpos")) { + Cvar_SetValue (vid_window_x, 0.0); + Cvar_SetValue (vid_window_y, 0.0); + } + + windowed_mode_set = true; + } + + VID_CheckModedescFixup (modenum); + VID_DestroyWindow (); + + WindowRect.top = WindowRect.left = 0; + WindowRect.right = modelist[modenum].width; + WindowRect.bottom = modelist[modenum].height; + DIBWidth = modelist[modenum].width; + DIBHeight = modelist[modenum].height; + + WindowStyle = WS_OVERLAPPEDWINDOW | WS_CAPTION | WS_SYSMENU | WS_SIZEBOX | + WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_CLIPSIBLINGS | + WS_CLIPCHILDREN | WS_THICKFRAME; + + // WindowStyle = WS_OVERLAPPEDWINDOW|WS_VISIBLE; + ExWindowStyle = 0; + AdjustWindowRectEx (&WindowRect, WindowStyle, FALSE, 0); + + // the first time we're called to set the mode, create the window we'll use + // for the rest of the session + if (!vid_mode_set) { + } else { + SetWindowLong (win_mainwindow, GWL_STYLE, WindowStyle | WS_VISIBLE); + SetWindowLong (win_mainwindow, GWL_EXSTYLE, ExWindowStyle); + } + + if (!SetWindowPos (win_mainwindow, + NULL, + 0, 0, + WindowRect.right - WindowRect.left, + WindowRect.bottom - WindowRect.top, + SWP_NOCOPYBITS | SWP_NOZORDER | SWP_HIDEWINDOW)) { + Sys_Error ("Couldn't resize DIB window"); + } + + // position and show the DIB window + VID_CheckWindowXY (); + SetWindowPos (win_mainwindow, NULL, vid_window_x->int_val, + vid_window_y->int_val, 0, 0, + SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW | SWP_DRAWFRAME); + + if (force_minimized) + ShowWindow (win_mainwindow, SW_MINIMIZE); + else + ShowWindow (win_mainwindow, SW_SHOWDEFAULT); + + UpdateWindow (win_mainwindow); + modestate = MS_WINDOWED; + vid_fulldib_on_focus_mode = 0; + + viddef.numpages = 1; + +// viddef.height = viddef.conheight = DIBHeight; +// viddef.width = viddef.conwidth = DIBWidth; + + viddef.height = viddef.conheight = DIBHeight; + viddef.width = viddef.conwidth = DIBWidth; +//FIXME? if (!yeahimconsoled){ +//FIXME? viddef.vconheight = DIBHeight; +//FIXME? viddef.vconwidth = DIBWidth; +//FIXME? } + SendMessage (win_mainwindow, WM_SETICON, (WPARAM) TRUE, (LPARAM) hIcon); + SendMessage (win_mainwindow, WM_SETICON, (WPARAM) FALSE, (LPARAM) hIcon); + + return true; +} + + +static qboolean +VID_SetFullDIBMode (int modenum) +{ + VID_DestroyWindow (); + + win_gdevmode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT; + win_gdevmode.dmPelsWidth = modelist[modenum].width; + win_gdevmode.dmPelsHeight = modelist[modenum].height; + win_gdevmode.dmSize = sizeof (win_gdevmode); + + if (ChangeDisplaySettings (&win_gdevmode, CDS_FULLSCREEN) != + DISP_CHANGE_SUCCESSFUL) + Sys_Error ("Couldn't set fullscreen DIB mode"); + + modestate = MS_FULLDIB; + vid_fulldib_on_focus_mode = modenum; + WindowRect.top = WindowRect.left = 0; + + WindowRect.right = modelist[modenum].width; + WindowRect.bottom = modelist[modenum].height; + + DIBWidth = modelist[modenum].width; + DIBHeight = modelist[modenum].height; + + WindowStyle = WS_POPUP | WS_SYSMENU | WS_CLIPSIBLINGS | WS_CLIPCHILDREN; + ExWindowStyle = 0; + + AdjustWindowRectEx (&WindowRect, WindowStyle, FALSE, 0); + + SetWindowLong (win_mainwindow, GWL_STYLE, WindowStyle | WS_VISIBLE); + SetWindowLong (win_mainwindow, GWL_EXSTYLE, ExWindowStyle); + + if (!SetWindowPos (win_mainwindow, + NULL, + 0, 0, + WindowRect.right - WindowRect.left, + WindowRect.bottom - WindowRect.top, + SWP_NOCOPYBITS | SWP_NOZORDER)) { + Sys_Error ("Couldn't resize DIB window"); + } + // position and show the DIB window + SetWindowPos (win_mainwindow, HWND_TOPMOST, 0, 0, 0, 0, + SWP_NOSIZE | SWP_SHOWWINDOW | SWP_DRAWFRAME); + ShowWindow (win_mainwindow, SW_SHOWDEFAULT); + UpdateWindow (win_mainwindow); + + viddef.numpages = 1; + +#ifdef SCALED2D + viddef.height = viddef.conheight = DIBHeight; + viddef.width = viddef.conwidth = DIBWidth; + // viddef.vconwidth = 320; + // viddef.vconheight = 200; +//FIXME? if (!yeahimconsoled){ +//FIXME? viddef.vconheight = DIBHeight; +//FIXME? viddef.vconwidth = DIBWidth; +//FIXME? } +#else + viddef.height = viddef.conheight = DIBHeight; + viddef.width = viddef.conwidth = DIBWidth; +#endif + + return true; +} + +static void +VID_RestoreOldMode (int original_mode) +{ + static qboolean inerror = false; + + if (inerror) + return; + + in_mode_set = false; + inerror = true; + // make sure mode set happens (video mode changes) + vid_modenum = original_mode - 1; + + if (!VID_SetMode (original_mode, vid_curpal)) { + vid_modenum = MODE_WINDOWED - 1; + + if (!VID_SetMode (windowed_default, vid_curpal)) + Sys_Error ("Can't set any video mode"); + } + + inerror = false; +} + + +static void __attribute__ ((used)) +VID_SetDefaultMode (void) +{ + if (viddef.initialized) + VID_SetMode (0, vid_curpal); + + IN_DeactivateMouse (); +} + +static vmode_t * +VID_GetModePtr (int modenum) +{ + if ((modenum >= 0) && (modenum < nummodes)) + return &modelist[modenum]; + else + return &badmode; +} + +static char * +VID_GetModeDescription (int mode) +{ + char *pinfo; + vmode_t *pv; + + if ((mode < 0) || (mode >= nummodes)) + return NULL; + + VID_CheckModedescFixup (mode); + pv = VID_GetModePtr (mode); + pinfo = pv->modedesc; + return pinfo; +} + +static int +VID_SetMode (int modenum, const byte *palette) +{ + int original_mode; // FIXME, temp; + qboolean stat; + MSG msg; + HDC hdc; + + while ((modenum >= nummodes) || (modenum < 0)) { + if (vid_modenum == NO_MODE) { + if (modenum == vid_default) { + modenum = windowed_default; + } else { + modenum = vid_default; + } + + Cvar_SetValue (vid_mode, (float) modenum); + } else { + Cvar_SetValue (vid_mode, (float) vid_modenum); + return 0; + } + } + + if (!force_mode_set && (modenum == vid_modenum)) + return true; + + // so Con_Printfs don't mess us up by forcing vid and snd updates +//FIXME? temp = scr_disabled_for_loading; +//FIXME? scr_disabled_for_loading = true; + in_mode_set = true; +//FIXME CDAudio_Pause (); +//FIXME S_ClearBuffer (); + + if (vid_modenum == NO_MODE) + original_mode = windowed_default; + else + original_mode = vid_modenum; + + // Set either the fullscreen or windowed mode + if (modelist[modenum].type == MS_WINDOWED) { + if (_windowed_mouse->int_val) { + stat = VID_SetWindowedMode (modenum); + IN_ActivateMouse (); + IN_HideMouse (); + } else { + IN_DeactivateMouse (); + IN_ShowMouse (); + stat = VID_SetWindowedMode (modenum); + } + } else { + stat = VID_SetFullDIBMode (modenum); + IN_ActivateMouse (); + IN_HideMouse (); + } + + window_width = viddef.width; + window_height = viddef.height; + + + Win_UpdateWindowStatus (0, 0); // FIXME right numbers? +//FIXME CDAudio_Resume (); +//FIXME? scr_disabled_for_loading = temp; + + if (!stat) { + VID_RestoreOldMode (original_mode); + return false; + } + + // now we try to make sure we get the focus on the mode switch, because + // sometimes in some systems we don't. We grab the foreground, then + // finish setting up, pump all our messages, and sleep for a little while + // to let messages finish bouncing around the system, then we put + // ourselves at the top of the z order, then grab the foreground again, + // Who knows if it helps, but it probably doesn't hurt + if (!force_minimized) + SetForegroundWindow (win_mainwindow); + + hdc = GetDC (NULL); + + if (GetDeviceCaps (hdc, RASTERCAPS) & RC_PALETTE) + vid_palettized = true; + else + vid_palettized = false; + + viddef.vid_internal->set_palette (palette); + ReleaseDC (NULL, hdc); + vid_modenum = modenum; + Cvar_SetValue (vid_mode, (float) vid_modenum); + + while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) { + TranslateMessage (&msg); + DispatchMessage (&msg); + } + + Sleep (100); + + if (!force_minimized) { + SetWindowPos (win_mainwindow, HWND_TOP, 0, 0, 0, 0, + SWP_DRAWFRAME | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW | + SWP_NOCOPYBITS); + + SetForegroundWindow (win_mainwindow); + } + // fix the leftover Alt from any Alt-Tab or the like that switched us away + ClearAllStates (); + + Sys_Printf ("%s\n", VID_GetModeDescription (vid_modenum)); + + viddef.vid_internal->set_palette (palette); + + in_mode_set = false; + + viddef.recalc_refdef = 1; + +//FIXME SCR_StretchInit(); +//FIXME SCR_StretchRefresh(); +//FIXME SCR_CvarCheck(); + return true; +} + + + + +//========================================================================== + + +/* +================ +VID_HandlePause +================ +*/ +static void __attribute__ ((used)) +VID_HandlePause (qboolean pause) +{ + if ((modestate == MS_WINDOWED) && _windowed_mouse->int_val) { + if (pause) { + IN_DeactivateMouse (); + IN_ShowMouse (); + } else { + IN_ActivateMouse (); + IN_HideMouse (); + } + } +} + + +/* +=================================================================== + +MAIN WINDOW + +=================================================================== +*/ + +typedef struct { + int modenum; + char *desc; + int iscur; + int width; +} modedesc_t; + +#define MAX_COLUMN_SIZE 5 +#define MODE_AREA_HEIGHT (MAX_COLUMN_SIZE + 6) +#define MAX_MODEDESCS (MAX_COLUMN_SIZE*3) + +//static modedesc_t modedescs[MAX_MODEDESCS]; + +static int +VID_NumModes (void) +{ + return nummodes; +} + +static char * __attribute__((used)) +VID_GetModeDescriptionMemCheck (int mode) +{ + char *pinfo; + vmode_t *pv; + + if ((mode < 0) || (mode >= nummodes)) + return NULL; + + VID_CheckModedescFixup (mode); + pv = VID_GetModePtr (mode); + pinfo = pv->modedesc; + + if (VID_CheckAdequateMem (pv->width, pv->height)) { + return pinfo; + } else { + return NULL; + } +} + + +// Tacks on "windowed" or "fullscreen" +static char * __attribute__((used)) +VID_GetModeDescription2 (int mode) +{ + static char pinfo[40]; + vmode_t *pv; + + if ((mode < 0) || (mode >= nummodes)) + return NULL; + + VID_CheckModedescFixup (mode); + pv = VID_GetModePtr (mode); + + if (modelist[mode].type == MS_FULLSCREEN) { + sprintf (pinfo, "%s fullscreen", pv->modedesc); + } else if (modelist[mode].type == MS_FULLDIB) { + sprintf (pinfo, "%s fullscreen", pv->modedesc); + } else { + sprintf (pinfo, "%s windowed", pv->modedesc); + } + + return pinfo; +} + + +// KJB: Added this to return the mode driver name in description for console +static char * +VID_GetExtModeDescription (int mode) +{ + static char pinfo[40]; + vmode_t *pv; + + if ((mode < 0) || (mode >= nummodes)) + return NULL; + + VID_CheckModedescFixup (mode); + pv = VID_GetModePtr (mode); + + if (modelist[mode].type == MS_FULLDIB) { + sprintf (pinfo, "%s fullscreen", pv->modedesc); + } else { + sprintf (pinfo, "%s windowed", pv->modedesc); + } + + return pinfo; +} +static void +VID_DescribeCurrentMode_f (void) +{ + Sys_Printf ("%s\n", VID_GetExtModeDescription (vid_modenum)); +} + +static void +VID_NumModes_f (void) +{ + if (nummodes == 1) + Sys_Printf ("%d video mode is available\n", nummodes); + else + Sys_Printf ("%d video modes are available\n", nummodes); +} + + +static void +VID_DescribeMode_f (void) +{ + int modenum; + + modenum = atoi (Cmd_Argv (1)); + Sys_Printf ("%s\n", VID_GetExtModeDescription (modenum)); +} + + +static void +VID_DescribeModes_f (void) +{ + int i, lnummodes; + char *pinfo; + qboolean na; + vmode_t *pv; + + na = false; + lnummodes = VID_NumModes (); + + for (i = 0; i < lnummodes; i++) { + pv = VID_GetModePtr (i); + pinfo = VID_GetExtModeDescription (i); + + if (VID_CheckAdequateMem (pv->width, pv->height)) { + Sys_Printf ("%2d: %s\n", i, pinfo); + } else { + Sys_Printf ("**: %s\n", pinfo); + na = true; + } + } + + if (na) { + Sys_Printf ("\n[**: not enough system RAM for mode]\n"); + } +} + +static void +VID_TestMode_f (void) +{ + int modenum; + double testduration; + + if (!vid_testingmode) { + modenum = atoi (Cmd_Argv (1)); + + if (VID_SetMode (modenum, vid_curpal)) { + vid_testingmode = 1; + testduration = atof (Cmd_Argv (2)); + + if (testduration == 0) + testduration = 5.0; + + vid_testendtime = Sys_DoubleTime () + testduration; + } + } +} + +static void +VID_Windowed_f (void) +{ + VID_SetMode (vid_windowed_mode->int_val, vid_curpal); +} + +static void +VID_Fullscreen_f (void) +{ + VID_SetMode (vid_fullscreen_mode->int_val, vid_curpal); +} + +static void +VID_Minimize_f (void) +{ + // we only support minimizing windows; if you're fullscreen, + // switch to windowed first + if (modestate == MS_WINDOWED) + ShowWindow (win_mainwindow, SW_MINIMIZE); +} + +static void +VID_ForceMode_f (void) +{ + int modenum; + + if (!vid_testingmode) { + modenum = atoi (Cmd_Argv (1)); + force_mode_set = 1; + VID_SetMode (modenum, vid_curpal); + force_mode_set = 0; + } +} + +void +Win_SetCaption (const char *text) +{ + if (win_mainwindow) { + SetWindowText (win_mainwindow, text); + } +} + +//static WORD systemgammaramps[3][256]; +static WORD currentgammaramps[3][256]; + +qboolean +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; +} + +#if 0 +static void +VID_SaveGamma (void) +{ + HDC hdc = GetDC (NULL); + + GetDeviceGammaRamp (hdc, &systemgammaramps[0][0]); + ReleaseDC (NULL, hdc); +} + +static void +VID_RestoreGamma (void) +{ + HDC hdc = GetDC (NULL); + + SetDeviceGammaRamp (hdc, &systemgammaramps[0][0]); + ReleaseDC (NULL, hdc); +} +#endif + +#define CVAR_ORIGINAL CVAR_NONE // FIXME +void +Win_Init_Cvars (void) +{ + vid_ddraw = Cvar_Get ("vid_ddraw", "1", CVAR_ORIGINAL, 0, ""); + vid_mode = Cvar_Get ("vid_mode", "0", CVAR_ORIGINAL, 0, ""); + vid_wait = Cvar_Get ("vid_wait", "0", CVAR_ORIGINAL, 0, ""); + vid_nopageflip = + Cvar_Get ("vid_nopageflip", "0", CVAR_ARCHIVE | CVAR_ORIGINAL, 0, ""); + _vid_wait_override = + Cvar_Get ("_vid_wait_override", "0", CVAR_ARCHIVE | CVAR_ORIGINAL, 0, + ""); + _vid_default_mode = + Cvar_Get ("_vid_default_mode", "0", CVAR_ARCHIVE | CVAR_ORIGINAL, 0, + ""); + _vid_default_mode_win = + Cvar_Get ("_vid_default_mode_win", "3", CVAR_ARCHIVE | CVAR_ORIGINAL, 0, + ""); + vid_config_x = + Cvar_Get ("vid_config_x", "800", CVAR_ARCHIVE | CVAR_ORIGINAL, 0, ""); + vid_config_y = + Cvar_Get ("vid_config_y", "600", CVAR_ARCHIVE | CVAR_ORIGINAL, 0, ""); + vid_stretch_by_2 = + Cvar_Get ("vid_stretch_by_2", "1", CVAR_ARCHIVE | CVAR_ORIGINAL, 0, ""); + _windowed_mouse = + Cvar_Get ("_windowed_mouse", "0", CVAR_ARCHIVE | CVAR_ORIGINAL, 0, ""); + vid_fullscreen_mode = + Cvar_Get ("vid_fullscreen_mode", "3", CVAR_ARCHIVE | CVAR_ORIGINAL, 0, + ""); + vid_windowed_mode = + Cvar_Get ("vid_windowed_mode", "0", CVAR_ARCHIVE | CVAR_ORIGINAL, 0, + ""); + block_switch = + Cvar_Get ("block_switch", "0", CVAR_ARCHIVE | CVAR_ORIGINAL, 0, ""); + vid_window_x = + Cvar_Get ("vid_window_x", "0", CVAR_ARCHIVE | CVAR_ORIGINAL, 0, ""); + vid_window_y = + Cvar_Get ("vid_window_y", "0", CVAR_ARCHIVE | CVAR_ORIGINAL, 0, ""); + + Cmd_AddCommand ("vid_testmode", VID_TestMode_f, ""); + Cmd_AddCommand ("vid_nummodes", VID_NumModes_f, ""); + Cmd_AddCommand ("vid_describecurrentmode", VID_DescribeCurrentMode_f, ""); + Cmd_AddCommand ("vid_describemode", VID_DescribeMode_f, ""); + Cmd_AddCommand ("vid_describemodes", VID_DescribeModes_f, ""); + Cmd_AddCommand ("vid_forcemode", VID_ForceMode_f, ""); + Cmd_AddCommand ("vid_windowed", VID_Windowed_f, ""); + Cmd_AddCommand ("vid_fullscreen", VID_Fullscreen_f, ""); + Cmd_AddCommand ("vid_minimize", VID_Minimize_f, ""); +} diff --git a/libs/video/targets/in_win.c b/libs/video/targets/in_win.c index cb54631f4..2a79681c3 100644 --- a/libs/video/targets/in_win.c +++ b/libs/video/targets/in_win.c @@ -46,6 +46,7 @@ #include "QF/sys.h" #include "compat.h" +#include "context_win.h" #include "in_win.h" #define DINPUT_BUFFERSIZE 16 @@ -55,9 +56,6 @@ HRESULT (WINAPI * pDirectInputCreate) (HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPUT * lplpDirectInput, LPUNKNOWN punkOuter); -extern qboolean win_canalttab; -extern DEVMODE win_gdevmode; - // mouse local variables static unsigned uiWheelMessage; static unsigned mouse_buttons; @@ -119,8 +117,6 @@ static DIDATAFORMAT df = { rgodf, // and here they are }; -// forward-referenced functions, joy - void IN_UpdateClipCursor (void) { @@ -168,7 +164,7 @@ IN_ActivateMouse (void) SystemParametersInfo (SPI_SETMOUSE, 0, newmouseparms, 0); SetCursorPos (window_center_x, window_center_y); - SetCapture (mainwindow); + SetCapture (win_mainwindow); ClipCursor (&window_rect); } @@ -255,7 +251,7 @@ IN_InitDInput (void) return false; } // set the cooperativity level. - hr = IDirectInputDevice_SetCooperativeLevel (g_pMouse, mainwindow, + hr = IDirectInputDevice_SetCooperativeLevel (g_pMouse, win_mainwindow, DISCL_EXCLUSIVE | DISCL_FOREGROUND); @@ -741,10 +737,10 @@ AppActivate (BOOL fActive, BOOL minimize) "(try upgrading your video drivers)\n (%lx)", GetLastError()); } - ShowWindow (mainwindow, SW_SHOWNORMAL); + ShowWindow (win_mainwindow, SW_SHOWNORMAL); // Fix for alt-tab bug in NVidia drivers - MoveWindow(mainwindow, 0, 0, win_gdevmode.dmPelsWidth, + MoveWindow(win_mainwindow, 0, 0, win_gdevmode.dmPelsWidth, win_gdevmode.dmPelsHeight, false); } } @@ -782,13 +778,13 @@ MainWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) switch (uMsg) { case WM_KILLFOCUS: if (modestate == MS_FULLDIB) - ShowWindow (mainwindow, SW_SHOWMINNOACTIVE); + ShowWindow (win_mainwindow, SW_SHOWMINNOACTIVE); break; case WM_CREATE: break; case WM_MOVE: - VID_UpdateWindowStatus ((int) LOWORD (lParam), + Win_UpdateWindowStatus ((int) LOWORD (lParam), (int) HIWORD (lParam)); break; @@ -848,7 +844,8 @@ MainWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case WM_CLOSE: if (MessageBox - (mainwindow, "Are you sure you want to quit?", "Confirm Exit", + (win_mainwindow, + "Are you sure you want to quit?", "Confirm Exit", MB_YESNO | MB_SETFOREGROUND | MB_ICONQUESTION) == IDYES) { Sys_Quit (); } @@ -864,8 +861,8 @@ MainWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) break; case WM_DESTROY: - if (mainwindow) - DestroyWindow (mainwindow); + if (win_mainwindow) + DestroyWindow (win_mainwindow); PostQuitMessage (0); break; diff --git a/libs/video/targets/vid_sdl.c b/libs/video/targets/vid_sdl.c index 738abbb4b..e71660cb6 100644 --- a/libs/video/targets/vid_sdl.c +++ b/libs/video/targets/vid_sdl.c @@ -51,7 +51,7 @@ #ifdef _WIN32 // FIXME: evil hack to get full DirectSound support with SDL #include #include -HWND mainwindow; +HWND win_mainwindow; #endif SDL_Surface *sdl_screen = NULL; @@ -116,7 +116,7 @@ VID_Init (byte *palette, byte *colormap) // SDL_GetWMInfo(&info); // mainwindow=info.window; - mainwindow=GetActiveWindow(); + win_mainwindow=GetActiveWindow(); #endif viddef.recalc_refdef = 1; // force a surface cache flush diff --git a/libs/video/targets/vid_sdl_sw.c b/libs/video/targets/vid_sdl_sw.c index 2d4f806d4..5a9a96b42 100644 --- a/libs/video/targets/vid_sdl_sw.c +++ b/libs/video/targets/vid_sdl_sw.c @@ -52,7 +52,6 @@ #ifdef _WIN32 // FIXME: evil hack to get full DirectSound support with SDL #include #include -HWND mainwindow; #endif // The original defaults @@ -95,7 +94,7 @@ sdl_update_palette (const byte *palette) } static void -VID_SetPalette (const byte *palette) +sdl_set_palette (const byte *palette) { if (memcmp (cached_palette, palette, sizeof (cached_palette))) { memcpy (cached_palette, palette, sizeof (cached_palette)); @@ -171,7 +170,7 @@ sw_ctx_t * SDL_SW_Context (void) { sw_ctx_t *ctx = calloc (1, sizeof (sw_ctx_t)); - ctx->set_palette = VID_SetPalette; + ctx->set_palette = sdl_set_palette; ctx->create_context = sdl_set_vid_mode; ctx->update = sdl_sw_update; return ctx; diff --git a/libs/video/targets/vid_win.c b/libs/video/targets/vid_win.c index af843eb05..fb4eeef96 100644 --- a/libs/video/targets/vid_win.c +++ b/libs/video/targets/vid_win.c @@ -28,1567 +28,26 @@ # include "config.h" #endif -#include "winquake.h" -#include - -#include "QF/cmd.h" -#include "QF/cvar.h" -#include "QF/input.h" -#include "QF/keys.h" -#include "QF/qargs.h" #include "QF/sys.h" #include "QF/va.h" #include "QF/vid.h" -#include "QF/GL/funcs.h" -#include "QF/GL/qf_vid.h" +#include "context_win.h" #include "d_iface.h" -#include "d_local.h" -#include "in_win.h" -#include "r_cvar.h" -#include "r_shared.h" #include "vid_internal.h" +#include "vid_sw.h" -// true if the ddraw driver started up OK -qboolean vid_usingddraw = false; - -// compatibility -HWND mainwindow = NULL; -qboolean win_canalttab = false; - -// main application window -HWND hWndWinQuake = NULL; -HDC maindc; -HGLRC baseRC; - -//FIXME?int yeahimconsoled; - -static void *libgl_handle; -static HGLRC (GLAPIENTRY * qfwglCreateContext) (HDC); -static BOOL (GLAPIENTRY * qfwglDeleteContext) (HGLRC); -static HGLRC (GLAPIENTRY * qfwglGetCurrentContext) (void); -static HDC (GLAPIENTRY * qfwglGetCurrentDC) (void); -static BOOL (GLAPIENTRY * qfwglMakeCurrent) (HDC, HGLRC); - -static void *(WINAPI * glGetProcAddress) (const char *symbol) = NULL; - -static void (*choose_visual) (void); -static void (*create_context) (const byte *palette); - -static void * -QFGL_GetProcAddress (void *handle, const char *name) -{ - void *glfunc = NULL; - - if (glGetProcAddress) - glfunc = glGetProcAddress (name); - if (!glfunc) - glfunc = GetProcAddress (handle, name); - return glfunc; -} - -static void * -QFGL_ProcAddress (const char *name, qboolean crit) -{ - void *glfunc = NULL; - - Sys_MaskPrintf (SYS_VID, "DEBUG: Finding symbol %s ... ", name); - - glfunc = QFGL_GetProcAddress (libgl_handle, name); - if (glfunc) { - Sys_MaskPrintf (SYS_VID, "found [%p]\n", glfunc); - return glfunc; - } - Sys_MaskPrintf (SYS_VID, "not found\n"); - - if (crit) { - Sys_Error ("Couldn't load critical OpenGL function %s, exiting...", - name); - } - return NULL; -} - -static void -GL_EndRendering (void) -{ - if (!scr_skipupdate) { - qfglFinish (); - SwapBuffers (maindc); - } - // handle the mouse state when windowed if that's changed - if (!vid_fullscreen->int_val) { - if (!in_grab->int_val) { -//FIXME if (windowed_mouse) { -//FIXME IN_DeactivateMouse (); -//FIXME IN_ShowMouse (); -//FIXME windowed_mouse = false; -//FIXME } - } else { -//FIXME windowed_mouse = true; - } - } -} - -static void -wgl_choose_visual (void) -{ -} - -static void -wgl_create_context (const byte *palette) -{ - DWORD lasterror; - - Sys_Printf ("maindc: %p\n", maindc); - baseRC = qfwglCreateContext (maindc); - if (!baseRC) { - lasterror=GetLastError(); - if (maindc && mainwindow) - ReleaseDC (mainwindow, maindc); - Sys_Error ("Could not initialize GL (wglCreateContext failed).\n\n" - "Make sure you are in 65535 color mode, and try running " - "with -window.\n" - "Error code: (%lx)", lasterror); - } - - if (!qfwglMakeCurrent (maindc, baseRC)) { - lasterror = GetLastError (); - if (baseRC) - qfwglDeleteContext (baseRC); - if (maindc && mainwindow) - ReleaseDC (mainwindow, maindc); - Sys_Error ("wglMakeCurrent failed (%lx)", lasterror); - } - - viddef.init_gl (); -} - -static void -wgl_load_gl (void) -{ - choose_visual = wgl_choose_visual; - create_context = wgl_create_context; - - viddef.get_proc_address = QFGL_ProcAddress; - viddef.end_rendering = GL_EndRendering; - - if (!(libgl_handle = LoadLibrary (gl_driver->string))) - Sys_Error ("Couldn't load OpenGL library %s!", gl_driver->string); - glGetProcAddress = - (void *) GetProcAddress (libgl_handle, "wglGetProcAddress"); - - qfwglCreateContext = QFGL_ProcAddress ("wglCreateContext", true); - qfwglDeleteContext = QFGL_ProcAddress ("wglDeleteContext", true); - qfwglGetCurrentContext = QFGL_ProcAddress ("wglGetCurrentContext", true); - qfwglGetCurrentDC = QFGL_ProcAddress ("wglGetCurrentDC", true); - qfwglMakeCurrent = QFGL_ProcAddress ("wglMakeCurrent", true); -} - - -/* -============================================================================= - - DIRECTDRAW VIDEO DRIVER - -============================================================================= -*/ - -LPDIRECTDRAW dd_Object = NULL; -HINSTANCE hInstDDraw = NULL; - -LPDIRECTDRAWSURFACE dd_FrontBuffer = NULL; -LPDIRECTDRAWSURFACE dd_BackBuffer = NULL; - -LPDIRECTDRAWCLIPPER dd_Clipper = NULL; - -typedef HRESULT (WINAPI * DIRECTDRAWCREATEPROC) (GUID FAR *, - LPDIRECTDRAW FAR *, - IUnknown FAR *); -DIRECTDRAWCREATEPROC QDirectDrawCreate = NULL; - -unsigned ddpal[256]; - -byte *vidbuf = NULL; - - -int dd_window_width = 640; -int dd_window_height = 480; -RECT SrcRect; -RECT DstRect; - -static void -DD_UpdateRects (int width, int height) -{ - POINT p; - - p.x = 0; - p.y = 0; - - // first we need to figure out where on the primary surface our window - // lives - ClientToScreen (hWndWinQuake, &p); - GetClientRect (hWndWinQuake, &DstRect); - OffsetRect (&DstRect, p.x, p.y); - SetRect (&SrcRect, 0, 0, width, height); -} - - -static void -VID_CreateDDrawDriver (int width, int height, const byte *palette, - void **buffer, int *rowbytes) -{ - HRESULT hr; - DDSURFACEDESC ddsd; - - vid_usingddraw = false; - dd_window_width = width; - dd_window_height = height; - - vidbuf = (byte *) malloc (width * height); - buffer[0] = vidbuf; - rowbytes[0] = width; - - if (!(hInstDDraw = LoadLibrary ("ddraw.dll"))) - return; - if (!(QDirectDrawCreate = - (DIRECTDRAWCREATEPROC) GetProcAddress (hInstDDraw, - "DirectDrawCreate"))) - return; - - if (FAILED (hr = QDirectDrawCreate (NULL, &dd_Object, NULL))) - return; - if (FAILED (hr = dd_Object->lpVtbl->SetCooperativeLevel (dd_Object, - hWndWinQuake, - DDSCL_NORMAL))) - return; - - // the primary surface in windowed mode is the full screen - memset (&ddsd, 0, sizeof (ddsd)); - ddsd.dwSize = sizeof (ddsd); - ddsd.dwFlags = DDSD_CAPS; - ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_VIDEOMEMORY; - - // ...and create it - if (FAILED (hr = dd_Object->lpVtbl->CreateSurface (dd_Object, &ddsd, - &dd_FrontBuffer, NULL))) - return; - - // not using a clipper will slow things down and switch aero off - if (FAILED (hr = IDirectDraw_CreateClipper (dd_Object, 0, &dd_Clipper, - NULL))) - return; - if (FAILED (hr = IDirectDrawClipper_SetHWnd (dd_Clipper, 0, hWndWinQuake))) - return; - if (FAILED (hr = IDirectDrawSurface_SetClipper (dd_FrontBuffer, - dd_Clipper))) - return; - - // the secondary surface is an offscreen surface that is the currect - // dimensions - // this will be blitted to the correct location on the primary surface - // (which is the full screen) during our draw op - memset (&ddsd, 0, sizeof (ddsd)); - ddsd.dwSize = sizeof (ddsd); - ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; - ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY; - ddsd.dwWidth = width; - ddsd.dwHeight = height; - - if (FAILED (hr = IDirectDraw_CreateSurface (dd_Object, &ddsd, - &dd_BackBuffer, NULL))) - return; - - // direct draw is working now - vid_usingddraw = true; - - // create a palette - VID_InitGamma (palette); - viddef.set_palette (palette); - - // create initial rects - DD_UpdateRects (dd_window_width, dd_window_height); -} - - -/* -===================================================================== - - GDI VIDEO DRIVER - -===================================================================== -*/ - -// common bitmap definition -typedef struct dibinfo { - BITMAPINFOHEADER header; - RGBQUAD acolors[256]; -} dibinfo_t; - - -static HGDIOBJ previously_selected_GDI_obj = NULL; -HBITMAP hDIBSection; -byte *pDIBBase = NULL; -HDC hdcDIBSection = NULL; -HDC hdcGDI = NULL; - - -static void -VID_CreateGDIDriver (int width, int height, const byte *palette, void **buffer, - int *rowbytes) -{ - dibinfo_t dibheader; - BITMAPINFO *pbmiDIB = (BITMAPINFO *) & dibheader; - int i; - - hdcGDI = GetDC (hWndWinQuake); - memset (&dibheader, 0, sizeof (dibheader)); - - // fill in the bitmap info - pbmiDIB->bmiHeader.biSize = sizeof (BITMAPINFOHEADER); - pbmiDIB->bmiHeader.biWidth = width; - pbmiDIB->bmiHeader.biHeight = height; - pbmiDIB->bmiHeader.biPlanes = 1; - pbmiDIB->bmiHeader.biCompression = BI_RGB; - pbmiDIB->bmiHeader.biSizeImage = 0; - pbmiDIB->bmiHeader.biXPelsPerMeter = 0; - pbmiDIB->bmiHeader.biYPelsPerMeter = 0; - pbmiDIB->bmiHeader.biClrUsed = 256; - pbmiDIB->bmiHeader.biClrImportant = 256; - pbmiDIB->bmiHeader.biBitCount = 8; - - // fill in the palette - for (i = 0; i < 256; i++) { - // d_8to24table isn't filled in yet so this is just for testing - dibheader.acolors[i].rgbRed = palette[i * 3]; - dibheader.acolors[i].rgbGreen = palette[i * 3 + 1]; - dibheader.acolors[i].rgbBlue = palette[i * 3 + 2]; - } - - // create the DIB section - hDIBSection = CreateDIBSection (hdcGDI, - pbmiDIB, - DIB_RGB_COLORS, - (void **) &pDIBBase, NULL, 0); - - // set video buffers - if (pbmiDIB->bmiHeader.biHeight > 0) { - // bottom up - buffer[0] = pDIBBase + (height - 1) * width; - rowbytes[0] = -width; - } else { - // top down - buffer[0] = pDIBBase; - rowbytes[0] = width; - } - - // clear the buffer - memset (pDIBBase, 0xff, width * height); - - if ((hdcDIBSection = CreateCompatibleDC (hdcGDI)) == NULL) - Sys_Error ("DIB_Init() - CreateCompatibleDC failed\n"); - - if ((previously_selected_GDI_obj = - SelectObject (hdcDIBSection, hDIBSection)) == NULL) - Sys_Error ("DIB_Init() - SelectObject failed\n"); - - // create a palette - VID_InitGamma (palette); - viddef.set_palette (palette); -} - - -static void -VID_UnloadAllDrivers (void) -{ - // shut down ddraw - if (vidbuf) { - free (vidbuf); - vidbuf = NULL; - } - - if (dd_Clipper) { - IDirectDrawClipper_Release (dd_Clipper); - dd_Clipper = NULL; - } - - if (dd_FrontBuffer) { - IDirectDrawSurface_Release (dd_FrontBuffer); - dd_FrontBuffer = NULL; - } - - if (dd_BackBuffer) { - IDirectDrawSurface_Release (dd_BackBuffer); - dd_BackBuffer = NULL; - } - - if (dd_Object) { - IDirectDraw_Release (dd_Object); - dd_Object = NULL; - } - - if (hInstDDraw) { - FreeLibrary (hInstDDraw); - hInstDDraw = NULL; - } - - QDirectDrawCreate = NULL; - - // shut down gdi - if (hdcDIBSection) { - SelectObject (hdcDIBSection, previously_selected_GDI_obj); - DeleteDC (hdcDIBSection); - hdcDIBSection = NULL; - } - - if (hDIBSection) { - DeleteObject (hDIBSection); - hDIBSection = NULL; - pDIBBase = NULL; - } - - if (hdcGDI) { - // if hdcGDI exists then hWndWinQuake must also be valid - ReleaseDC (hWndWinQuake, hdcGDI); - hdcGDI = NULL; - } - // not using ddraw now - vid_usingddraw = false; -} - - - -// compatibility -qboolean DDActive; - -// not used any more -void -VID_LockBuffer (void) -{ -} - -void -VID_UnlockBuffer (void) -{ -} - -//static int VID_ForceUnlockedAndReturnState (void) {return 0;} -void -VID_ForceLockState (int lk) -{ -} - - -#define MAX_MODE_LIST 36 -#define VID_ROW_SIZE 3 - -extern qboolean Minimized; - -HWND WINAPI InitializeWindow (HINSTANCE hInstance, int nCmdShow); - -int DIBWidth, DIBHeight; -RECT WindowRect; -DWORD WindowStyle, ExWindowStyle; - -int window_center_x, window_center_y, window_width, window_height; -RECT window_rect; - -DEVMODE win_gdevmode; -static qboolean startwindowed = 0, windowed_mode_set; -static int firstupdate = 1; -static qboolean vid_initialized = false, vid_palettized; -static int vid_fulldib_on_focus_mode; -static qboolean force_minimized, in_mode_set, force_mode_set; -static int windowed_mouse; -static qboolean palette_changed, vid_mode_set; -static HICON hIcon; - -#define MODE_WINDOWED 0 -#define MODE_SETTABLE_WINDOW 2 -#define NO_MODE (MODE_WINDOWED - 1) -#define MODE_FULLSCREEN_DEFAULT (MODE_WINDOWED + 3) - -cvar_t *vid_ddraw; - -// Note that 0 is MODE_WINDOWED -cvar_t *vid_mode; - -// Note that 0 is MODE_WINDOWED -cvar_t *_vid_default_mode; - -// Note that 3 is MODE_FULLSCREEN_DEFAULT -cvar_t *_vid_default_mode_win; -cvar_t *vid_wait; -cvar_t *vid_nopageflip; -cvar_t *_vid_wait_override; -cvar_t *vid_config_x; -cvar_t *vid_config_y; -cvar_t *vid_stretch_by_2; -cvar_t *_windowed_mouse; -cvar_t *vid_fullscreen_mode; -cvar_t *vid_windowed_mode; -cvar_t *block_switch; -cvar_t *vid_window_x; -cvar_t *vid_window_y; - - -int vid_modenum = NO_MODE; -int vid_testingmode, vid_realmode; -double vid_testendtime; -int vid_default = MODE_WINDOWED; -static int windowed_default; - -modestate_t modestate = MS_UNINIT; - -byte vid_curpal[256 * 3]; - -unsigned short d_8to16table[256]; - -int mode; - -typedef struct { - modestate_t type; - int width; - int height; - int modenum; - int fullscreen; - char modedesc[13]; -} vmode_t; - -static vmode_t modelist[MAX_MODE_LIST]; -static int nummodes; - -int aPage; // Current active display page -int vPage; // Current visible display page -int waitVRT = true; // True to wait for retrace on flip - -static vmode_t badmode; +static vid_internal_t vid_internal; static byte backingbuf[48 * 24]; -void VID_MenuDraw (void); -void VID_MenuKey (int key); - -LONG WINAPI MainWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); -void AppActivate (BOOL fActive, BOOL minimize); - -static int VID_SetMode (int modenum, const byte *palette); - -// video commands -int VID_NumModes (void); -vmode_t *VID_GetModePtr (int modenum); -void VID_TestMode_f (void); -void VID_ForceMode_f (void); -void VID_Minimize_f (void); -void VID_Fullscreen_f (void); -void VID_Windowed_f (void); -void VID_DescribeModes_f (void); -void VID_DescribeMode_f (void); -void VID_NumModes_f (void); -void VID_DescribeCurrentMode_f (void); -char *VID_GetExtModeDescription (int mode); -char *VID_GetModeDescription (int mode); -char *VID_GetModeDescription2 (int mode); -char *VID_GetModeDescriptionMemCheck (int mode); -void VID_CheckModedescFixup (int mode); - - -/* -================ -VID_RememberWindowPos -================ -*/ -static void __attribute__ ((used)) -VID_RememberWindowPos (void) -{ - RECT rect; - - if (GetWindowRect (hWndWinQuake, &rect)) { - if ((rect.left < GetSystemMetrics (SM_CXSCREEN)) && - (rect.top < GetSystemMetrics (SM_CYSCREEN)) && - (rect.right > 0) && (rect.bottom > 0)) { - Cvar_SetValue (vid_window_x, (float) rect.left); - Cvar_SetValue (vid_window_y, (float) rect.top); - } - } -} - - -/* -================ -VID_CheckWindowXY -================ -*/ -static void -VID_CheckWindowXY (void) -{ - if ((vid_window_x->int_val > (GetSystemMetrics (SM_CXSCREEN) - 160)) || - (vid_window_y->int_val > (GetSystemMetrics (SM_CYSCREEN) - 120)) || - (vid_window_x->int_val < 0) || (vid_window_y->int_val < 0)) { - Cvar_SetValue (vid_window_x, 0.0); - Cvar_SetValue (vid_window_y, 0.0); - } -} - - -/* -================ -VID_UpdateWindowStatus -================ -*/ -void -VID_UpdateWindowStatus (int window_x, int window_y) -{ - window_rect.left = window_x; - window_rect.top = window_y; - window_rect.right = window_x + window_width; - window_rect.bottom = window_y + window_height; - window_center_x = (window_rect.left + window_rect.right) / 2; - window_center_y = (window_rect.top + window_rect.bottom) / 2; - IN_UpdateClipCursor (); -} - - -/* -================ -ClearAllStates -================ -*/ -static void -ClearAllStates (void) -{ - int i; - - // send an up event for each key, to make sure the server clears them all - for (i = 0; i < 256; i++) { - Key_Event (i, 0, false); - } - - Key_ClearStates (); - IN_ClearStates (); -} - - -/* -================ -VID_CheckAdequateMem -================ -*/ -static qboolean -VID_CheckAdequateMem (int width, int height) -{ - // there will always be enough ;) - return true; -} - - -static void -VID_InitModes (HINSTANCE hInstance) -{ - WNDCLASS wc; - HDC hdc; - -//FIXME hIcon = LoadIcon (hInstance, MAKEINTRESOURCE (IDI_ICON2)); - - /* Register the frame class */ - wc.style = CS_OWNDC; - wc.lpfnWndProc = (WNDPROC) MainWndProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = hInstance; - wc.hIcon = 0; - wc.hCursor = LoadCursor (NULL, IDC_ARROW); - wc.hbrBackground = NULL; - wc.lpszMenuName = 0; - wc.lpszClassName = "WinQuake"; - - if (!RegisterClass (&wc)) - Sys_Error ("Couldn't register window class"); - - modelist[0].type = MS_WINDOWED; - modelist[0].width = 320; - modelist[0].height = 240; - strcpy (modelist[0].modedesc, "320x240"); - modelist[0].modenum = MODE_WINDOWED; - modelist[0].fullscreen = 0; - - modelist[1].type = MS_WINDOWED; - modelist[1].width = 640; - modelist[1].height = 480; - strcpy (modelist[1].modedesc, "640x480"); - modelist[1].modenum = MODE_WINDOWED + 1; - modelist[1].fullscreen = 0; - - modelist[2].type = MS_WINDOWED; - modelist[2].width = 800; - modelist[2].height = 600; - strcpy (modelist[2].modedesc, "800x600"); - modelist[2].modenum = MODE_WINDOWED + 2; - modelist[2].fullscreen = 0; - - // automatically stretch the default mode up if > 640x480 desktop - // resolution - hdc = GetDC (NULL); - - if ((GetDeviceCaps (hdc, HORZRES) > 800) - && !COM_CheckParm ("-noautostretch")) { - vid_default = MODE_WINDOWED + 2; - } else if ((GetDeviceCaps (hdc, HORZRES) > 640) - && !COM_CheckParm ("-noautostretch")) { - vid_default = MODE_WINDOWED + 1; - } else { - vid_default = MODE_WINDOWED; - } - - // always start at the lowest mode then switch to the higher one if - // selected - vid_default = MODE_WINDOWED; - - windowed_default = vid_default; - ReleaseDC (NULL, hdc); - nummodes = 3; // reserve space for windowed mode -} - - -/* -================= -VID_GetDisplayModes -================= -*/ -static void -VID_GetDisplayModes (void) -{ - DEVMODE devmode; - int i, modenum, existingmode, originalnummodes, lowestres; - BOOL stat; - - // enumerate > 8 bpp modes - originalnummodes = nummodes; - modenum = 0; - lowestres = 99999; - - do { - stat = EnumDisplaySettings (NULL, modenum, &devmode); - - if ((devmode.dmPelsWidth <= MAXWIDTH) - && (devmode.dmPelsHeight <= MAXHEIGHT) - && (devmode.dmPelsWidth >= 320) - && (devmode.dmPelsHeight >= 240) - && (nummodes < MAX_MODE_LIST)) { - devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; - - if (ChangeDisplaySettings (&devmode, CDS_TEST | CDS_FULLSCREEN) == - DISP_CHANGE_SUCCESSFUL) { - modelist[nummodes].type = MS_FULLDIB; - modelist[nummodes].width = devmode.dmPelsWidth; - modelist[nummodes].height = devmode.dmPelsHeight; - modelist[nummodes].modenum = 0; - modelist[nummodes].fullscreen = 1; - sprintf (modelist[nummodes].modedesc, "%dx%d", - (int) devmode.dmPelsWidth, - (int) devmode.dmPelsHeight); - - // see is the mode already there - // (same dimensions but different refresh rate) - for (i = originalnummodes, existingmode = 0; - i < nummodes; i++) { - if ((modelist[nummodes].width == modelist[i].width) - && (modelist[nummodes].height == modelist[i].height)) { - existingmode = 1; - break; - } - } - - // if it's not add it to the list - if (!existingmode) { - if (modelist[nummodes].width < lowestres) - lowestres = modelist[nummodes].width; - - nummodes++; - } - } - } - - modenum++; - } while (stat); - - if (nummodes != originalnummodes) - vid_default = MODE_FULLSCREEN_DEFAULT; - else - Sys_Printf ("No fullscreen DIB modes found\n"); -} - -static void -WIN_OpenDisplay (void) -{ - VID_InitModes (global_hInstance); - VID_GetDisplayModes (); - - vid_testingmode = 0; - - // if (COM_CheckParm("-startwindowed")) - { - startwindowed = 1; - vid_default = windowed_default; - } - -//FIXME? if (hwnd_dialog) -//FIXME? DestroyWindow (hwnd_dialog); - - // 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 - hWndWinQuake = CreateWindowEx (ExWindowStyle, - "WinQuake", - "WinQuake", - WindowStyle, - 0, 0, - WindowRect.right - WindowRect.left, - WindowRect.bottom - WindowRect.top, - NULL, NULL, global_hInstance, NULL); - - if (!hWndWinQuake) - Sys_Error ("Couldn't create DIB window"); - - // compatibility - mainwindow = hWndWinQuake; - - // done - vid_mode_set = true; -//FIXME if (firsttime) S_Init (); -} - -static void -WIN_SetVidMode (unsigned width, unsigned height, const byte *palette) -{ -//FIXME SCR_StretchInit(); - - force_mode_set = true; - VID_SetMode (vid_default, palette); - force_mode_set = false; - vid_realmode = vid_modenum; - strcpy (badmode.modedesc, "Bad mode"); -} - -static void -VID_DestroyWindow (void) -{ - if (modestate == MS_FULLDIB) - ChangeDisplaySettings (NULL, CDS_FULLSCREEN); - - VID_UnloadAllDrivers (); -} - - -static qboolean -VID_SetWindowedMode (int modenum) -{ - if (!windowed_mode_set) { - if (COM_CheckParm ("-resetwinpos")) { - Cvar_SetValue (vid_window_x, 0.0); - Cvar_SetValue (vid_window_y, 0.0); - } - - windowed_mode_set = true; - } - - VID_CheckModedescFixup (modenum); - VID_DestroyWindow (); - - WindowRect.top = WindowRect.left = 0; - WindowRect.right = modelist[modenum].width; - WindowRect.bottom = modelist[modenum].height; - DIBWidth = modelist[modenum].width; - DIBHeight = modelist[modenum].height; - - WindowStyle = WS_OVERLAPPEDWINDOW | WS_CAPTION | WS_SYSMENU | WS_SIZEBOX | - WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_CLIPSIBLINGS | - WS_CLIPCHILDREN | WS_THICKFRAME; - - // WindowStyle = WS_OVERLAPPEDWINDOW|WS_VISIBLE; - ExWindowStyle = 0; - AdjustWindowRectEx (&WindowRect, WindowStyle, FALSE, 0); - - // the first time we're called to set the mode, create the window we'll use - // for the rest of the session - if (!vid_mode_set) { - } else { - SetWindowLong (hWndWinQuake, GWL_STYLE, WindowStyle | WS_VISIBLE); - SetWindowLong (hWndWinQuake, GWL_EXSTYLE, ExWindowStyle); - } - - if (!SetWindowPos (hWndWinQuake, - NULL, - 0, 0, - WindowRect.right - WindowRect.left, - WindowRect.bottom - WindowRect.top, - SWP_NOCOPYBITS | SWP_NOZORDER | SWP_HIDEWINDOW)) { - Sys_Error ("Couldn't resize DIB window"); - } - - // position and show the DIB window - VID_CheckWindowXY (); - SetWindowPos (hWndWinQuake, NULL, vid_window_x->int_val, - vid_window_y->int_val, 0, 0, - SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW | SWP_DRAWFRAME); - - if (force_minimized) - ShowWindow (hWndWinQuake, SW_MINIMIZE); - else - ShowWindow (hWndWinQuake, SW_SHOWDEFAULT); - - UpdateWindow (hWndWinQuake); - modestate = MS_WINDOWED; - vid_fulldib_on_focus_mode = 0; - - viddef.numpages = 1; - -// viddef.height = viddef.conheight = DIBHeight; -// viddef.width = viddef.conwidth = DIBWidth; - - viddef.height = viddef.conheight = DIBHeight; - viddef.width = viddef.conwidth = DIBWidth; -//FIXME? if (!yeahimconsoled){ -//FIXME? viddef.vconheight = DIBHeight; -//FIXME? viddef.vconwidth = DIBWidth; -//FIXME? } - SendMessage (hWndWinQuake, WM_SETICON, (WPARAM) TRUE, (LPARAM) hIcon); - SendMessage (hWndWinQuake, WM_SETICON, (WPARAM) FALSE, (LPARAM) hIcon); - - return true; -} - - -static qboolean -VID_SetFullDIBMode (int modenum) -{ - VID_DestroyWindow (); - - win_gdevmode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT; - win_gdevmode.dmPelsWidth = modelist[modenum].width; - win_gdevmode.dmPelsHeight = modelist[modenum].height; - win_gdevmode.dmSize = sizeof (win_gdevmode); - - if (ChangeDisplaySettings (&win_gdevmode, CDS_FULLSCREEN) != - DISP_CHANGE_SUCCESSFUL) - Sys_Error ("Couldn't set fullscreen DIB mode"); - - modestate = MS_FULLDIB; - vid_fulldib_on_focus_mode = modenum; - WindowRect.top = WindowRect.left = 0; - - WindowRect.right = modelist[modenum].width; - WindowRect.bottom = modelist[modenum].height; - - DIBWidth = modelist[modenum].width; - DIBHeight = modelist[modenum].height; - - WindowStyle = WS_POPUP | WS_SYSMENU | WS_CLIPSIBLINGS | WS_CLIPCHILDREN; - ExWindowStyle = 0; - - AdjustWindowRectEx (&WindowRect, WindowStyle, FALSE, 0); - - SetWindowLong (hWndWinQuake, GWL_STYLE, WindowStyle | WS_VISIBLE); - SetWindowLong (hWndWinQuake, GWL_EXSTYLE, ExWindowStyle); - - if (!SetWindowPos (hWndWinQuake, - NULL, - 0, 0, - WindowRect.right - WindowRect.left, - WindowRect.bottom - WindowRect.top, - SWP_NOCOPYBITS | SWP_NOZORDER)) { - Sys_Error ("Couldn't resize DIB window"); - } - // position and show the DIB window - SetWindowPos (hWndWinQuake, HWND_TOPMOST, 0, 0, 0, 0, - SWP_NOSIZE | SWP_SHOWWINDOW | SWP_DRAWFRAME); - ShowWindow (hWndWinQuake, SW_SHOWDEFAULT); - UpdateWindow (hWndWinQuake); - - viddef.numpages = 1; - -#ifdef SCALED2D - viddef.height = viddef.conheight = DIBHeight; - viddef.width = viddef.conwidth = DIBWidth; - // viddef.vconwidth = 320; - // viddef.vconheight = 200; -//FIXME? if (!yeahimconsoled){ -//FIXME? viddef.vconheight = DIBHeight; -//FIXME? viddef.vconwidth = DIBWidth; -//FIXME? } -#else - viddef.height = viddef.conheight = DIBHeight; - viddef.width = viddef.conwidth = DIBWidth; -#endif - - return true; -} - -static void -VID_RestoreOldMode (int original_mode) -{ - static qboolean inerror = false; - - if (inerror) - return; - - in_mode_set = false; - inerror = true; - // make sure mode set happens (video mode changes) - vid_modenum = original_mode - 1; - - if (!VID_SetMode (original_mode, vid_curpal)) { - vid_modenum = MODE_WINDOWED - 1; - - if (!VID_SetMode (windowed_default, vid_curpal)) - Sys_Error ("Can't set any video mode"); - } - - inerror = false; -} - - -static void __attribute__ ((used)) -VID_SetDefaultMode (void) -{ - if (vid_initialized) - VID_SetMode (0, vid_curpal); - - IN_DeactivateMouse (); -} - -static void -win_init_bufers (void) -{ - // set the rest of the buffers we need (why not just use one single buffer - // instead of all this crap? oh well, it's Quake...) - viddef.direct = (byte *) viddef.buffer; - viddef.conbuffer = viddef.buffer; - - // more crap for the console - viddef.conrowbytes = viddef.rowbytes; -} - -static int -VID_SetMode (int modenum, const byte *palette) -{ - int original_mode; // FIXME, temp; - qboolean stat; - MSG msg; - HDC hdc; - - while ((modenum >= nummodes) || (modenum < 0)) { - if (vid_modenum == NO_MODE) { - if (modenum == vid_default) { - modenum = windowed_default; - } else { - modenum = vid_default; - } - - Cvar_SetValue (vid_mode, (float) modenum); - } else { - Cvar_SetValue (vid_mode, (float) vid_modenum); - return 0; - } - } - - if (!force_mode_set && (modenum == vid_modenum)) - return true; - - // so Con_Printfs don't mess us up by forcing vid and snd updates -//FIXME? temp = scr_disabled_for_loading; -//FIXME? scr_disabled_for_loading = true; - in_mode_set = true; -//FIXME CDAudio_Pause (); -//FIXME S_ClearBuffer (); - - if (vid_modenum == NO_MODE) - original_mode = windowed_default; - else - original_mode = vid_modenum; - - // Set either the fullscreen or windowed mode - if (modelist[modenum].type == MS_WINDOWED) { - if (_windowed_mouse->int_val) { - stat = VID_SetWindowedMode (modenum); - IN_ActivateMouse (); - IN_HideMouse (); - } else { - IN_DeactivateMouse (); - IN_ShowMouse (); - stat = VID_SetWindowedMode (modenum); - } - } else { - stat = VID_SetFullDIBMode (modenum); - IN_ActivateMouse (); - IN_HideMouse (); - } - - window_width = viddef.width; - window_height = viddef.height; - - - VID_UpdateWindowStatus (0, 0); // FIXME right numbers? -//FIXME CDAudio_Resume (); -//FIXME? scr_disabled_for_loading = temp; - - if (!stat) { - VID_RestoreOldMode (original_mode); - return false; - } - - // now we try to make sure we get the focus on the mode switch, because - // sometimes in some systems we don't. We grab the foreground, then - // finish setting up, pump all our messages, and sleep for a little while - // to let messages finish bouncing around the system, then we put - // ourselves at the top of the z order, then grab the foreground again, - // Who knows if it helps, but it probably doesn't hurt - if (!force_minimized) - SetForegroundWindow (hWndWinQuake); - - hdc = GetDC (NULL); - - if (GetDeviceCaps (hdc, RASTERCAPS) & RC_PALETTE) - vid_palettized = true; - else - vid_palettized = false; - - viddef.set_palette (palette); - ReleaseDC (NULL, hdc); - vid_modenum = modenum; - Cvar_SetValue (vid_mode, (float) vid_modenum); - - while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) { - TranslateMessage (&msg); - DispatchMessage (&msg); - } - - Sleep (100); - - if (!force_minimized) { - SetWindowPos (hWndWinQuake, HWND_TOP, 0, 0, 0, 0, - SWP_DRAWFRAME | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW | - SWP_NOCOPYBITS); - - SetForegroundWindow (hWndWinQuake); - } - // fix the leftover Alt from any Alt-Tab or the like that switched us away - ClearAllStates (); - - Sys_Printf ("%s\n", VID_GetModeDescription (vid_modenum)); - - viddef.set_palette (palette); - - in_mode_set = false; - - viddef.recalc_refdef = 1; - -//FIXME SCR_StretchInit(); -//FIXME SCR_StretchRefresh(); -//FIXME SCR_CvarCheck(); - return true; -} - - -static void -VID_SetPalette (const byte *palette) -{ - int i; - const byte *pal = palette; - - if (!Minimized) { - if (vid_usingddraw) { - // incoming palette is 3 component - for (i = 0; i < 256; i++, pal += 3) { - PALETTEENTRY *p = (PALETTEENTRY *) & ddpal[i]; - - p->peRed = viddef.gammatable[pal[2]]; - p->peGreen = viddef.gammatable[pal[1]]; - p->peBlue = viddef.gammatable[pal[0]]; - p->peFlags = 255; - } - } else { - RGBQUAD colors[256]; - - if (hdcDIBSection) { - // incoming palette is 3 component - for (i = 0; i < 256; i++, pal += 3) { - PALETTEENTRY *p = (PALETTEENTRY *) & ddpal[i]; - - colors[i].rgbRed = viddef.gammatable[pal[0]]; - colors[i].rgbGreen = viddef.gammatable[pal[1]]; - colors[i].rgbBlue = viddef.gammatable[pal[2]]; - colors[i].rgbReserved = 0; - - p->peRed = viddef.gammatable[pal[2]]; - p->peGreen = viddef.gammatable[pal[1]]; - p->peBlue = viddef.gammatable[pal[0]]; - p->peFlags = 255; - } - - colors[0].rgbRed = 0; - colors[0].rgbGreen = 0; - colors[0].rgbBlue = 0; - colors[255].rgbRed = 0xff; - colors[255].rgbGreen = 0xff; - colors[255].rgbBlue = 0xff; - - if (SetDIBColorTable (hdcDIBSection, 0, 256, colors) == 0) { - Sys_Printf ("DIB_SetPalette() - SetDIBColorTable failed\n"); - } - } - } - } - - memcpy (vid_curpal, palette, sizeof (vid_curpal)); -} - - -#define CVAR_ORIGINAL CVAR_NONE // FIXME -void -VID_Init_Cvars (void) -{ - gl_driver = Cvar_Get ("gl_driver", GL_DRIVER, CVAR_ROM, NULL, - "The OpenGL library to use. (path optional)"); - vid_ddraw = Cvar_Get ("vid_ddraw", "1", CVAR_ORIGINAL, 0, ""); - vid_mode = Cvar_Get ("vid_mode", "0", CVAR_ORIGINAL, 0, ""); - vid_wait = Cvar_Get ("vid_wait", "0", CVAR_ORIGINAL, 0, ""); - vid_nopageflip = - Cvar_Get ("vid_nopageflip", "0", CVAR_ARCHIVE | CVAR_ORIGINAL, 0, ""); - _vid_wait_override = - Cvar_Get ("_vid_wait_override", "0", CVAR_ARCHIVE | CVAR_ORIGINAL, 0, - ""); - _vid_default_mode = - Cvar_Get ("_vid_default_mode", "0", CVAR_ARCHIVE | CVAR_ORIGINAL, 0, - ""); - _vid_default_mode_win = - Cvar_Get ("_vid_default_mode_win", "3", CVAR_ARCHIVE | CVAR_ORIGINAL, 0, - ""); - vid_config_x = - Cvar_Get ("vid_config_x", "800", CVAR_ARCHIVE | CVAR_ORIGINAL, 0, ""); - vid_config_y = - Cvar_Get ("vid_config_y", "600", CVAR_ARCHIVE | CVAR_ORIGINAL, 0, ""); - vid_stretch_by_2 = - Cvar_Get ("vid_stretch_by_2", "1", CVAR_ARCHIVE | CVAR_ORIGINAL, 0, ""); - _windowed_mouse = - Cvar_Get ("_windowed_mouse", "0", CVAR_ARCHIVE | CVAR_ORIGINAL, 0, ""); - vid_fullscreen_mode = - Cvar_Get ("vid_fullscreen_mode", "3", CVAR_ARCHIVE | CVAR_ORIGINAL, 0, - ""); - vid_windowed_mode = - Cvar_Get ("vid_windowed_mode", "0", CVAR_ARCHIVE | CVAR_ORIGINAL, 0, - ""); - block_switch = - Cvar_Get ("block_switch", "0", CVAR_ARCHIVE | CVAR_ORIGINAL, 0, ""); - vid_window_x = - Cvar_Get ("vid_window_x", "0", CVAR_ARCHIVE | CVAR_ORIGINAL, 0, ""); - vid_window_y = - Cvar_Get ("vid_window_y", "0", CVAR_ARCHIVE | CVAR_ORIGINAL, 0, ""); -} - -static void -win_choose_visual (void) -{ -} - -static void -win_create_context (const byte *palette) -{ - HDC hdc; - - // shutdown any old driver that was active - VID_UnloadAllDrivers (); - - // because we have set the background brush for the window to NULL (to - // avoid flickering when re-sizing the window on the desktop), we clear - // the window to black when created, otherwise it will be empty while - // Quake starts up. This also prevents a screen flash to white when - // switching drivers. it still flashes, but at least it's black now - hdc = GetDC (hWndWinQuake); - PatBlt (hdc, 0, 0, WindowRect.right, WindowRect.bottom, BLACKNESS); - ReleaseDC (hWndWinQuake, hdc); - - // create the new driver - vid_usingddraw = false; - - // attempt to create a direct draw driver - if (vid_ddraw->int_val) - VID_CreateDDrawDriver (DIBWidth, DIBHeight, palette, &viddef.buffer, - &viddef.rowbytes); - - // create a gdi driver if directdraw failed or if we preferred not to use - // it - if (!vid_usingddraw) { - // because directdraw may have been partially created we must shut it - // down again first - VID_UnloadAllDrivers (); - - // now create the gdi driver - VID_CreateGDIDriver (DIBWidth, DIBHeight, palette, &viddef.buffer, - &viddef.rowbytes); - } - // if ddraw failed to come up we disable the cvar too - if (vid_ddraw->int_val && !vid_usingddraw) - Cvar_Set (vid_ddraw, "0"); - - viddef.do_screen_buffer = win_init_bufers; - VID_InitBuffers (); -} - -void -VID_Init (byte *palette, byte *colormap) -{ - Sys_RegisterShutdown (VID_shutdown); - - choose_visual = win_choose_visual; - create_context = win_create_context; - - R_LoadModule (wgl_load_gl, VID_SetPalette); - - viddef.numpages = 1; - viddef.colormap8 = colormap; - viddef.fullbright = 256 - viddef.colormap8[256 * VID_GRADES]; - - VID_GetWindowSize (640, 480); - WIN_OpenDisplay (); - choose_visual (); - WIN_SetVidMode (viddef.width, viddef.height, palette); - create_context (palette); - - VID_InitGamma (palette); - viddef.set_palette (palette); - - vid_initialized = true; -} - -#if 0 -Cmd_AddCommand ("vid_testmode", VID_TestMode_f, ""); -Cmd_AddCommand ("vid_nummodes", VID_NumModes_f, ""); -Cmd_AddCommand ("vid_describecurrentmode", VID_DescribeCurrentMode_f, ""); -Cmd_AddCommand ("vid_describemode", VID_DescribeMode_f, ""); -Cmd_AddCommand ("vid_describemodes", VID_DescribeModes_f, ""); -Cmd_AddCommand ("vid_forcemode", VID_ForceMode_f, ""); -Cmd_AddCommand ("vid_windowed", VID_Windowed_f, ""); -Cmd_AddCommand ("vid_fullscreen", VID_Fullscreen_f, ""); -Cmd_AddCommand ("vid_minimize", VID_Minimize_f, ""); -#endif - - -static void -VID_shutdown (void) -{ - if (vid_initialized) { - if (modestate == MS_FULLDIB) - ChangeDisplaySettings (NULL, CDS_FULLSCREEN); - - PostMessage (HWND_BROADCAST, WM_PALETTECHANGED, (WPARAM) hWndWinQuake, - (LPARAM) 0); - PostMessage (HWND_BROADCAST, WM_SYSCOLORCHANGE, (WPARAM) 0, (LPARAM) 0); - AppActivate (false, false); - - VID_DestroyWindow (); - -//FIXME? if (hwnd_dialog) DestroyWindow (hwnd_dialog); - if (hWndWinQuake) - DestroyWindow (hWndWinQuake); - - vid_testingmode = 0; - vid_initialized = 0; - } -} - - -/* -================ -FlipScreen -================ -*/ -static void -FlipScreen (vrect_t *rects) -{ - int numrects = 0; - - while (rects) { - if (vid_usingddraw) { - int x, y; - HRESULT hr = S_OK; - byte *src = NULL; - unsigned *dst = NULL; - - if (dd_BackBuffer) { - RECT TheRect; - RECT sRect, dRect; - DDSURFACEDESC ddsd; - - memset (&ddsd, 0, sizeof (ddsd)); - ddsd.dwSize = sizeof (DDSURFACEDESC); - - // lock the correct subrect - TheRect.left = rects->x; - TheRect.right = rects->x + rects->width; - TheRect.top = rects->y; - TheRect.bottom = rects->y + rects->height; - - if ((hr = - IDirectDrawSurface_Lock (dd_BackBuffer, &TheRect, &ddsd, - DDLOCK_WRITEONLY | - DDLOCK_SURFACEMEMORYPTR, - NULL)) == DDERR_WASSTILLDRAWING) - return; - - src = (byte *) vidbuf + rects->y * viddef.rowbytes + rects->x; - dst = (unsigned *) ddsd.lpSurface; - - // convert pitch to unsigned int addressable - ddsd.lPitch >>= 2; - - // because we created a 32 bit backbuffer we need to copy from - // the 8 bit memory buffer to it before flipping - if (!(rects->width & 15)) { - for (y = 0; y < rects->height; - y++, src += viddef.rowbytes, dst += ddsd.lPitch) { - byte *psrc = src; - unsigned *pdst = dst; - - for (x = 0; x < rects->width; - x += 16, psrc += 16, pdst += 16) { - pdst[0] = ddpal[psrc[0]]; - pdst[1] = ddpal[psrc[1]]; - pdst[2] = ddpal[psrc[2]]; - pdst[3] = ddpal[psrc[3]]; - - pdst[4] = ddpal[psrc[4]]; - pdst[5] = ddpal[psrc[5]]; - pdst[6] = ddpal[psrc[6]]; - pdst[7] = ddpal[psrc[7]]; - - pdst[8] = ddpal[psrc[8]]; - pdst[9] = ddpal[psrc[9]]; - pdst[10] = ddpal[psrc[10]]; - pdst[11] = ddpal[psrc[11]]; - - pdst[12] = ddpal[psrc[12]]; - pdst[13] = ddpal[psrc[13]]; - pdst[14] = ddpal[psrc[14]]; - pdst[15] = ddpal[psrc[15]]; - } - } - } else if (!(rects->width % 10)) { - for (y = 0; y < rects->height; - y++, src += viddef.rowbytes, dst += ddsd.lPitch) { - byte *psrc = src; - unsigned *pdst = dst; - - for (x = 0; x < rects->width; - x += 10, psrc += 10, pdst += 10) { - pdst[0] = ddpal[psrc[0]]; - pdst[1] = ddpal[psrc[1]]; - pdst[2] = ddpal[psrc[2]]; - pdst[3] = ddpal[psrc[3]]; - pdst[4] = ddpal[psrc[4]]; - - pdst[5] = ddpal[psrc[5]]; - pdst[6] = ddpal[psrc[6]]; - pdst[7] = ddpal[psrc[7]]; - pdst[8] = ddpal[psrc[8]]; - pdst[9] = ddpal[psrc[9]]; - } - } - } else if (!(rects->width & 7)) { - for (y = 0; y < rects->height; - y++, src += viddef.rowbytes, dst += ddsd.lPitch) { - byte *psrc = src; - unsigned *pdst = dst; - - for (x = 0; x < rects->width; - x += 8, psrc += 8, pdst += 8) { - pdst[0] = ddpal[psrc[0]]; - pdst[1] = ddpal[psrc[1]]; - pdst[2] = ddpal[psrc[2]]; - pdst[3] = ddpal[psrc[3]]; - - pdst[4] = ddpal[psrc[4]]; - pdst[5] = ddpal[psrc[5]]; - pdst[6] = ddpal[psrc[6]]; - pdst[7] = ddpal[psrc[7]]; - } - } - } else if (!(rects->width % 5)) { - for (y = 0; y < rects->height; - y++, src += viddef.rowbytes, dst += ddsd.lPitch) { - byte *psrc = src; - unsigned *pdst = dst; - - for (x = 0; x < rects->width; - x += 5, psrc += 5, pdst += 5) { - pdst[0] = ddpal[psrc[0]]; - pdst[1] = ddpal[psrc[1]]; - pdst[2] = ddpal[psrc[2]]; - pdst[3] = ddpal[psrc[3]]; - pdst[4] = ddpal[psrc[4]]; - } - } - } else if (!(rects->width & 3)) { - for (y = 0; y < rects->height; - y++, src += viddef.rowbytes, dst += ddsd.lPitch) { - byte *psrc = src; - unsigned *pdst = dst; - - for (x = 0; x < rects->width; - x += 4, psrc += 4, pdst += 4) { - pdst[0] = ddpal[psrc[0]]; - pdst[1] = ddpal[psrc[1]]; - pdst[2] = ddpal[psrc[2]]; - pdst[3] = ddpal[psrc[3]]; - } - } - } else { - for (y = 0; y < rects->height; - y++, src += viddef.rowbytes, dst += ddsd.lPitch) { - for (x = 0; x < rects->width; x++) { - dst[x] = ddpal[src[x]]; - } - } - } - - IDirectDrawSurface_Unlock (dd_BackBuffer, NULL); - - // correctly offset source - sRect.left = SrcRect.left + rects->x; - sRect.right = SrcRect.left + rects->x + rects->width; - sRect.top = SrcRect.top + rects->y; - sRect.bottom = SrcRect.top + rects->y + rects->height; - - // correctly offset dest - dRect.left = DstRect.left + rects->x; - dRect.right = DstRect.left + rects->x + rects->width; - dRect.top = DstRect.top + rects->y; - dRect.bottom = DstRect.top + rects->y + rects->height; - - // copy to front buffer - IDirectDrawSurface_Blt (dd_FrontBuffer, &dRect, dd_BackBuffer, - &sRect, 0, NULL); - } - } else if (hdcDIBSection) { - BitBlt (hdcGDI, rects->x, rects->y, - rects->x + rects->width, rects->y + rects->height, - hdcDIBSection, rects->x, rects->y, SRCCOPY); - } - - numrects++; - rects = rects->next; - } -} - - void D_BeginDirectRect (int x, int y, byte *pbitmap, int width, int height) { int i, j, reps, repshift; vrect_t rect; - if (!vid_initialized) + if (!viddef.initialized || !win_sw_context) return; if (viddef.aspect > 1.5) { @@ -1620,7 +79,7 @@ D_BeginDirectRect (int x, int y, byte *pbitmap, int width, int height) rect.height = height << repshift; rect.next = NULL; - FlipScreen (&rect); + win_sw_context->update (&rect); } @@ -1630,7 +89,7 @@ D_EndDirectRect (int x, int y, int width, int height) int i, j, reps, repshift; vrect_t rect; - if (!vid_initialized) + if (!viddef.initialized || !win_sw_context) return; if (viddef.aspect > 1.5) { @@ -1658,29 +117,98 @@ D_EndDirectRect (int x, int y, int width, int height) rect.height = height << repshift; rect.next = NULL; - FlipScreen (&rect); + win_sw_context->update (&rect); +} + +static void +VID_shutdown (void *data) +{ + Sys_MaskPrintf (SYS_VID, "VID_shutdown\n"); + Win_CloseDisplay (); +} + +void +VID_Init (byte *palette, byte *colormap) +{ + Sys_RegisterShutdown (VID_shutdown, 0); + + vid_internal.gl_context = Win_GL_Context; + vid_internal.sw_context = Win_SW_Context; +#ifdef HAVE_VULKAN + vid_internal.vulkan_context = Win_Vulkan_Context; +#endif + + R_LoadModule (&vid_internal); + + viddef.numpages = 1; + viddef.colormap8 = colormap; + viddef.fullbright = 256 - viddef.colormap8[256 * VID_GRADES]; + + VID_GetWindowSize (640, 480); + Win_OpenDisplay (); + vid_internal.choose_visual (); + Win_SetVidMode (viddef.width, viddef.height, palette); + vid_internal.create_context (); + + VID_InitGamma (palette); + viddef.vid_internal->set_palette (palette); + + Sys_MaskPrintf (SYS_VID, "Video mode %dx%d initialized.\n", + viddef.width, viddef.height); + + viddef.initialized = true; +} + +void +VID_Init_Cvars (void) +{ + Win_Init_Cvars (); +#ifdef HAVE_VULKAN + Win_Vulkan_Init_Cvars (); +#endif + Win_GL_Init_Cvars (); +} + +void +VID_LockBuffer (void) +{ +} + +void +VID_UnlockBuffer (void) +{ +} + +void +VID_SetCaption (const char *text) +{ + if (text && *text) { + char *temp = strdup (text); + + Win_SetCaption (va (0, "%s: %s", PACKAGE_STRING, temp)); + free (temp); + } else { + Win_SetCaption (va (0, "%s", PACKAGE_STRING)); + } +} + +qboolean +VID_SetGamma (double gamma) +{ + return Win_SetGamma (gamma); } +#if 0 void VID_Update (vrect_t *rects) { vrect_t rect; RECT trect; - if (!vid_palettized && palette_changed) { - palette_changed = false; - rect.x = 0; - rect.y = 0; - rect.width = viddef.width; - rect.height = viddef.height; - rect.next = NULL; - rects = ▭ - } - if (firstupdate) { if (modestate == MS_WINDOWED) { - GetWindowRect (hWndWinQuake, &trect); + GetWindowRect (win_mainwindow, &trect); if ((trect.left != vid_window_x->int_val) || (trect.top != vid_window_y->int_val)) { @@ -1690,7 +218,7 @@ VID_Update (vrect_t *rects) } VID_CheckWindowXY (); - SetWindowPos (hWndWinQuake, NULL, vid_window_x->int_val, + SetWindowPos (win_mainwindow, NULL, vid_window_x->int_val, vid_window_y->int_val, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW | SWP_DRAWFRAME); @@ -1763,401 +291,4 @@ VID_Update (vrect_t *rects) } } } - - -//========================================================================== - - -/* -================ -VID_HandlePause -================ -*/ -static void __attribute__ ((used)) -VID_HandlePause (qboolean pause) -{ - if ((modestate == MS_WINDOWED) && _windowed_mouse->int_val) { - if (pause) { - IN_DeactivateMouse (); - IN_ShowMouse (); - } else { - IN_ActivateMouse (); - IN_HideMouse (); - } - } -} - - -/* -=================================================================== - -MAIN WINDOW - -=================================================================== -*/ - -typedef struct { - int modenum; - char *desc; - int iscur; - int width; -} modedesc_t; - -#define MAX_COLUMN_SIZE 5 -#define MODE_AREA_HEIGHT (MAX_COLUMN_SIZE + 6) -#define MAX_MODEDESCS (MAX_COLUMN_SIZE*3) - -//static modedesc_t modedescs[MAX_MODEDESCS]; - -/* -================= -VID_NumModes -================= -*/ -int -VID_NumModes (void) -{ - return nummodes; -} - - -/* -================= -VID_GetModePtr -================= -*/ -vmode_t * -VID_GetModePtr (int modenum) -{ - if ((modenum >= 0) && (modenum < nummodes)) - return &modelist[modenum]; - else - return &badmode; -} - - -/* -================= -VID_CheckModedescFixup -================= -*/ -void -VID_CheckModedescFixup (int mode) -{ -} - - -/* -================= -VID_GetModeDescriptionMemCheck -================= -*/ -char * -VID_GetModeDescriptionMemCheck (int mode) -{ - char *pinfo; - vmode_t *pv; - - if ((mode < 0) || (mode >= nummodes)) - return NULL; - - VID_CheckModedescFixup (mode); - pv = VID_GetModePtr (mode); - pinfo = pv->modedesc; - - if (VID_CheckAdequateMem (pv->width, pv->height)) { - return pinfo; - } else { - return NULL; - } -} - - -/* -================= -VID_GetModeDescription -================= -*/ -char * -VID_GetModeDescription (int mode) -{ - char *pinfo; - vmode_t *pv; - - if ((mode < 0) || (mode >= nummodes)) - return NULL; - - VID_CheckModedescFixup (mode); - pv = VID_GetModePtr (mode); - pinfo = pv->modedesc; - return pinfo; -} - - -/* -================= -VID_GetModeDescription2 - -Tacks on "windowed" or "fullscreen" -================= -*/ -char * -VID_GetModeDescription2 (int mode) -{ - static char pinfo[40]; - vmode_t *pv; - - if ((mode < 0) || (mode >= nummodes)) - return NULL; - - VID_CheckModedescFixup (mode); - pv = VID_GetModePtr (mode); - - if (modelist[mode].type == MS_FULLSCREEN) { - sprintf (pinfo, "%s fullscreen", pv->modedesc); - } else if (modelist[mode].type == MS_FULLDIB) { - sprintf (pinfo, "%s fullscreen", pv->modedesc); - } else { - sprintf (pinfo, "%s windowed", pv->modedesc); - } - - return pinfo; -} - - -// KJB: Added this to return the mode driver name in description for console - -char * -VID_GetExtModeDescription (int mode) -{ - static char pinfo[40]; - vmode_t *pv; - - if ((mode < 0) || (mode >= nummodes)) - return NULL; - - VID_CheckModedescFixup (mode); - pv = VID_GetModePtr (mode); - - if (modelist[mode].type == MS_FULLDIB) { - sprintf (pinfo, "%s fullscreen", pv->modedesc); - } else { - sprintf (pinfo, "%s windowed", pv->modedesc); - } - - return pinfo; -} - - -/* -================= -VID_DescribeCurrentMode_f -================= -*/ -void -VID_DescribeCurrentMode_f (void) -{ - Sys_Printf ("%s\n", VID_GetExtModeDescription (vid_modenum)); -} - - -/* -================= -VID_NumModes_f -================= -*/ -void -VID_NumModes_f (void) -{ - if (nummodes == 1) - Sys_Printf ("%d video mode is available\n", nummodes); - else - Sys_Printf ("%d video modes are available\n", nummodes); -} - - -/* -================= -VID_DescribeMode_f -================= -*/ -void -VID_DescribeMode_f (void) -{ - int modenum; - - modenum = atoi (Cmd_Argv (1)); - Sys_Printf ("%s\n", VID_GetExtModeDescription (modenum)); -} - - -/* -================= -VID_DescribeModes_f -================= -*/ -void -VID_DescribeModes_f (void) -{ - int i, lnummodes; - char *pinfo; - qboolean na; - vmode_t *pv; - - na = false; - lnummodes = VID_NumModes (); - - for (i = 0; i < lnummodes; i++) { - pv = VID_GetModePtr (i); - pinfo = VID_GetExtModeDescription (i); - - if (VID_CheckAdequateMem (pv->width, pv->height)) { - Sys_Printf ("%2d: %s\n", i, pinfo); - } else { - Sys_Printf ("**: %s\n", pinfo); - na = true; - } - } - - if (na) { - Sys_Printf ("\n[**: not enough system RAM for mode]\n"); - } -} - - -/* -================= -VID_TestMode_f -================= -*/ -void -VID_TestMode_f (void) -{ - int modenum; - double testduration; - - if (!vid_testingmode) { - modenum = atoi (Cmd_Argv (1)); - - if (VID_SetMode (modenum, vid_curpal)) { - vid_testingmode = 1; - testduration = atof (Cmd_Argv (2)); - - if (testduration == 0) - testduration = 5.0; - - vid_testendtime = Sys_DoubleTime () + testduration; - } - } -} - - -/* -================= -VID_Windowed_f -================= -*/ -void -VID_Windowed_f (void) -{ - VID_SetMode (vid_windowed_mode->int_val, vid_curpal); -} - - -/* -================= -VID_Fullscreen_f -================= -*/ -void -VID_Fullscreen_f (void) -{ - VID_SetMode (vid_fullscreen_mode->int_val, vid_curpal); -} - - -/* -================= -VID_Minimize_f -================= -*/ -void -VID_Minimize_f (void) -{ - // we only support minimizing windows; if you're fullscreen, - // switch to windowed first - if (modestate == MS_WINDOWED) - ShowWindow (hWndWinQuake, SW_MINIMIZE); -} - - - -/* -================= -VID_ForceMode_f -================= -*/ -void -VID_ForceMode_f (void) -{ - int modenum; - - if (!vid_testingmode) { - modenum = atoi (Cmd_Argv (1)); - force_mode_set = 1; - VID_SetMode (modenum, vid_curpal); - force_mode_set = 0; - } -} - -void -VID_SetCaption (const char *text) -{ - if (text && *text) { - char *temp = strdup (text); - - SetWindowText (mainwindow, (LPSTR) va ("%s: %s", PACKAGE_STRING, temp)); - free (temp); - } else { - SetWindowText (mainwindow, (LPSTR) va ("%s", PACKAGE_STRING)); - } -} - -//static WORD systemgammaramps[3][256]; -static WORD currentgammaramps[3][256]; - -qboolean -VID_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; -} - -#if 0 -static void -VID_SaveGamma (void) -{ - HDC hdc = GetDC (NULL); - - GetDeviceGammaRamp (hdc, &systemgammaramps[0][0]); - ReleaseDC (NULL, hdc); -} - -static void -VID_RestoreGamma (void) -{ - HDC hdc = GetDC (NULL); - - SetDeviceGammaRamp (hdc, &systemgammaramps[0][0]); - ReleaseDC (NULL, hdc); -} #endif diff --git a/libs/video/targets/vid_win_gl.c b/libs/video/targets/vid_win_gl.c new file mode 100644 index 000000000..7a194d49b --- /dev/null +++ b/libs/video/targets/vid_win_gl.c @@ -0,0 +1,185 @@ +/* + vid_win_gl.c + + Win32 GL 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 + +#include "QF/cvar.h" +#include "QF/sys.h" +#include "QF/vid.h" + +#include "context_win.h" +#include "r_internal.h" +#include "vid_internal.h" +#include "vid_gl.h" + +// Define GLAPIENTRY to a useful value +#ifndef GLAPIENTRY +# define GLAPIENTRY WINAPI +#endif +static void *libgl_handle; +static HGLRC (GLAPIENTRY * qfwglCreateContext) (HDC); +static BOOL (GLAPIENTRY * qfwglDeleteContext) (HGLRC); +static HGLRC (GLAPIENTRY * qfwglGetCurrentContext) (void); +static HDC (GLAPIENTRY * qfwglGetCurrentDC) (void); +static BOOL (GLAPIENTRY * qfwglMakeCurrent) (HDC, HGLRC); +static void (GLAPIENTRY *qfglFinish) (void); +static void *(WINAPI * glGetProcAddress) (const char *symbol) = NULL; +static int use_gl_proceaddress = 0; + +static cvar_t *gl_driver; +static HGLRC baseRC;//FIXME should be in gl_ctx_t, but that's GLXContext... +static void * +QFGL_GetProcAddress (void *handle, const char *name) +{ + void *glfunc = NULL; + + if (use_gl_proceaddress && glGetProcAddress) + glfunc = glGetProcAddress (name); + if (!glfunc) + glfunc = GetProcAddress (handle, name); + return glfunc; +} + +static void * +QFGL_ProcAddress (const char *name, qboolean crit) +{ + void *glfunc = NULL; + + Sys_MaskPrintf (SYS_VID, "DEBUG: Finding symbol %s ... ", name); + + glfunc = QFGL_GetProcAddress (libgl_handle, name); + if (glfunc) { + Sys_MaskPrintf (SYS_VID, "found [%p]\n", glfunc); + return glfunc; + } + Sys_MaskPrintf (SYS_VID, "not found\n"); + + if (crit) { + Sys_Error ("Couldn't load critical OpenGL function %s, exiting...", + name); + } + return NULL; +} + +static void +wgl_choose_visual (gl_ctx_t *ctx) +{ +} + +static void +wgl_create_context (gl_ctx_t *ctx) +{ + DWORD lasterror; + + Sys_Printf ("maindc: %p\n", win_maindc); + baseRC = qfwglCreateContext (win_maindc); + if (!baseRC) { + lasterror=GetLastError(); + if (win_maindc && win_mainwindow) + ReleaseDC (win_mainwindow, win_maindc); + Sys_Error ("Could not initialize GL (wglCreateContext failed).\n\n" + "Make sure you are in 65535 color mode, and try running " + "with -window.\n" + "Error code: (%lx)", lasterror); + } + + if (!qfwglMakeCurrent (win_maindc, baseRC)) { + lasterror = GetLastError (); + if (baseRC) + qfwglDeleteContext (baseRC); + if (win_maindc && win_mainwindow) + ReleaseDC (win_mainwindow, win_maindc); + Sys_Error ("wglMakeCurrent failed (%lx)", lasterror); + } + + ctx->init_gl (); +} + +static void +wgl_end_rendering (void) +{ + if (!scr_skipupdate) { + qfglFinish (); + SwapBuffers (win_maindc); + } + // handle the mouse state when windowed if that's changed + if (!vid_fullscreen->int_val) { +//FIXME if (!in_grab->int_val) { +//FIXME if (windowed_mouse) { +//FIXME IN_DeactivateMouse (); +//FIXME IN_ShowMouse (); +//FIXME windowed_mouse = false; +//FIXME } +//FIXME } else { +//FIXME windowed_mouse = true; +//FIXME } + } +} + +static void +wgl_load_gl (void) +{ + libgl_handle = LoadLibrary (gl_driver->string); + if (!libgl_handle) { + Sys_Error ("Couldn't load OpenGL library %s!", gl_driver->string); + } + glGetProcAddress = + (void *) GetProcAddress (libgl_handle, "wglGetProcAddress"); + + qfwglCreateContext = QFGL_ProcAddress ("wglCreateContext", true); + qfwglDeleteContext = QFGL_ProcAddress ("wglDeleteContext", true); + qfwglGetCurrentContext = QFGL_ProcAddress ("wglGetCurrentContext", true); + qfwglGetCurrentDC = QFGL_ProcAddress ("wglGetCurrentDC", true); + qfwglMakeCurrent = QFGL_ProcAddress ("wglMakeCurrent", true); + + use_gl_proceaddress = 1; + + qfglFinish = QFGL_ProcAddress ("glFinish", true); +} + +gl_ctx_t * +Win_GL_Context (void) +{ + gl_ctx_t *ctx = calloc (1, sizeof (gl_ctx_t)); + ctx->load_gl = wgl_load_gl; + ctx->choose_visual = wgl_choose_visual; + ctx->create_context = wgl_create_context; + ctx->get_proc_address = QFGL_ProcAddress; + ctx->end_rendering = wgl_end_rendering; + return ctx; +} + +void +Win_GL_Init_Cvars (void) +{ + gl_driver = Cvar_Get ("gl_driver", GL_DRIVER, CVAR_ROM, NULL, + "The OpenGL library to use. (path optional)"); +} diff --git a/libs/video/targets/vid_win_sw.c b/libs/video/targets/vid_win_sw.c new file mode 100644 index 000000000..a869f273d --- /dev/null +++ b/libs/video/targets/vid_win_sw.c @@ -0,0 +1,234 @@ +/* + vid_win.c + + Win32 SW 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 + +#include "QF/cvar.h" +#include "QF/qargs.h" +#include "QF/sys.h" +#include "QF/vid.h" + +#include "context_win.h" +#include "r_internal.h" +#include "vid_internal.h" +#include "vid_sw.h" + +typedef union { + byte bgra[4]; + uint32_t value; +} win_palette_t; + +static win_palette_t st2d_8to32table[256]; +static byte current_palette[768]; +static int palette_changed; + +static void +win_init_bufers (void) +{ + // set the rest of the buffers we need (why not just use one single buffer + // instead of all this crap? oh well, it's Quake...) + viddef.direct = viddef.buffer; + viddef.conbuffer = viddef.buffer; + + // more crap for the console + viddef.conrowbytes = viddef.rowbytes; +} + +static void +win_set_palette (const byte *palette) +{ + palette_changed = 1; + if (palette != current_palette) { + memcpy (current_palette, palette, sizeof (current_palette)); + } + for (int i = 0; i < 256; i++) { + const byte *pal = palette + 3 * i; + st2d_8to32table[i].bgra[0] = viddef.gammatable[pal[2]]; + st2d_8to32table[i].bgra[1] = viddef.gammatable[pal[1]]; + st2d_8to32table[i].bgra[2] = viddef.gammatable[pal[0]]; + st2d_8to32table[i].bgra[3] = 255; + } + if (!Minimized && !win_using_ddraw && win_dib_section) { + RGBQUAD colors[256]; + memcpy (colors, st2d_8to32table, sizeof (colors)); + for (int i = 0; i < 256; i++) { + colors[i].rgbReserved = 0; + } + colors[0].rgbRed = 0; + colors[0].rgbGreen = 0; + colors[0].rgbBlue = 0; + colors[255].rgbRed = 0xff; + colors[255].rgbGreen = 0xff; + colors[255].rgbBlue = 0xff; + + if (SetDIBColorTable (win_dib_section, 0, 256, colors) == 0) { + Sys_Printf ("win_set_palette() - SetDIBColorTable failed\n"); + } + } +} + +static void +dd_blit_rect (vrect_t *rect) +{ + RECT TheRect; + RECT sRect, dRect; + DDSURFACEDESC ddsd; + + memset (&ddsd, 0, sizeof (ddsd)); + ddsd.dwSize = sizeof (DDSURFACEDESC); + + // lock the correct subrect + TheRect.left = rect->x; + TheRect.right = rect->x + rect->width; + TheRect.top = rect->y; + TheRect.bottom = rect->y + rect->height; + + if (IDirectDrawSurface_Lock (win_dd_backbuffer, &TheRect, &ddsd, + DDLOCK_WRITEONLY | DDLOCK_SURFACEMEMORYPTR, + NULL) == DDERR_WASSTILLDRAWING) { + return; + } + + // convert pitch to 32-bit addressable + ddsd.lPitch >>= 2; + + byte *src = viddef.buffer + rect->y * viddef.rowbytes + rect->x; + unsigned *dst = ddsd.lpSurface; + for (int y = rect->height; y-- > 0; ) { + for (int x = rect->width; x-- > 0; ) { + *dst++ = st2d_8to32table[*src++].value; + } + src += viddef.rowbytes - rect->width; + dst += ddsd.lPitch - rect->width; + } + + IDirectDrawSurface_Unlock (win_dd_backbuffer, NULL); + + // correctly offset source + sRect.left = win_src_rect.left + rect->x; + sRect.right = win_src_rect.left + rect->x + rect->width; + sRect.top = win_src_rect.top + rect->y; + sRect.bottom = win_src_rect.top + rect->y + rect->height; + + // correctly offset dest + dRect.left = win_dst_rect.left + rect->x; + dRect.right = win_dst_rect.left + rect->x + rect->width; + dRect.top = win_dst_rect.top + rect->y; + dRect.bottom = win_dst_rect.top + rect->y + rect->height; + + // copy to front buffer + IDirectDrawSurface_Blt (win_dd_frontbuffer, &dRect, win_dd_backbuffer, + &sRect, 0, NULL); +} + +static void +win_sw_update (vrect_t *rects) +{ + vrect_t full_rect; + if (!win_palettized && palette_changed) { + palette_changed = false; + full_rect.x = 0; + full_rect.y = 0; + full_rect.width = viddef.width; + full_rect.height = viddef.height; + full_rect.next = 0; + rects = &full_rect; + } + + if (win_using_ddraw) { + while (rects) { + dd_blit_rect (rects); + rects = rects->next; + } + } else if (win_dib_section) { + while (rects) { + BitBlt (win_gdi, rects->x, rects->y, + rects->x + rects->width, rects->y + rects->height, + win_dib_section, rects->x, rects->y, SRCCOPY); + rects = rects->next; + } + } +} + + +static void +win_choose_visual (sw_ctx_t *ctx) +{ +} + +static void +win_set_background (void) +{ + // because we have set the background brush for the window to NULL (to + // avoid flickering when re-sizing the window on the desktop), we clear + // the window to black when created, otherwise it will be empty while + // Quake starts up. This also prevents a screen flash to white when + // switching drivers. it still flashes, but at least it's black now + HDC hdc = GetDC (win_mainwindow); + PatBlt (hdc, 0, 0, win_window_rect.right, win_window_rect.bottom, + BLACKNESS); + ReleaseDC (win_mainwindow, hdc); +} + +static void +win_create_context (sw_ctx_t *ctx) +{ + // shutdown any old driver that was active + Win_UnloadAllDrivers (); + + win_sw_context = ctx; + + win_set_background (); + + // create the new driver + win_using_ddraw = false; + + Win_CreateDriver (); + + viddef.vid_internal->do_screen_buffer = win_init_bufers; + VID_InitBuffers (); +} + +sw_ctx_t * +Win_SW_Context (void) +{ + sw_ctx_t *ctx = calloc (1, sizeof (sw_ctx_t)); + ctx->set_palette = win_set_palette; + ctx->choose_visual = win_choose_visual; + ctx->create_context = win_create_context; + ctx->update = win_sw_update; + return ctx; +} + +void +Win_SW_Init_Cvars (void) +{ +} diff --git a/libs/video/targets/vid_win_vulkan.c b/libs/video/targets/vid_win_vulkan.c new file mode 100644 index 000000000..2ec53343e --- /dev/null +++ b/libs/video/targets/vid_win_vulkan.c @@ -0,0 +1,145 @@ +/* + 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 "QF/cvar.h" +#include "QF/set.h" +#include "QF/sys.h" +#include "QF/va.h" + +#include "QF/Vulkan/instance.h" + +#include "context_win.h" +#include "vid_internal.h" +#include "vid_vulkan.h" + +static cvar_t *vulkan_library_name; + +typedef struct vulkan_presentation_s { +#define PRESENTATION_VULKAN_FUNCTION_FROM_EXTENSION(name,ext) PFN_##name name; +#include "QF/Vulkan/funclist.h" + + set_t *usable_visuals; +} vulkan_presentation_t; + +static const char *required_extensions[] = { + 0 +}; + +static HMODULE vulkan_library; + +static void +load_vulkan_library (vulkan_ctx_t *ctx) +{ + vulkan_library = LoadLibrary (vulkan_library_name->string); + if (!vulkan_library) { + DWORD errcode = GetLastError (); + Sys_Error ("Couldn't load vulkan library %s: %ld", + vulkan_library_name->string, errcode); + } + + #define EXPORTED_VULKAN_FUNCTION(name) \ + ctx->name = (PFN_##name) GetProcAddress (vulkan_library, #name); \ + if (!ctx->name) { \ + Sys_Error ("Couldn't find exported vulkan function %s", #name); \ + } + + #define GLOBAL_LEVEL_VULKAN_FUNCTION(name) \ + ctx->name = (PFN_##name) ctx->vkGetInstanceProcAddr (0, #name); \ + if (!ctx->name) { \ + Sys_Error ("Couldn't find global-level function %s", #name); \ + } + + #include "QF/Vulkan/funclist.h" +} + +static void +unload_vulkan_library (vulkan_ctx_t *ctx) +{ + FreeLibrary (vulkan_library); + vulkan_library = 0; +} + +static void +win_vulkan_init_presentation (vulkan_ctx_t *ctx) +{ +} + +static int +win_vulkan_get_presentation_support (vulkan_ctx_t *ctx, + VkPhysicalDevice physicalDevice, + uint32_t queueFamilyIndex) +{ + if (!ctx->presentation) { + win_vulkan_init_presentation (ctx); + } + vulkan_presentation_t *pres = ctx->presentation; + return !set_is_empty (pres->usable_visuals); +} + +static void +win_vulkan_choose_visual (vulkan_ctx_t *ctx) +{ +} + +static void +win_vulkan_create_window (vulkan_ctx_t *ctx) +{ +} + +static VkSurfaceKHR +win_vulkan_create_surface (vulkan_ctx_t *ctx) +{ + return 0; +} + +vulkan_ctx_t * +Win_Vulkan_Context (void) +{ + vulkan_ctx_t *ctx = calloc (1, sizeof (vulkan_ctx_t)); + ctx->load_vulkan = load_vulkan_library; + ctx->unload_vulkan = unload_vulkan_library; + ctx->get_presentation_support = win_vulkan_get_presentation_support; + ctx->choose_visual = win_vulkan_choose_visual; + ctx->create_window = win_vulkan_create_window; + ctx->create_surface = win_vulkan_create_surface; + ctx->required_extensions = required_extensions; + ctx->va_ctx = va_create_context (4); + return ctx; +} + +void +Win_Vulkan_Init_Cvars (void) +{ + vulkan_library_name = Cvar_Get ("vulkan_library", "vulkan-1.dll", + CVAR_ROM, 0, + "the name of the vulkan shared library"); +} diff --git a/libs/video/targets/vid_x11_gl.c b/libs/video/targets/vid_x11_gl.c index 28b2f3294..6dca344ab 100644 --- a/libs/video/targets/vid_x11_gl.c +++ b/libs/video/targets/vid_x11_gl.c @@ -65,19 +65,17 @@ typedef XID GLXDrawable; +// GLXContext is a pointer to opaque data +typedef struct __GLXcontextRec *GLXContext; + + // Define GLAPIENTRY to a useful value #ifndef GLAPIENTRY -# ifdef _WIN32 -# include -# define GLAPIENTRY WINAPI -# undef LoadImage -# else # ifdef APIENTRY # define GLAPIENTRY APIENTRY # else # define GLAPIENTRY # endif -# endif #endif static void *libgl_handle; static void (*qfglXSwapBuffers) (Display *dpy, GLXDrawable drawable); @@ -155,8 +153,9 @@ static void glx_create_context (gl_ctx_t *ctx) { XSync (x_disp, 0); - ctx->context = qfglXCreateContext (x_disp, x_visinfo, NULL, True); - qfglXMakeCurrent (x_disp, x_win, ctx->context); + ctx->context = (GL_context) qfglXCreateContext (x_disp, x_visinfo, NULL, + True); + qfglXMakeCurrent (x_disp, x_win, (GLXContext) ctx->context); ctx->init_gl (); } diff --git a/libs/video/targets/vid_x11_sw.c b/libs/video/targets/vid_x11_sw.c index 9c734a635..a04900585 100644 --- a/libs/video/targets/vid_x11_sw.c +++ b/libs/video/targets/vid_x11_sw.c @@ -188,7 +188,7 @@ xlib_rgb24 (int r, int g, int b) } static void -VID_SetPalette (const byte *palette) +x11_set_palette (const byte *palette) { int i; XColor colors[256]; @@ -529,7 +529,7 @@ sw_ctx_t * X11_SW_Context (void) { sw_ctx_t *ctx = calloc (1, sizeof (sw_ctx_t)); - ctx->set_palette = VID_SetPalette; + ctx->set_palette = x11_set_palette; ctx->choose_visual = x11_choose_visual; ctx->create_context = x11_create_context; ctx->update = x11_sw_update; diff --git a/nq/source/Makemodule.am b/nq/source/Makemodule.am index 6caa9fe32..2288bd20c 100644 --- a/nq/source/Makemodule.am +++ b/nq/source/Makemodule.am @@ -31,7 +31,7 @@ # bin_PROGRAMS += @NQ_TARGETS@ -EXTRA_PROGRAMS += nq-fbdev nq-sdl nq-svga nq-wgl nq-x11 nq-server +EXTRA_PROGRAMS += nq-fbdev nq-sdl nq-svga nq-win nq-x11 nq-server noinst_LIBRARIES += @nq_libs@ EXTRA_LIBRARIES += nq/source/libnq_client.a nq/source/libnq_common.a nq/source/libnq_sdl.a nq/source/libnq_server.a @@ -140,16 +140,17 @@ nq_x11_DEPENDENCIES= $(nq_x11_libs) # OpenGL-using targets # ... SGI/Microsoft WGL (Windows OpenGL) -nq_wgl_libs= \ +nq_win_libs= \ $(nq_client_libs) \ $(nq_cl_plugin_LIBS) \ - $(opengl_QFLIBS) \ - libs/video/targets/libQFwgl.la \ + libs/video/renderer/libQFrenderer.la \ + libs/models/libQFmodels.la \ + libs/video/targets/libQFwin.la \ $(nq_client_LIBS) -nq_wgl_SOURCES= nq/source/sys_win.c -nq_wgl_LDADD= $(nq_wgl_libs) -lgdi32 -lcomctl32 -lwinmm $(NET_LIBS) -nq_wgl_LDFLAGS= $(common_ldflags) -nq_wgl_DEPENDENCIES= $(nq_wgl_libs) +nq_win_SOURCES= nq/source/sys_win.c +nq_win_LDADD= $(nq_win_libs) -lgdi32 -lcomctl32 -lwinmm $(NET_LIBS) +nq_win_LDFLAGS= $(common_ldflags) +nq_win_DEPENDENCIES= $(nq_win_libs) # Dedicated Server if SYSTYPE_WIN32 diff --git a/nq/source/sys_sdl.c b/nq/source/sys_sdl.c index ddc4a8df7..76e84b558 100644 --- a/nq/source/sys_sdl.c +++ b/nq/source/sys_sdl.c @@ -55,7 +55,7 @@ #include "nq/include/host.h" #ifdef _WIN32 -# include "nq/include/winquake.h" +# include "winquake.h" #endif int qf_sdl_link; @@ -123,6 +123,11 @@ SDL_main (int argc, char *argv[]) fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) | O_NONBLOCK); Sys_Printf ("Quake -- Version %s\n", NQ_VERSION); } +#else + // hack to prevent gcc suggesting noreturn + if (!sys_nostdout) { + return 1; + } #endif oldtime = Sys_DoubleTime () - 0.1; diff --git a/qw/source/Makemodule.am b/qw/source/Makemodule.am index bad7bd189..7e9c1a61c 100644 --- a/qw/source/Makemodule.am +++ b/qw/source/Makemodule.am @@ -30,7 +30,7 @@ bin_PROGRAMS += @QW_TARGETS@ EXTRA_PROGRAMS += \ - qw-client-fbdev qw-client-sdl qw-client-svga qw-client-wgl qw-client-x11 \ + qw-client-fbdev qw-client-sdl qw-client-svga qw-client-win qw-client-x11 \ qw-server qw-master noinst_LIBRARIES += @qw_libs@ @@ -164,13 +164,14 @@ qw_client_x11_LDFLAGS= $(common_ldflags) qw_client_x11_DEPENDENCIES= $(qw_client_x11_libs) # ... SGI/Microsoft WGL (Windows OpenGL) -qw_client_wgl_libs= \ +qw_client_win_libs= \ $(qw_client_libs) \ $(qw_cl_plugin_LIBS) \ - $(opengl_LIBS) \ - libs/video/targets/libQFwgl.la \ + libs/video/renderer/libQFrenderer.la \ + libs/models/libQFmodels.la \ + libs/video/targets/libQFwin.la \ $(qw_client_LIBS) -qw_client_wgl_SOURCES= qw/source/cl_sys_win.c -qw_client_wgl_LDADD= $(qw_client_wgl_libs) -lgdi32 -lwinmm $(NET_LIBS) $(LIBCURL_LIBS) -qw_client_wgl_LDFLAGS= $(common_ldflags) -qw_client_wgl_DEPENDENCIES= $(qw_client_wgl_libs) +qw_client_win_SOURCES= qw/source/cl_sys_win.c +qw_client_win_LDADD= $(qw_client_win_libs) -lgdi32 -lwinmm $(NET_LIBS) $(LIBCURL_LIBS) +qw_client_win_LDFLAGS= $(common_ldflags) +qw_client_win_DEPENDENCIES= $(qw_client_win_libs) diff --git a/qw/source/cl_sys_sdl.c b/qw/source/cl_sys_sdl.c index c3b620ca8..0959b94cc 100644 --- a/qw/source/cl_sys_sdl.c +++ b/qw/source/cl_sys_sdl.c @@ -118,6 +118,11 @@ SDL_main (int argc, char *argv[]) #ifndef _WIN32 if (!COM_CheckParm ("-noconinput")) fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) | O_NONBLOCK); +#else + // hack to prevent gcc suggesting noreturn + if (!sys_nostdout) { + return 1; + } #endif Sys_RegisterShutdown (Host_Shutdown, 0); Sys_RegisterShutdown (Net_LogStop, 0); diff --git a/ruamoko/cl_menu/Makemodule.am b/ruamoko/cl_menu/Makemodule.am index c6c57aa7a..90dcbb5ba 100644 --- a/ruamoko/cl_menu/Makemodule.am +++ b/ruamoko/cl_menu/Makemodule.am @@ -41,7 +41,7 @@ ruamoko/cl_menu/menu.dat$(EXEEXT): $(ruamoko_menu_obj) $(QFCC_DEP) ruamoko/lib/l include $(ruamoko_menu_dep) # am--include-marker r_depfiles_remade += $(ruamoko_menu_dep) -ruamoko/cl_menu/menu.sym: ruamoko/cl_menu/menu.dat +ruamoko/cl_menu/menu.sym: ruamoko/cl_menu/menu.dat$(EXEEXT) EXTRA_DIST += \ ruamoko/cl_menu/CrosshairCvar.h \ diff --git a/ruamoko/qwaq/Makemodule.am b/ruamoko/qwaq/Makemodule.am index 781db5c76..1626d661b 100644 --- a/ruamoko/qwaq/Makemodule.am +++ b/ruamoko/qwaq/Makemodule.am @@ -57,7 +57,7 @@ ruamoko_qwaq_qwaq_curses_SOURCES= \ $e ruamoko_qwaq_qwaq_curses_LDADD= $(qwaq_curses_libs) $(QWAQ_LIBS) \ - $(PANEL_LIBS) $(CURSES_LIBS) $(PTHREAD_LDFLAGS) $(DL_LIBS) + $(PANEL_LIBS) $(NCURSES_LIBS) $(PTHREAD_LDFLAGS) $(DL_LIBS) ruamoko_qwaq_qwaq_curses_LDFLAGS= ruamoko_qwaq_qwaq_curses_DEPENDENCIES= $(qwaq_curses_libs) $(QWAQ_DEPS) diff --git a/ruamoko/qwaq/builtins/curses.c b/ruamoko/qwaq/builtins/curses.c index 7da55d4e2..976a15ee7 100644 --- a/ruamoko/qwaq/builtins/curses.c +++ b/ruamoko/qwaq/builtins/curses.c @@ -659,7 +659,7 @@ dump_command (qwaq_resources_t *res, int len) } void -qwaq_init_timeout (struct timespec *timeout, long time) +qwaq_init_timeout (struct timespec *timeout, int64_t time) { #define SEC 1000000000L struct timeval now; diff --git a/ruamoko/qwaq/builtins/debug.c b/ruamoko/qwaq/builtins/debug.c index a8c56f280..741bd8a91 100644 --- a/ruamoko/qwaq/builtins/debug.c +++ b/ruamoko/qwaq/builtins/debug.c @@ -31,14 +31,12 @@ # include "config.h" #endif -#include #include #include #include #include #include #include -#include #include #include "QF/dstring.h" diff --git a/ruamoko/qwaq/builtins/input.c b/ruamoko/qwaq/builtins/input.c index ce47b1914..afe96a2ec 100644 --- a/ruamoko/qwaq/builtins/input.c +++ b/ruamoko/qwaq/builtins/input.c @@ -31,16 +31,19 @@ # include "config.h" #endif -#include #include #include #include #include #include #include -#include #include +#ifdef HAVE_SIGACTION // no sigaction, no window resize +#include +#include +#endif + #include "QF/dstring.h" #include "QF/hash.h" #include "QF/keys.h" @@ -164,6 +167,7 @@ static qwaq_key_t default_keys[] = { { "\033[1;6D", QFK_LEFT, 5 }, }; +#ifdef HAVE_SIGACTION static struct sigaction save_winch; static sigset_t winch_mask; static volatile sig_atomic_t winch_arrived; @@ -173,6 +177,7 @@ handle_winch (int sig) { winch_arrived = 1; } +#endif int qwaq_add_event (qwaq_resources_t *res, qwaq_event_t *event) @@ -196,7 +201,7 @@ qwaq_add_event (qwaq_resources_t *res, qwaq_event_t *event) } pthread_mutex_lock (&res->event_cond.mut); - qwaq_init_timeout (&timeout, 5000 * 1000000L); + qwaq_init_timeout (&timeout, 5000 * (int64_t) 1000000); while (RB_SPACE_AVAILABLE (res->event_queue) < 1 && ret == 0) { ret = pthread_cond_timedwait (&res->event_cond.wcond, &res->event_cond.mut, &timeout); @@ -207,6 +212,7 @@ qwaq_add_event (qwaq_resources_t *res, qwaq_event_t *event) return ret; } +#ifdef HAVE_SIGACTION static void resize_event (qwaq_resources_t *res) { @@ -220,6 +226,7 @@ resize_event (qwaq_resources_t *res) event.resize.height = size.ws_row; qwaq_add_event (res, &event); } +#endif static void key_event (qwaq_resources_t *res, int key, unsigned shift) @@ -428,11 +435,13 @@ void qwaq_input_init (qwaq_resources_t *res) Hash_Add (res->key_sequences, &default_keys[i]); } +#ifdef HAVE_SIGACTION sigemptyset (&winch_mask); sigaddset (&winch_mask, SIGWINCH); struct sigaction action = {}; action.sa_handler = handle_winch; sigaction (SIGWINCH, &action, &save_winch); +#endif // ncurses takes care of input mode for us, so need only tell xterm // what we need @@ -447,13 +456,16 @@ void qwaq_input_shutdown (qwaq_resources_t *res) write(1, SGR_OFF, sizeof (SGR_OFF) - 1); write(1, MOUSE_MOVES_OFF, sizeof (MOUSE_MOVES_OFF) - 1); +#ifdef HAVE_SIGACTION sigaction (SIGWINCH, &save_winch, 0); +#endif } void qwaq_process_input (qwaq_resources_t *res) { char buf[256]; int len; +#ifdef HAVE_SIGACTION sigset_t save_set; int saw_winch; @@ -464,6 +476,7 @@ void qwaq_process_input (qwaq_resources_t *res) if (saw_winch) { resize_event (res); } +#endif while (Sys_CheckInput (1, -1)) { len = read(0, buf, sizeof (buf)); for (int i = 0; i < len; i++) { diff --git a/ruamoko/qwaq/builtins/main.c b/ruamoko/qwaq/builtins/main.c index f8800df93..7e4e7f5b4 100644 --- a/ruamoko/qwaq/builtins/main.c +++ b/ruamoko/qwaq/builtins/main.c @@ -52,6 +52,8 @@ #include "QF/va.h" #include "QF/zone.h" +#include "compat.h" + #include "ruamoko/qwaq/qwaq.h" #include "ruamoko/qwaq/debugger/debug.h" diff --git a/ruamoko/qwaq/qwaq.h b/ruamoko/qwaq/qwaq.h index 43efc4700..dc7b6f668 100644 --- a/ruamoko/qwaq/qwaq.h +++ b/ruamoko/qwaq/qwaq.h @@ -1,6 +1,8 @@ #ifndef __qwaq_h #define __qwaq_h +#include + #include "QF/darray.h" #include "QF/progs.h" #include "QF/sys.h" diff --git a/ruamoko/qwaq/ui/curses.h b/ruamoko/qwaq/ui/curses.h index f3038365e..538157f58 100644 --- a/ruamoko/qwaq/ui/curses.h +++ b/ruamoko/qwaq/ui/curses.h @@ -201,7 +201,7 @@ typedef struct qwaq_resources_s { void qwaq_input_init (qwaq_resources_t *res); void qwaq_input_shutdown (qwaq_resources_t *res); void qwaq_process_input (qwaq_resources_t *res); -void qwaq_init_timeout (struct timespec *timeout, long time); +void qwaq_init_timeout (struct timespec *timeout, int64_t time); int qwaq_add_event (qwaq_resources_t *res, qwaq_event_t *event); void qwaq_init_cond (rwcond_t *cond); #endif diff --git a/tools/carne/main.c b/tools/carne/main.c index 8ecc723cd..db45b88aa 100644 --- a/tools/carne/main.c +++ b/tools/carne/main.c @@ -1,3 +1,7 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + #include #include #include diff --git a/tools/cross/mingw64/cross-configure.sh b/tools/cross/mingw64/cross-configure.sh index b9aa14371..7a886f631 100755 --- a/tools/cross/mingw64/cross-configure.sh +++ b/tools/cross/mingw64/cross-configure.sh @@ -1,19 +1,20 @@ #!/bin/sh -x set -e -mkdir -p native i686-w64-mingw32.static +mkdir -p native x86_64-w64-mingw32.static cd native ../../configure \ + --enable-silent-rules \ --disable-shared \ --without-clients \ --without-servers \ - --with-tools=qfcc,pak -cd ../i686-w64-mingw32.static + --with-tools=qfcc,pak,qwaq +cd ../x86_64-w64-mingw32.static export MINGW=/opt/mxe -export MINGW_USR=$MINGW/usr/i686-w64-mingw32.static +export MINGW_USR=$MINGW/usr/x86_64-w64-mingw32.static export PKG_CONFIG_LIBDIR=$MINGW_USR/lib/pkgconfig export PKG_CONFIG_PATH=$MINGW_USR/local/lib/pkgconfig export PATH=$MINGW/usr/bin:$PATH ../../configure \ - --host=i686-w64-mingw32.static \ + --host=x86_64-w64-mingw32.static \ --disable-shared \ $* diff --git a/tools/cross/mingw64/cross-make.sh b/tools/cross/mingw64/cross-make.sh index 9ecef230e..6282f1cef 100755 --- a/tools/cross/mingw64/cross-make.sh +++ b/tools/cross/mingw64/cross-make.sh @@ -3,14 +3,15 @@ set -e if test -d native; then cd native make $* - cd ../x86_64-w64-mingw32 - ln -fs ../native/tools/qfcc/source/qfcc . - ln -fs ../native/tools/pak/pak . + cd ../x86_64-w64-mingw32.static + ln -fs ../native/qfcc . + ln -fs ../native/pak . + ln -fs ../native/ruamoko/qwaq/qwaq-curses . fi export MINGW=/opt/mxe -export MINGW_USR=$MINGW/usr/x86_64-w64-mingw32 +export MINGW_USR=$MINGW/usr/x86_64-w64-mingw32.static export PKG_CONFIG_LIBDIR=$MINGW_USR/lib/pkgconfig export PKG_CONFIG_PATH=$MINGW_USR/local/lib/pkgconfig export PATH=$MINGW/usr/bin:$PATH -make PAK='$(top_builddir)/pak' QFCC='$(top_builddir)/qfcc' $* +make PAK='$(top_builddir)/pak' QFCC='$(top_builddir)/qfcc' QWAQ_CURSES='$(top_builddir)/qwaq-curses' $* diff --git a/tools/qfcc/source/Makemodule.am b/tools/qfcc/source/Makemodule.am index 97b4eeb5c..76e3f73d8 100644 --- a/tools/qfcc/source/Makemodule.am +++ b/tools/qfcc/source/Makemodule.am @@ -2,7 +2,7 @@ QFCC_LIBS=@QFCC_LIBS@ QFCC_DEPS=@QFCC_DEPS@ QFCC_INCS=@QFCC_INCS@ -EXTRA_PROGRAMS += qfcc qfprogs +EXTRA_PROGRAMS += qfcc$(EXEEXT) qfprogs$(EXEEXT) bin_PROGRAMS += @QFCC_TARGETS@ bin_SCRIPTS += tools/qfcc/source/qfpreqcc diff --git a/tools/qfcc/source/cpp.c b/tools/qfcc/source/cpp.c index 1adb1301b..db2d95d55 100644 --- a/tools/qfcc/source/cpp.c +++ b/tools/qfcc/source/cpp.c @@ -269,7 +269,7 @@ preprocess_file (const char *filename, const char *ext) puts(""); } -#ifdef _WIN64 +#if defined(_WIN64) || defined(_WIN32) status = spawnvp (_P_WAIT, cpp_argv[0], (char **) cpp_argv); #else status = spawnvp (_P_WAIT, cpp_argv[0], cpp_argv); diff --git a/tools/qfcc/source/dump_lines.c b/tools/qfcc/source/dump_lines.c index 46382cf11..044c7fdc7 100644 --- a/tools/qfcc/source/dump_lines.c +++ b/tools/qfcc/source/dump_lines.c @@ -168,7 +168,8 @@ qfo_lines (qfo_t *qfo) pr_lineno_t *lineno; qfo_func_t *func = 0; - for (func = qfo->funcs; func - qfo->funcs < qfo->num_funcs; func++) { + for (func = qfo->funcs; + (size_t) (func - qfo->funcs) < qfo->num_funcs; func++) { if (!func->line_info) { // builtin continue; @@ -182,7 +183,7 @@ qfo_lines (qfo_t *qfo) qfo_set_func_data(qfo, func, &func_data); start_lineno = qfo->lines + func->line_info; for (lineno = start_lineno + 1; - lineno - qfo->lines < qfo->num_lines && lineno->line; + (size_t) (lineno - qfo->lines) < qfo->num_lines && lineno->line; lineno++) { } diff --git a/tools/qfcc/source/dump_strings.c b/tools/qfcc/source/dump_strings.c index ce9627f32..ae32856e7 100644 --- a/tools/qfcc/source/dump_strings.c +++ b/tools/qfcc/source/dump_strings.c @@ -40,18 +40,18 @@ #include "tools/qfcc/include/qfprogs.h" static void -dump_string_block (const char *strblock, unsigned size) +dump_string_block (const char *strblock, size_t size) { const char *s = strblock; printf ("%x \"", 0); - while (s - strblock < size) { + while ((size_t) (s - strblock) < size) { char c = *s++; switch (c) { case 0: fputs ("\"\n", stdout); - if (s - strblock < size) - printf ("%lx \"", s - strblock); + if ((size_t) (s - strblock) < size) + printf ("%zx \"", s - strblock); break; case 9: fputs ("\\t", stdout); diff --git a/tools/qfcc/source/linker.c b/tools/qfcc/source/linker.c index 502283fb5..d93b1ea60 100644 --- a/tools/qfcc/source/linker.c +++ b/tools/qfcc/source/linker.c @@ -1191,7 +1191,7 @@ undefined_def (qfo_def_t *def) pr_uint_t best_dist; pr_lineno_t *line; - while (func - work->funcs < work->num_funcs) { + while (func - work->funcs < (ptrdiff_t) work->num_funcs) { if (func->code >= 0 && (pr_uint_t) func->code <= reloc->offset) { if (!best || reloc->offset - func->code < best_dist) { @@ -1206,7 +1206,7 @@ undefined_def (qfo_def_t *def) line_def.line = best->line; if (!line->line && line->fa.func == (pr_uint_t) (best - work->funcs)) { - while (line - work->lines < work->num_lines - 1 + while (line - work->lines < (ptrdiff_t) work->num_lines - 1 && line[1].line && line[1].fa.addr <= (pr_uint_t) reloc->offset) line++; diff --git a/tools/qfcc/source/obj_file.c b/tools/qfcc/source/obj_file.c index a8e6ae5fb..0380d1fbb 100644 --- a/tools/qfcc/source/obj_file.c +++ b/tools/qfcc/source/obj_file.c @@ -46,6 +46,8 @@ #include "QF/quakeio.h" #include "QF/va.h" +#include "compat.h" + #include "tools/qfcc/include/codespace.h" #include "tools/qfcc/include/debug.h" #include "tools/qfcc/include/def.h" diff --git a/tools/qfspritegen/spritegen.c b/tools/qfspritegen/spritegen.c index 08ddc86f1..e1af9e487 100644 --- a/tools/qfspritegen/spritegen.c +++ b/tools/qfspritegen/spritegen.c @@ -22,6 +22,10 @@ // Result is stored in /raid/quake/id1/sprites/.spr. // +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + #include #include #include