mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-30 07:31:13 +00:00
8d5b217266
r4169 | acceptthis | 2013-01-17 08:55:12 +0000 (Thu, 17 Jan 2013) | 31 lines removed MAX_VISEDICTS limit. PEXT2_REPLACEMENTDELTAS tweaked, now has 4 million entity limit. still not enabled by default. TE_BEAM now maps to a separate TEQW_BEAM to avoid conflicts with QW. added android multitouch emulation for windows/rawinput (in_simulatemultitouch). split topcolor/bottomcolor from scoreboard, for dp's colormap|1024 feature. now using utf-8 for windows consoles. qcc warnings/errors now give clickable console links for quick+easy editing. disabled menutint when the currently active item changes contrast or gamma (for OneManClan). Added support for drawfont/drawfontscale. tweaked the qcvm a little to reduce the number of pointers. .doll file loading. still experimental and will likely crash. requires csqc active, even if its a dummy progs. this will be fixed in time. Still other things that need cleaning up. windows: gl_font "?" shows the standard windows font-selection dialog, and can be used to select windows fonts. not all work. and you probably don't want to use windings. fixed splitscreen support when playing mvds. added mini-scoreboards to splitscreen. editor/debugger now shows asm if there's no linenumber info. also, pressing f1 for help shows the shortcuts. Added support for .framegroups files for psk(psa) and iqm formats. True support for ezquake's colour codes. Mutually exclusive with background colours. path command output slightly more readable. added support for digest_hex (MD4, SHA1, CRC16). skingroups now colourmap correctly. Fix terrain colour hints, and litdata from the wrong bsp. fix ftp dual-homed issue. support epsv command, and enable ipv6 (eprt still not supported). remove d3d11 compilation from the makefile. the required headers are not provided by mingw, and are not available to the build bot, so don't bother. fix v *= v.x and similar opcodes. fteqcc: fixed support for áéíóú type chars in names. utf-8 files now properly supported (even with the utf-8 bom/identifier). utf-16 also supported. fteqcc: fixed '#if 1 == 3 && 4' parsing. fteqcc: -Werror acts on the warning, rather than as a separate error. Line numbers are thus more readable. fteqcc: copyright message now includes compile date instead. fteqccgui: the treeview control is now coloured depending on whether there were warnings/errors in the last compile. fteqccgui: the output window is now focused and scrolls down as compilation progresses. pr_dumpplatform command dumps out some pragmas to convert more serious warnings to errors. This is to avoid the infamous 'fteqcc sucks cos my code sucks' issue. rewrote prespawn/modelist/soundlist code. server tracks progress now. ------------------------------------------------------------------------ git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4167 fc73d0e0-1445-4013-8a0c-d673dee63da5
777 lines
17 KiB
C
777 lines
17 KiB
C
#include "quakedef.h"
|
|
#ifdef SWQUAKE
|
|
#include "sw.h"
|
|
|
|
#include "winquake.h"
|
|
/*Fixup outdated windows headers*/
|
|
#ifndef WM_XBUTTONDOWN
|
|
#define WM_XBUTTONDOWN 0x020B
|
|
#define WM_XBUTTONUP 0x020C
|
|
#endif
|
|
#ifndef MK_XBUTTON1
|
|
#define MK_XBUTTON1 0x0020
|
|
#endif
|
|
#ifndef MK_XBUTTON2
|
|
#define MK_XBUTTON2 0x0040
|
|
#endif
|
|
// copied from DarkPlaces in an attempt to grab more buttons
|
|
#ifndef MK_XBUTTON3
|
|
#define MK_XBUTTON3 0x0080
|
|
#endif
|
|
#ifndef MK_XBUTTON4
|
|
#define MK_XBUTTON4 0x0100
|
|
#endif
|
|
#ifndef MK_XBUTTON5
|
|
#define MK_XBUTTON5 0x0200
|
|
#endif
|
|
#ifndef MK_XBUTTON6
|
|
#define MK_XBUTTON6 0x0400
|
|
#endif
|
|
#ifndef MK_XBUTTON7
|
|
#define MK_XBUTTON7 0x0800
|
|
#endif
|
|
#ifndef WM_INPUT
|
|
#define WM_INPUT 255
|
|
#endif
|
|
|
|
|
|
|
|
typedef struct dibinfo
|
|
{
|
|
BITMAPINFOHEADER header;
|
|
RGBQUAD acolors[256];
|
|
} dibinfo_t;
|
|
|
|
//struct
|
|
//{
|
|
HBITMAP hDIBSection;
|
|
qbyte *pDIBBase;
|
|
|
|
HDC mainhDC;
|
|
HDC hdcDIBSection;
|
|
HGDIOBJ previously_selected_GDI_obj;
|
|
|
|
int framenumber;
|
|
void *screenbuffer;
|
|
qintptr_t screenpitch;
|
|
int window_x, window_y;
|
|
unsigned int *depthbuffer;
|
|
struct
|
|
{
|
|
qboolean isfullscreen;
|
|
} w32sw;
|
|
HWND mainwindow;
|
|
|
|
void DIB_Shutdown(void)
|
|
{
|
|
if (depthbuffer)
|
|
{
|
|
BZ_Free(depthbuffer);
|
|
depthbuffer = NULL;
|
|
}
|
|
|
|
if (hdcDIBSection)
|
|
{
|
|
SelectObject(hdcDIBSection, previously_selected_GDI_obj);
|
|
DeleteDC(hdcDIBSection);
|
|
hdcDIBSection = NULL;
|
|
}
|
|
|
|
if (hDIBSection)
|
|
{
|
|
DeleteObject(hDIBSection);
|
|
hDIBSection = NULL;
|
|
pDIBBase = NULL;
|
|
}
|
|
|
|
if (mainhDC)
|
|
{
|
|
ReleaseDC(mainwindow, mainhDC);
|
|
mainhDC = 0;
|
|
}
|
|
}
|
|
qboolean DIB_Init(void)
|
|
{
|
|
dibinfo_t dibheader;
|
|
BITMAPINFO *pbmiDIB = ( BITMAPINFO * ) &dibheader;
|
|
int i;
|
|
|
|
memset( &dibheader, 0, sizeof( dibheader ) );
|
|
|
|
/*
|
|
** grab a DC
|
|
*/
|
|
if ( !mainhDC )
|
|
{
|
|
if ( ( mainhDC = GetDC( mainwindow ) ) == NULL )
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
** fill in the BITMAPINFO struct
|
|
*/
|
|
pbmiDIB->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
|
pbmiDIB->bmiHeader.biWidth = vid.pixelwidth;
|
|
pbmiDIB->bmiHeader.biHeight = vid.pixelheight;
|
|
pbmiDIB->bmiHeader.biPlanes = 1;
|
|
pbmiDIB->bmiHeader.biBitCount = 32;
|
|
pbmiDIB->bmiHeader.biCompression = BI_RGB;
|
|
pbmiDIB->bmiHeader.biSizeImage = 0;
|
|
pbmiDIB->bmiHeader.biXPelsPerMeter = 0;
|
|
pbmiDIB->bmiHeader.biYPelsPerMeter = 0;
|
|
pbmiDIB->bmiHeader.biClrUsed = 0;
|
|
pbmiDIB->bmiHeader.biClrImportant = 0;
|
|
|
|
/*
|
|
** fill in the palette
|
|
*/
|
|
for ( i = 0; i < 256; i++ )
|
|
{
|
|
dibheader.acolors[i].rgbRed = ( d_8to24rgbtable[i] >> 0 ) & 0xff;
|
|
dibheader.acolors[i].rgbGreen = ( d_8to24rgbtable[i] >> 8 ) & 0xff;
|
|
dibheader.acolors[i].rgbBlue = ( d_8to24rgbtable[i] >> 16 ) & 0xff;
|
|
}
|
|
|
|
/*
|
|
** create the DIB section
|
|
*/
|
|
hDIBSection = CreateDIBSection( mainhDC,
|
|
pbmiDIB,
|
|
DIB_RGB_COLORS,
|
|
(void**)&pDIBBase,
|
|
NULL,
|
|
0 );
|
|
|
|
if ( hDIBSection == NULL )
|
|
{
|
|
Con_Printf( "DIB_Init() - CreateDIBSection failed\n" );
|
|
goto fail;
|
|
}
|
|
|
|
if (pbmiDIB->bmiHeader.biHeight < 0)
|
|
{
|
|
// bottom up
|
|
screenbuffer = pDIBBase + ( vid.pixelheight - 1 ) * vid.pixelwidth * 4;
|
|
screenpitch = -(int)vid.pixelwidth;
|
|
}
|
|
else
|
|
{
|
|
// top down
|
|
screenbuffer = pDIBBase;
|
|
screenpitch = vid.pixelwidth;
|
|
}
|
|
|
|
/*
|
|
** clear the DIB memory buffer
|
|
*/
|
|
memset( pDIBBase, 0, vid.pixelwidth * vid.pixelheight * 4);
|
|
|
|
if ( ( hdcDIBSection = CreateCompatibleDC( mainhDC ) ) == NULL )
|
|
{
|
|
Con_Printf( "DIB_Init() - CreateCompatibleDC failed\n" );
|
|
goto fail;
|
|
}
|
|
if ( ( previously_selected_GDI_obj = SelectObject( hdcDIBSection, hDIBSection ) ) == NULL )
|
|
{
|
|
Con_Printf( "DIB_Init() - SelectObject failed\n" );
|
|
goto fail;
|
|
}
|
|
|
|
depthbuffer = BZ_Malloc(vid.pixelwidth * vid.pixelheight * sizeof(*depthbuffer));
|
|
if (depthbuffer)
|
|
return true;
|
|
|
|
fail:
|
|
DIB_Shutdown();
|
|
return false;
|
|
}
|
|
void DIB_SwapBuffers(void)
|
|
{
|
|
// extern float usingstretch;
|
|
|
|
// if (usingstretch == 1)
|
|
BitBlt( mainhDC,
|
|
0, 0,
|
|
vid.pixelwidth,
|
|
vid.pixelheight,
|
|
hdcDIBSection,
|
|
0, 0,
|
|
SRCCOPY );
|
|
/* else
|
|
StretchBlt( mainhDC, //Why is StretchBlt not optimised for a scale of 2? Surly that would be a frequently used quantity?
|
|
0, 0,
|
|
vid.width*usingstretch,
|
|
vid.height*usingstretch,
|
|
hdcDIBSection,
|
|
0, 0,
|
|
vid.width, vid.height,
|
|
SRCCOPY );
|
|
*/
|
|
}
|
|
|
|
extern int window_width;
|
|
extern int window_height;
|
|
void SWV_UpdateWindowStatus(void)
|
|
{
|
|
POINT p;
|
|
RECT nr;
|
|
RECT WindowRect;
|
|
GetClientRect(mainwindow, &nr);
|
|
|
|
//if its bad then we're probably minimised
|
|
if (nr.right <= nr.left)
|
|
return;
|
|
if (nr.bottom <= nr.top)
|
|
return;
|
|
|
|
WindowRect = nr;
|
|
p.x = 0;
|
|
p.y = 0;
|
|
ClientToScreen(mainwindow, &p);
|
|
window_x = p.x;
|
|
window_y = p.y;
|
|
window_width = WindowRect.right - WindowRect.left;
|
|
window_height = WindowRect.bottom - WindowRect.top;
|
|
|
|
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;
|
|
|
|
INS_UpdateClipCursor ();
|
|
}
|
|
|
|
|
|
qboolean SWAppActivate(BOOL fActive, BOOL minimize)
|
|
/****************************************************************************
|
|
*
|
|
* Function: AppActivate
|
|
* Parameters: fActive - True if app is activating
|
|
*
|
|
* Description: If the application is activating, then swap the system
|
|
* into SYSPAL_NOSTATIC mode so that our palettes will display
|
|
* correctly.
|
|
*
|
|
****************************************************************************/
|
|
{
|
|
static BOOL sound_active;
|
|
|
|
if (ActiveApp == fActive && Minimized == minimize)
|
|
return false; //so windows doesn't crash us over and over again.
|
|
|
|
ActiveApp = fActive;
|
|
Minimized = minimize;
|
|
|
|
// enable/disable sound on focus gain/loss
|
|
if (!ActiveApp && sound_active)
|
|
{
|
|
S_BlockSound ();
|
|
sound_active = false;
|
|
}
|
|
else if (ActiveApp && !sound_active)
|
|
{
|
|
S_UnblockSound ();
|
|
sound_active = true;
|
|
}
|
|
|
|
INS_UpdateGrabs(false, ActiveApp);
|
|
|
|
/*
|
|
if (fActive)
|
|
{
|
|
if (modestate != MS_WINDOWED)
|
|
{
|
|
if (vid_canalttab && vid_wassuspended) {
|
|
vid_wassuspended = false;
|
|
ChangeDisplaySettings (&gdevmode, CDS_FULLSCREEN);
|
|
ShowWindow(mainwindow, SW_SHOWNORMAL);
|
|
}
|
|
}
|
|
}
|
|
if (!fActive)
|
|
{
|
|
if (modestate != MS_WINDOWED)
|
|
{
|
|
if (vid_canalttab) {
|
|
ChangeDisplaySettings (NULL, 0);
|
|
vid_wassuspended = true;
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
return true;
|
|
}
|
|
|
|
LONG WINAPI MainWndProc (
|
|
HWND hWnd,
|
|
UINT uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam)
|
|
{
|
|
LONG lRet = 0;
|
|
int fActive, fMinimized, temp;
|
|
HDC hdc;
|
|
PAINTSTRUCT ps;
|
|
extern unsigned int uiWheelMessage;
|
|
// static int recursiveflag;
|
|
|
|
if ( uMsg == uiWheelMessage ) {
|
|
uMsg = WM_MOUSEWHEEL;
|
|
wParam <<= 16;
|
|
}
|
|
|
|
switch (uMsg)
|
|
{
|
|
case WM_CREATE:
|
|
break;
|
|
|
|
case WM_SYSCOMMAND:
|
|
|
|
// Check for maximize being hit
|
|
switch (wParam & ~0x0F)
|
|
{
|
|
case SC_MAXIMIZE:
|
|
Cbuf_AddText("vid_fullscreen 1;vid_restart\n", RESTRICT_LOCAL);
|
|
// if minimized, bring up as a window before going fullscreen,
|
|
// so MGL will have the right state to restore
|
|
/* if (Minimized)
|
|
{
|
|
force_mode_set = true;
|
|
VID_SetMode (vid_modenum, vid_curpal);
|
|
force_mode_set = false;
|
|
}
|
|
|
|
VID_SetMode ((int)vid_fullscreen_mode.value, vid_curpal);
|
|
*/ break;
|
|
|
|
case SC_SCREENSAVE:
|
|
case SC_MONITORPOWER:
|
|
if (w32sw.isfullscreen)
|
|
{
|
|
// don't call DefWindowProc() because we don't want to start
|
|
// the screen saver fullscreen
|
|
break;
|
|
}
|
|
|
|
// fall through windowed and allow the screen saver to start
|
|
|
|
default:
|
|
// if (!vid_initializing)
|
|
// {
|
|
// S_BlockSound ();
|
|
// }
|
|
|
|
lRet = DefWindowProc (hWnd, uMsg, wParam, lParam);
|
|
|
|
// if (!vid_initializing)
|
|
// {
|
|
// S_UnblockSound ();
|
|
// }
|
|
}
|
|
break;
|
|
|
|
case WM_MOVE:
|
|
SWV_UpdateWindowStatus ();
|
|
|
|
// if ((modestate == MS_WINDOWED) && !in_mode_set && !Minimized)
|
|
// VID_RememberWindowPos ();
|
|
|
|
break;
|
|
|
|
case WM_SIZE:
|
|
SWV_UpdateWindowStatus ();
|
|
/* Minimized = false;
|
|
|
|
if (!(wParam & SIZE_RESTORED))
|
|
{
|
|
if (wParam & SIZE_MINIMIZED)
|
|
Minimized = true;
|
|
}
|
|
|
|
if (!Minimized && !w32sw.isfullscreen)
|
|
{
|
|
int nt, nl;
|
|
int nw, nh;
|
|
qboolean move = false;
|
|
RECT r;
|
|
GetClientRect (hWnd, &r);
|
|
nw = (int)(r.right - r.left)&~3;
|
|
nh = (int)(r.bottom - r.top)&~3;
|
|
|
|
window_width = nw;
|
|
window_height = nh;
|
|
VID2_UpdateWindowStatus();
|
|
|
|
if (nw < 320)
|
|
{
|
|
move = true;
|
|
nw = 320;
|
|
}
|
|
if (nh < 200)
|
|
{
|
|
move = true;
|
|
nh = 200;
|
|
}
|
|
if (nh > MAXHEIGHT)
|
|
{
|
|
move = true;
|
|
nh = MAXHEIGHT;
|
|
}
|
|
if ((r.right - r.left) & 3)
|
|
move = true;
|
|
if ((r.bottom - r.top) & 3)
|
|
move = true;
|
|
|
|
GetWindowRect (hWnd, &r);
|
|
nl = r.left;
|
|
nt = r.top;
|
|
r.left =0;
|
|
r.top = 0;
|
|
r.right = nw*usingstretch;
|
|
r.bottom = nh*usingstretch;
|
|
AdjustWindowRectEx(&r, WS_OVERLAPPEDWINDOW, FALSE, 0);
|
|
vid.recalc_refdef = true;
|
|
if (move)
|
|
MoveWindow(hWnd, nl, nt, r.right - r.left, r.bottom - r.top, true);
|
|
else
|
|
{
|
|
if (vid.width != nw || vid.height != nh)
|
|
{
|
|
M_RemoveAllMenus(); //can cause probs
|
|
DIB_Shutdown();
|
|
vid.conwidth = vid.width = nw;//vid_stretch.value;
|
|
vid.conheight = vid.height = nh;///vid_stretch.value;
|
|
|
|
DIB_Init( &vid.buffer, &vid.rowbytes );
|
|
vid.conbuffer = vid.buffer;
|
|
vid.conrowbytes = vid.rowbytes;
|
|
|
|
if (VID_AllocBuffers(vid.width, vid.height, r_pixbytes))
|
|
D_InitCaches (vid_surfcache, vid_surfcachesize);
|
|
|
|
SCR_UpdateWholeScreen();
|
|
}
|
|
else
|
|
SCR_UpdateWholeScreen();
|
|
}
|
|
|
|
}
|
|
*/
|
|
break;
|
|
|
|
case WM_SYSCHAR:
|
|
// keep Alt-Space from happening
|
|
break;
|
|
|
|
case WM_ACTIVATE:
|
|
fActive = LOWORD(wParam);
|
|
fMinimized = (BOOL) HIWORD(wParam);
|
|
SWAppActivate(!(fActive == WA_INACTIVE), fMinimized);
|
|
|
|
// fix the leftover Alt from any Alt-Tab or the like that switched us away
|
|
// ClearAllStates ();
|
|
|
|
break;
|
|
|
|
case WM_PAINT:
|
|
hdc = BeginPaint(hWnd, &ps);
|
|
|
|
// if (!in_mode_set && host_initialized)
|
|
// SCR_UpdateWholeScreen ();
|
|
|
|
EndPaint(hWnd, &ps);
|
|
break;
|
|
|
|
case WM_KEYDOWN:
|
|
case WM_SYSKEYDOWN:
|
|
// if (!vid_initializing)
|
|
INS_TranslateKeyEvent(wParam, lParam, true, 0);
|
|
break;
|
|
|
|
case WM_KEYUP:
|
|
case WM_SYSKEYUP:
|
|
// if (!vid_initializing)
|
|
INS_TranslateKeyEvent(wParam, lParam, false, 0);
|
|
break;
|
|
|
|
// this is complicated because Win32 seems to pack multiple mouse events into
|
|
// one update sometimes, so we always check all states and look for events
|
|
case WM_LBUTTONDOWN:
|
|
case WM_LBUTTONUP:
|
|
case WM_RBUTTONDOWN:
|
|
case WM_RBUTTONUP:
|
|
case WM_MBUTTONDOWN:
|
|
case WM_MBUTTONUP:
|
|
case WM_MOUSEMOVE:
|
|
case WM_XBUTTONDOWN:
|
|
case WM_XBUTTONUP:
|
|
// if (!vid_initializing)
|
|
{
|
|
temp = 0;
|
|
|
|
if (wParam & MK_LBUTTON)
|
|
temp |= 1;
|
|
|
|
if (wParam & MK_RBUTTON)
|
|
temp |= 2;
|
|
|
|
if (wParam & MK_MBUTTON)
|
|
temp |= 4;
|
|
|
|
// extra buttons
|
|
if (wParam & MK_XBUTTON1)
|
|
temp |= 8;
|
|
|
|
if (wParam & MK_XBUTTON2)
|
|
temp |= 16;
|
|
|
|
if (wParam & MK_XBUTTON3)
|
|
temp |= 32;
|
|
|
|
if (wParam & MK_XBUTTON4)
|
|
temp |= 64;
|
|
|
|
if (wParam & MK_XBUTTON5)
|
|
temp |= 128;
|
|
|
|
if (wParam & MK_XBUTTON6)
|
|
temp |= 256;
|
|
|
|
if (wParam & MK_XBUTTON7)
|
|
temp |= 512;
|
|
|
|
INS_MouseEvent (temp);
|
|
}
|
|
break;
|
|
// JACK: This is the mouse wheel with the Intellimouse
|
|
// Its delta is either positive or neg, and we generate the proper
|
|
// Event.
|
|
case WM_MOUSEWHEEL:
|
|
{
|
|
if ((short) HIWORD(wParam) > 0)
|
|
{
|
|
Key_Event(0, K_MWHEELUP, 0, true);
|
|
Key_Event(0, K_MWHEELUP, 0, false);
|
|
}
|
|
else
|
|
{
|
|
Key_Event(0, K_MWHEELDOWN, 0, true);
|
|
Key_Event(0, K_MWHEELDOWN, 0, false);
|
|
}
|
|
}
|
|
break;
|
|
case WM_INPUT:
|
|
// raw input handling
|
|
INS_RawInput_Read((HANDLE)lParam);
|
|
break;
|
|
/* case WM_DISPLAYCHANGE:
|
|
if (!in_mode_set && (modestate == MS_WINDOWED) && !vid_fulldib_on_focus_mode)
|
|
{
|
|
force_mode_set = true;
|
|
VID_SetMode (vid_modenum, vid_curpal);
|
|
force_mode_set = false;
|
|
}
|
|
break;
|
|
*/
|
|
case WM_CLOSE:
|
|
// this causes Close in the right-click task bar menu not to work, but right
|
|
// now bad things happen if Close is handled in that case (garbage and a
|
|
// crash on Win95)
|
|
// if (!vid_initializing)
|
|
{
|
|
if (MessageBox (mainwindow, "Are you sure you want to quit?", "Confirm Exit",
|
|
MB_YESNO | MB_SETFOREGROUND | MB_ICONQUESTION) == IDYES)
|
|
{
|
|
Cbuf_AddText("\nquit\n", RESTRICT_LOCAL);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case MM_MCINOTIFY:
|
|
lRet = CDAudio_MessageHandler (hWnd, uMsg, wParam, lParam);
|
|
break;
|
|
|
|
default:
|
|
/* pass all unhandled messages to DefWindowProc */
|
|
lRet = DefWindowProc (hWnd, uMsg, wParam, lParam);
|
|
break;
|
|
}
|
|
|
|
/* return 0 if handled message, 1 if not */
|
|
return lRet;
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
** VID_CreateWindow
|
|
*/
|
|
#define WINDOW_CLASS_NAME FULLENGINENAME
|
|
#define WINDOW_TITLE_NAME FULLENGINENAME
|
|
|
|
|
|
void VID_CreateWindow(int width, int height, qboolean fullscreen)
|
|
{
|
|
WNDCLASS wc;
|
|
RECT r;
|
|
int x, y, w, h;
|
|
int exstyle;
|
|
int stylebits;
|
|
|
|
|
|
if (fullscreen)
|
|
{
|
|
exstyle = WS_EX_TOPMOST;
|
|
stylebits = WS_POPUP;
|
|
}
|
|
else
|
|
{
|
|
exstyle = 0;
|
|
stylebits = WS_OVERLAPPEDWINDOW;
|
|
}
|
|
|
|
/* Register the frame class */
|
|
wc.style = 0;
|
|
wc.lpfnWndProc = (WNDPROC)MainWndProc;
|
|
wc.cbClsExtra = 0;
|
|
wc.cbWndExtra = 0;
|
|
wc.hInstance = global_hInstance;
|
|
wc.hIcon = 0;
|
|
wc.hCursor = LoadCursor (NULL,IDC_ARROW);
|
|
wc.hbrBackground = (void *)COLOR_GRAYTEXT;
|
|
wc.lpszMenuName = 0;
|
|
wc.lpszClassName = WINDOW_CLASS_NAME;
|
|
|
|
RegisterClass(&wc);
|
|
|
|
r.left = 0;
|
|
r.top = 0;
|
|
r.right = width;
|
|
r.bottom = height;
|
|
|
|
AdjustWindowRectEx (&r, stylebits, FALSE, exstyle);
|
|
|
|
window_rect = r;
|
|
|
|
w = r.right - r.left;
|
|
h = r.bottom - r.top;
|
|
x = 0;//vid_xpos.value;
|
|
y = 0;//vid_ypos.value;
|
|
|
|
mainwindow = CreateWindowEx(
|
|
exstyle,
|
|
WINDOW_CLASS_NAME,
|
|
WINDOW_TITLE_NAME,
|
|
stylebits,
|
|
x, y, w, h,
|
|
NULL,
|
|
NULL,
|
|
global_hInstance,
|
|
NULL);
|
|
|
|
if (!mainwindow)
|
|
Sys_Error("Couldn't create window");
|
|
|
|
ShowWindow(mainwindow, SW_SHOWNORMAL);
|
|
UpdateWindow(mainwindow);
|
|
SetForegroundWindow(mainwindow);
|
|
SetFocus(mainwindow);
|
|
|
|
SWV_UpdateWindowStatus();
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void SW_VID_UpdateViewport(wqcom_t *com)
|
|
{
|
|
com->viewport.cbuf = screenbuffer;
|
|
com->viewport.dbuf = depthbuffer;
|
|
com->viewport.width = vid.pixelwidth;
|
|
com->viewport.height = vid.pixelheight;
|
|
com->viewport.stride = screenpitch;
|
|
com->viewport.framenum = framenumber;
|
|
|
|
/* com->viewport.buf = pDIBBase;
|
|
com->viewport.width = vid.pixelwidth;
|
|
com->viewport.height = vid.pixelheight;
|
|
com->viewport.stride = vid.pixelwidth;
|
|
com->viewport.framenum = framenumber;*/
|
|
}
|
|
|
|
void SW_VID_SwapBuffers(void)
|
|
{
|
|
extern cvar_t vid_conautoscale;
|
|
DIB_SwapBuffers();
|
|
framenumber++;
|
|
|
|
INS_UpdateGrabs(false, ActiveApp);
|
|
|
|
// memset( pDIBBase, 0, vid.pixelwidth * vid.pixelheight * 4);
|
|
|
|
|
|
if (window_width != vid.pixelwidth || window_height != vid.pixelheight)
|
|
{
|
|
DIB_Shutdown();
|
|
vid.pixelwidth = window_width;
|
|
vid.pixelheight = window_height;
|
|
if (!DIB_Init())
|
|
Sys_Error("resize reinitialization error");
|
|
|
|
Cvar_ForceCallback(&vid_conautoscale);
|
|
}
|
|
}
|
|
|
|
qboolean SW_VID_Init(rendererstate_t *info, unsigned char *palette)
|
|
{
|
|
vid.pixelwidth = info->width;
|
|
vid.pixelheight = info->height;
|
|
|
|
VID_CreateWindow(vid.pixelwidth, vid.pixelheight, false);
|
|
|
|
if (!DIB_Init())
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
void SW_VID_DeInit(void)
|
|
{
|
|
DIB_Shutdown();
|
|
DestroyWindow(mainwindow);
|
|
}
|
|
void SW_VID_SetPalette(unsigned char *palette)
|
|
{
|
|
}
|
|
void SW_VID_ShiftPalette(unsigned char *palette)
|
|
{
|
|
}
|
|
char *SW_VID_GetRGBInfo(int prepad, int *truevidwidth, int *truevidheight)
|
|
{
|
|
char *buf = NULL;
|
|
char *src, *dst;
|
|
int w, h;
|
|
buf = BZ_Malloc(prepad + (vid.pixelwidth * vid.pixelheight * 3));
|
|
dst = buf + prepad;
|
|
for (h = 0; h < vid.pixelheight; h++)
|
|
{
|
|
for (w = 0, src = (char*)screenbuffer + (h * vid.pixelwidth*4); w < vid.pixelwidth; w++, dst += 3, src += 4)
|
|
{
|
|
dst[0] = src[2];
|
|
dst[1] = src[1];
|
|
dst[2] = src[0];
|
|
}
|
|
}
|
|
*truevidwidth = vid.pixelwidth;
|
|
*truevidheight = vid.pixelheight;
|
|
return buf;
|
|
}
|
|
void SW_VID_SetWindowCaption(char *msg)
|
|
{
|
|
}
|
|
#endif
|