This commit is contained in:
Nishi 2026-05-12 23:38:18 +09:00
commit 39d6fde32d
Signed by: nishi
GPG key ID: 27EF69B208EB9343
14 changed files with 434 additions and 1398 deletions

4
.gitignore vendored
View file

@ -1,3 +1,3 @@
*.o
/mwquake
/id1/mwquake
/build
/id1/gquake

25
CMakeLists.txt Normal file
View file

@ -0,0 +1,25 @@
cmake_minimum_required(VERSION 3.25)
project(gquake)
file(GLOB SOURCES src/*.c)
find_package(OpenGL REQUIRED)
set(MILSKO "/usr/local")
option(TRY_SDL2 "Try SDL2" ON)
add_executable(gquake ${SOURCES})
target_include_directories(gquake PRIVATE include)
target_compile_definitions(gquake PRIVATE GL_EXT_SHARED GLQUAKE)
target_link_libraries(gquake PRIVATE OpenGL::GL)
find_package(SDL2 OPTIONAL)
if(SDL2_FOUND AND TRY_SDL2)
target_compile_definitions(gquake PRIVATE USE_SDL2)
target_link_libraries(gquake PRIVATE SDL2::SDL2)
else()
target_compile_definitions(gquake PRIVATE USE_MILSKO USE_MINIAUDIO)
target_include_directories(gquake PRIVATE ${MILSKO}/include)
target_link_directories(gquake PRIVATE ${MILSKO}/src ${MILSKO}/lib)
target_link_libraries(gquake PRIVATE Mw)
endif()

View file

@ -1,23 +0,0 @@
# $Id$
MILSKO = /usr/local
.PHONY: all clean
.SUFFIXES: .c .o
CC = cc
CFLAGS = -Iinclude -DGLQUAKE -I/usr/X11R7/include -I$(MILSKO)/include
LDFLAGS = -L/usr/X11R7/lib -L$(MILSKO)/src -L$(MILSKO)/lib
LIBS = -lMw -lGL -lm
OBJS = src/cl_demo.o src/cl_input.o src/cl_main.o src/cl_parse.o src/cl_tent.o src/chase.o src/cmd.o src/common.o src/console.o src/crc.o src/cvar.o src/gl_draw.o src/gl_mesh.o src/gl_model.o src/gl_refrag.o src/gl_rlight.o src/gl_rmain.o src/gl_rmisc.o src/gl_rsurf.o src/gl_screen.o src/gl_test.o src/gl_warp.o src/host.o src/host_cmd.o src/keys.o src/menu.o src/mathlib.o src/net_dgrm.o src/net_loop.o src/net_main.o src/net_vcr.o src/pr_cmds.o src/pr_edict.o src/pr_exec.o src/r_part.o src/sbar.o src/sv_main.o src/sv_phys.o src/sv_move.o src/sv_user.o src/zone.o src/view.o src/wad.o src/world.o src/cd.o src/sound.o src/gl.o src/stb_ds.o src/snd_mem.o src/mix.o src/miniaudio.o src/snd_ma.o src/net_udp.o src/net_bsd.o src/sys.o
all: mwquake
clean:
rm -f $(OBJS) quake
mwquake: $(OBJS)
$(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
.c.o:
$(CC) $(CFLAGS) -c -o $@ $<

View file

@ -55,6 +55,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define K_PGUP 150
#define K_HOME 151
#define K_END 152
#define K_SUPER 153
#define K_PAUSE 255

View file

@ -22,6 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//#define GLTEST // experimental stuff
#define QUAKE_GAME // as opposed to utilities
#define QUAKE_PREFIX "gquake/"
#ifdef _WIN32
#define OEMRESOURCE
@ -334,3 +335,23 @@ extern cvar_t chase_active;
void Chase_Init (void);
void Chase_Reset (void);
void Chase_Update (void);
#ifdef USE_MILSKO
#include <Mw/Milsko.h>
#include <Mw/Widget/OpenGL.h>
#endif
#ifdef USE_SDL2
#include <SDL.h>
#include <SDL_audio.h>
#include <SDL_opengl.h>
#endif
extern qboolean mouse_active, fullscreen;
extern int mx, my;
void Port_Init(int width, int height);
void Port_Step(void);
void Port_GrabPointer(int toggle);
void Port_Shutdown(void);
void Port_SwapBuffer(void);

View file

@ -1,365 +0,0 @@
/*
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 the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// conproc.c
#include <windows.h>
#include "conproc.h"
#include "quakedef.h"
HANDLE heventDone;
HANDLE hfileBuffer;
HANDLE heventChildSend;
HANDLE heventParentSend;
HANDLE hStdout;
HANDLE hStdin;
DWORD RequestProc (DWORD dwNichts);
LPVOID GetMappedBuffer (HANDLE hfileBuffer);
void ReleaseMappedBuffer (LPVOID pBuffer);
BOOL GetScreenBufferLines (int *piLines);
BOOL SetScreenBufferLines (int iLines);
BOOL ReadText (LPTSTR pszText, int iBeginLine, int iEndLine);
BOOL WriteText (LPCTSTR szText);
int CharToCode (char c);
BOOL SetConsoleCXCY(HANDLE hStdout, int cx, int cy);
void InitConProc (HANDLE hFile, HANDLE heventParent, HANDLE heventChild)
{
DWORD dwID;
CONSOLE_SCREEN_BUFFER_INFO info;
int wheight, wwidth;
// ignore if we don't have all the events.
if (!hFile || !heventParent || !heventChild)
return;
hfileBuffer = hFile;
heventParentSend = heventParent;
heventChildSend = heventChild;
// so we'll know when to go away.
heventDone = CreateEvent (NULL, FALSE, FALSE, NULL);
if (!heventDone)
{
Con_SafePrintf ("Couldn't create heventDone\n");
return;
}
if (!CreateThread (NULL,
0,
(LPTHREAD_START_ROUTINE) RequestProc,
0,
0,
&dwID))
{
CloseHandle (heventDone);
Con_SafePrintf ("Couldn't create QHOST thread\n");
return;
}
// save off the input/output handles.
hStdout = GetStdHandle (STD_OUTPUT_HANDLE);
hStdin = GetStdHandle (STD_INPUT_HANDLE);
// force 80 character width, at least 25 character height
SetConsoleCXCY (hStdout, 80, 25);
}
void DeinitConProc (void)
{
if (heventDone)
SetEvent (heventDone);
}
DWORD RequestProc (DWORD dwNichts)
{
int *pBuffer;
DWORD dwRet;
HANDLE heventWait[2];
int iBeginLine, iEndLine;
heventWait[0] = heventParentSend;
heventWait[1] = heventDone;
while (1)
{
dwRet = WaitForMultipleObjects (2, heventWait, FALSE, INFINITE);
// heventDone fired, so we're exiting.
if (dwRet == WAIT_OBJECT_0 + 1)
break;
pBuffer = (int *) GetMappedBuffer (hfileBuffer);
// hfileBuffer is invalid. Just leave.
if (!pBuffer)
{
Con_SafePrintf ("Invalid hfileBuffer\n");
break;
}
switch (pBuffer[0])
{
case CCOM_WRITE_TEXT:
// Param1 : Text
pBuffer[0] = WriteText ((LPCTSTR) (pBuffer + 1));
break;
case CCOM_GET_TEXT:
// Param1 : Begin line
// Param2 : End line
iBeginLine = pBuffer[1];
iEndLine = pBuffer[2];
pBuffer[0] = ReadText ((LPTSTR) (pBuffer + 1), iBeginLine,
iEndLine);
break;
case CCOM_GET_SCR_LINES:
// No params
pBuffer[0] = GetScreenBufferLines (&pBuffer[1]);
break;
case CCOM_SET_SCR_LINES:
// Param1 : Number of lines
pBuffer[0] = SetScreenBufferLines (pBuffer[1]);
break;
}
ReleaseMappedBuffer (pBuffer);
SetEvent (heventChildSend);
}
return 0;
}
LPVOID GetMappedBuffer (HANDLE hfileBuffer)
{
LPVOID pBuffer;
pBuffer = MapViewOfFile (hfileBuffer,
FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
return pBuffer;
}
void ReleaseMappedBuffer (LPVOID pBuffer)
{
UnmapViewOfFile (pBuffer);
}
BOOL GetScreenBufferLines (int *piLines)
{
CONSOLE_SCREEN_BUFFER_INFO info;
BOOL bRet;
bRet = GetConsoleScreenBufferInfo (hStdout, &info);
if (bRet)
*piLines = info.dwSize.Y;
return bRet;
}
BOOL SetScreenBufferLines (int iLines)
{
return SetConsoleCXCY (hStdout, 80, iLines);
}
BOOL ReadText (LPTSTR pszText, int iBeginLine, int iEndLine)
{
COORD coord;
DWORD dwRead;
BOOL bRet;
coord.X = 0;
coord.Y = iBeginLine;
bRet = ReadConsoleOutputCharacter(
hStdout,
pszText,
80 * (iEndLine - iBeginLine + 1),
coord,
&dwRead);
// Make sure it's null terminated.
if (bRet)
pszText[dwRead] = '\0';
return bRet;
}
BOOL WriteText (LPCTSTR szText)
{
DWORD dwWritten;
INPUT_RECORD rec;
char upper, *sz;
sz = (LPTSTR) szText;
while (*sz)
{
// 13 is the code for a carriage return (\n) instead of 10.
if (*sz == 10)
*sz = 13;
upper = toupper(*sz);
rec.EventType = KEY_EVENT;
rec.Event.KeyEvent.bKeyDown = TRUE;
rec.Event.KeyEvent.wRepeatCount = 1;
rec.Event.KeyEvent.wVirtualKeyCode = upper;
rec.Event.KeyEvent.wVirtualScanCode = CharToCode (*sz);
rec.Event.KeyEvent.uChar.AsciiChar = *sz;
rec.Event.KeyEvent.uChar.UnicodeChar = *sz;
rec.Event.KeyEvent.dwControlKeyState = isupper(*sz) ? 0x80 : 0x0;
WriteConsoleInput(
hStdin,
&rec,
1,
&dwWritten);
rec.Event.KeyEvent.bKeyDown = FALSE;
WriteConsoleInput(
hStdin,
&rec,
1,
&dwWritten);
sz++;
}
return TRUE;
}
int CharToCode (char c)
{
char upper;
upper = toupper(c);
switch (c)
{
case 13:
return 28;
default:
break;
}
if (isalpha(c))
return (30 + upper - 65);
if (isdigit(c))
return (1 + upper - 47);
return c;
}
BOOL SetConsoleCXCY(HANDLE hStdout, int cx, int cy)
{
CONSOLE_SCREEN_BUFFER_INFO info;
COORD coordMax;
coordMax = GetLargestConsoleWindowSize(hStdout);
if (cy > coordMax.Y)
cy = coordMax.Y;
if (cx > coordMax.X)
cx = coordMax.X;
if (!GetConsoleScreenBufferInfo(hStdout, &info))
return FALSE;
// height
info.srWindow.Left = 0;
info.srWindow.Right = info.dwSize.X - 1;
info.srWindow.Top = 0;
info.srWindow.Bottom = cy - 1;
if (cy < info.dwSize.Y)
{
if (!SetConsoleWindowInfo(hStdout, TRUE, &info.srWindow))
return FALSE;
info.dwSize.Y = cy;
if (!SetConsoleScreenBufferSize(hStdout, info.dwSize))
return FALSE;
}
else if (cy > info.dwSize.Y)
{
info.dwSize.Y = cy;
if (!SetConsoleScreenBufferSize(hStdout, info.dwSize))
return FALSE;
if (!SetConsoleWindowInfo(hStdout, TRUE, &info.srWindow))
return FALSE;
}
if (!GetConsoleScreenBufferInfo(hStdout, &info))
return FALSE;
// width
info.srWindow.Left = 0;
info.srWindow.Right = cx - 1;
info.srWindow.Top = 0;
info.srWindow.Bottom = info.dwSize.Y - 1;
if (cx < info.dwSize.X)
{
if (!SetConsoleWindowInfo(hStdout, TRUE, &info.srWindow))
return FALSE;
info.dwSize.X = cx;
if (!SetConsoleScreenBufferSize(hStdout, info.dwSize))
return FALSE;
}
else if (cx > info.dwSize.X)
{
info.dwSize.X = cx;
if (!SetConsoleScreenBufferSize(hStdout, info.dwSize))
return FALSE;
if (!SetConsoleWindowInfo(hStdout, TRUE, &info.srWindow))
return FALSE;
}
return TRUE;
}

148
src/gl.c
View file

@ -25,25 +25,20 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "quakedef.h"
#include <Mw/Milsko.h>
#include <Mw/Widget/OpenGL.h>
#define WARP_WIDTH 320
#define WARP_HEIGHT 200
static MwWidget win;
static MwWidget opengl;
unsigned short d_8to16table[256];
unsigned d_8to24table[256];
unsigned char d_15to8table[65536];
static qboolean mouse_avail;
static qboolean mouse_active;
static int mx, my;
static int old_mouse_x, old_mouse_y;
qboolean mouse_active, fullscreen;
int mx, my;
qboolean dgamouse = qfalse;
qboolean vidmode_ext = qfalse;
@ -91,96 +86,17 @@ void D_EndDirectRect (int x, int y, int width, int height)
static void install_grabs(void)
{
MwHideCursor(opengl);
MwGrabPointer(opengl, 1);
Port_GrabPointer(1);
mouse_active = qtrue;
}
static void uninstall_grabs(void)
{
if (!win)
return;
MwGrabPointer(opengl, 0);
Port_GrabPointer(0);
mouse_active = qfalse;
}
static int MilskoToQuakeKey(int key){
if(key == MwKEY_ENTER) key = K_ENTER;
if(key == MwKEY_ESCAPE) key = K_ESCAPE;
if(key == MwKEY_BACKSPACE) key = K_BACKSPACE;
if(key == MwKEY_LEFT) key = K_LEFTARROW;
if(key == MwKEY_RIGHT) key = K_RIGHTARROW;
if(key == MwKEY_UP) key = K_UPARROW;
if(key == MwKEY_DOWN) key = K_DOWNARROW;
if(key == MwKEY_LEFTSHIFT) key = K_SHIFT;
if(key == MwKEY_RIGHTSHIFT) key = K_SHIFT;
if('A' <= key && key <= 'Z') return tolower(key);
return key;
}
static int MilskoToQuakeMouse(int btn){
int b = 0;
if(btn == MwMOUSE_LEFT) b = 0;
if(btn == MwMOUSE_MIDDLE) b = 2;
if(btn == MwMOUSE_RIGHT) b = 1;
if(btn == MwMOUSE_WHEELUP) return K_MWHEELUP;
if(btn == MwMOUSE_WHEELDOWN) return K_MWHEELDOWN;
return K_MOUSE1 + b;
}
void mousemove(MwWidget handle, void* user, void* call) {
MwPoint* p = call;
int vecX = p->x;
int vecY = p->y;
if (mouse_active) {
mx += vecX * 2;
my += vecY * 2;
}
}
void key(MwWidget handle, void* user, void* call){
int k = *(int*)call;
k = MilskoToQuakeKey(k);
if(k == -0xdead) return;
if(k & MwKEY_FLAG) return;
Key_Event(k, 1);
}
void keyrelease(MwWidget handle, void* user, void* call){
int k = *(int*)call;
k = MilskoToQuakeKey(k);
if(k == -0xdead) return;
if(k & MwKEY_FLAG) return;
Key_Event(k, 0);
}
void mousedown(MwWidget handle, void* user, void* call){
MwMouse* m = call;
Key_Event(MilskoToQuakeMouse(m->button), 1);
}
void mouseup(MwWidget handle, void* user, void* call){
MwMouse* m = call;
Key_Event(MilskoToQuakeMouse(m->button), 0);
}
void focusin(MwWidget handle, void* user, void* call){
if(mouse_active){
MwGrabPointer(opengl, 0);
MwGrabPointer(opengl, 1);
}
}
void focusout(MwWidget handle, void* user, void* call){
MwGrabPointer(opengl, 0);
}
static void HandleEvents(void)
{
int b;
@ -188,7 +104,7 @@ static void HandleEvents(void)
int mwx = vid.width/2;
int mwy = vid.height/2;
if(MwPending(win)) MwStep(win);
Port_Step();
if (dowarp) {
/* move the mouse to the window center again */
@ -198,7 +114,7 @@ static void HandleEvents(void)
static void IN_DeactivateMouse( void )
{
if (!mouse_avail || !win)
if (!mouse_avail)
return;
if (mouse_active) {
@ -209,7 +125,7 @@ static void IN_DeactivateMouse( void )
static void IN_ActivateMouse( void )
{
if (!mouse_avail || !win)
if (!mouse_avail)
return;
if (!mouse_active) {
@ -223,11 +139,8 @@ static void IN_ActivateMouse( void )
void VID_Shutdown(void)
{
IN_DeactivateMouse();
if (win) {
MwDestroyWidget(win);
}
Port_Shutdown();
vidmode_active = qfalse;
win = NULL;
}
void signal_handler(int sig)
@ -377,7 +290,7 @@ void GL_BeginRendering (int *x, int *y, int *width, int *height)
void GL_EndRendering (void)
{
glFlush();
MwOpenGLSwapBuffer(opengl);
Port_SwapBuffer();
}
qboolean VID_Is8bit(void)
@ -420,11 +333,10 @@ void VID_Init(unsigned char *palette)
char gldir[MAX_OSPATH];
int width = 640, height = 480;
unsigned long mask;
qboolean fullscreen = qtrue;
int MajorVersion, MinorVersion;
int actualWidth, actualHeight;
MwSizeHints sh;
MwWidget label;
fullscreen = qtrue;
mouse_avail = 1;
@ -433,8 +345,6 @@ void VID_Init(unsigned char *palette)
vid.colormap = host_colormap;
vid.fullbright = 256 - LittleLong (*((int *)vid.colormap + 2048));
MwLibraryInit();
// interpret command-line params
// set vid parameters
@ -465,33 +375,7 @@ void VID_Init(unsigned char *palette)
if (vid.conheight < 200)
vid.conheight = 200;
win = MwVaCreateWidget(MwWindowClass, "Quake", NULL, MwDEFAULT, MwDEFAULT, width, height + 24,
MwNtitle, "Quake",
NULL);
label = MwVaCreateWidget(MwLabelClass, "Label", win, 0, height, width, 24,
MwNtext, "Milsko Quake!",
NULL);
opengl = MwCreateWidget(MwOpenGLClass, "OpenGL", win, 0, 0, width, height);
sh.min_width = sh.max_width = width;
sh.min_height = sh.max_height = height + 24;
MwVaApply(win,
MwNsizeHints, &sh,
NULL);
MwOpenGLMakeCurrent(opengl);
MwAddUserHandler(opengl, MwNmouseMoveHandler, mousemove, NULL);
MwAddUserHandler(opengl, MwNkeyHandler, key, NULL);
MwAddUserHandler(opengl, MwNkeyReleaseHandler, keyrelease, NULL);
MwAddUserHandler(opengl, MwNmouseDownHandler, mousedown, NULL);
MwAddUserHandler(opengl, MwNmouseUpHandler, mouseup, NULL);
MwAddUserHandler(opengl, MwNfocusInHandler, focusin, NULL);
MwAddUserHandler(opengl, MwNfocusOutHandler, focusout, NULL);
if(fullscreen){
/* todo */
}
Port_Init(width, height);
scr_width = width;
scr_height = height;
@ -510,7 +394,7 @@ void VID_Init(unsigned char *palette)
GL_Init();
sprintf (gldir, "%s/mwquake", com_gamedir);
sprintf (gldir, "%s/%s", com_gamedir, QUAKE_PREFIX);
Sys_mkdir (gldir);
VID_SetPalette(palette);
@ -522,7 +406,6 @@ void VID_Init(unsigned char *palette)
void Sys_SendKeyEvents(void)
{
if(win == NULL) return;
HandleEvents();
}
@ -546,9 +429,6 @@ IN_Commands
*/
void IN_Commands (void)
{
if (!win)
return;
if (vidmode_active || key_dest == key_game)
IN_ActivateMouse();
else

View file

@ -304,8 +304,8 @@ void GL_MakeAliasModelDisplayLists (model_t *m, aliashdr_t *hdr)
//
// look for a cached version
//
strcpy (cache, "mwquake/");
COM_StripExtension (m->name+strlen("progs/"), cache+strlen("mwquake/"));
strcpy (cache, QUAKE_PREFIX);
COM_StripExtension (m->name+strlen("progs/"), cache+strlen(QUAKE_PREFIX));
strcat (cache, ".ms2");
COM_FOpenFile (cache, &f);

View file

@ -87,6 +87,7 @@ keyname_t keynames[] =
{"PGUP", K_PGUP},
{"HOME", K_HOME},
{"END", K_END},
{"SUPER", K_SUPER},
{"MOUSE1", K_MOUSE1},
{"MOUSE2", K_MOUSE2},

View file

@ -1,2 +1,4 @@
#ifdef USE_MINIAUDIO
#define MINIAUDIO_IMPLEMENTATION
#include "miniaudio.h"
#endif

239
src/port.c Normal file
View file

@ -0,0 +1,239 @@
#include "quakedef.h"
#ifdef USE_MILSKO
static MwWidget win = NULL;
static MwWidget opengl;
static int MilskoToQuakeKey(int key){
if(key == MwKEY_ENTER) key = K_ENTER;
if(key == MwKEY_ESCAPE) key = K_ESCAPE;
if(key == MwKEY_BACKSPACE) key = K_BACKSPACE;
if(key == MwKEY_LEFT) key = K_LEFTARROW;
if(key == MwKEY_RIGHT) key = K_RIGHTARROW;
if(key == MwKEY_UP) key = K_UPARROW;
if(key == MwKEY_DOWN) key = K_DOWNARROW;
if(key == MwKEY_LEFTSHIFT) key = K_SHIFT;
if(key == MwKEY_RIGHTSHIFT) key = K_SHIFT;
if(key == MwKEY_ALT) key = K_ALT;
if(key == MwKEY_CONTROL) key = K_CONTROL;
if('A' <= key && key <= 'Z') return tolower(key);
return key;
}
static int MilskoToQuakeMouse(int btn){
int b = 0;
if(btn == MwMOUSE_LEFT) b = 0;
if(btn == MwMOUSE_MIDDLE) b = 2;
if(btn == MwMOUSE_RIGHT) b = 1;
if(btn == MwMOUSE_WHEELUP) return K_MWHEELUP;
if(btn == MwMOUSE_WHEELDOWN) return K_MWHEELDOWN;
return K_MOUSE1 + b;
}
static void MWAPI mousemove(MwWidget handle, void* user, void* call) {
MwPoint* p = call;
int vecX = p->x;
int vecY = p->y;
if (mouse_active) {
mx += vecX * 2;
my += vecY * 2;
}
}
static void MWAPI key(MwWidget handle, void* user, void* call){
int k = *(int*)call;
k = MilskoToQuakeKey(k);
if(k == -0xdead) return;
if(k & MwKEY_FLAG) return;
Key_Event(k, 1);
}
static void MWAPI keyrelease(MwWidget handle, void* user, void* call){
int k = *(int*)call;
k = MilskoToQuakeKey(k);
if(k == -0xdead) return;
if(k & MwKEY_FLAG) return;
Key_Event(k, 0);
}
static void MWAPI mousedown(MwWidget handle, void* user, void* call){
MwMouse* m = call;
Key_Event(MilskoToQuakeMouse(m->button), 1);
}
static void MWAPI mouseup(MwWidget handle, void* user, void* call){
MwMouse* m = call;
Key_Event(MilskoToQuakeMouse(m->button), 0);
}
static void MWAPI focusin(MwWidget handle, void* user, void* call){
if(mouse_active){
MwGrabPointer(opengl, 0);
MwGrabPointer(opengl, 1);
}
}
static void MWAPI focusout(MwWidget handle, void* user, void* call){
MwGrabPointer(opengl, 0);
}
void Port_Init(int width, int height){
MwSizeHints sh;
MwWidget label;
MwLibraryInit();
win = MwVaCreateWidget(MwWindowClass, "Quake", NULL, MwDEFAULT, MwDEFAULT, width, height + 24,
MwNtitle, "Quake",
NULL);
label = MwVaCreateWidget(MwLabelClass, "Label", win, 0, height, width, 24,
MwNtext, "Milsko Quake!",
NULL);
opengl = MwCreateWidget(MwOpenGLClass, "OpenGL", win, 0, 0, width, height);
sh.min_width = sh.max_width = width;
sh.min_height = sh.max_height = height + 24;
MwVaApply(win,
MwNsizeHints, &sh,
NULL);
MwOpenGLMakeCurrent(opengl);
MwAddUserHandler(opengl, MwNmouseMoveHandler, mousemove, NULL);
MwAddUserHandler(opengl, MwNkeyHandler, key, NULL);
MwAddUserHandler(opengl, MwNkeyReleaseHandler, keyrelease, NULL);
MwAddUserHandler(opengl, MwNmouseDownHandler, mousedown, NULL);
MwAddUserHandler(opengl, MwNmouseUpHandler, mouseup, NULL);
MwAddUserHandler(opengl, MwNfocusInHandler, focusin, NULL);
MwAddUserHandler(opengl, MwNfocusOutHandler, focusout, NULL);
if(fullscreen){
/* todo */
}
}
void Port_Step(void){
if(!win) return;
if(MwPending(win)) MwStep(win);
}
void Port_GrabPointer(int toggle){
if(!win) return;
if(toggle){
MwHideCursor(opengl);
MwGrabPointer(opengl, 1);
}else{
MwGrabPointer(opengl, 0);
}
}
void Port_Shutdown(void){
if (win) {
MwDestroyWidget(win);
}
win = NULL;
}
void Port_SwapBuffer(void){
MwOpenGLSwapBuffer(opengl);
}
#endif
#ifdef USE_SDL2
static SDL_Window* win;
static SDL_GLContext context;
void Port_Init(int width, int height){
SDL_Init(SDL_INIT_VIDEO);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
win = SDL_CreateWindow("Quake", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL);
context = SDL_GL_CreateContext(win);
}
void Port_Step(void){
if(!win) return;
SDL_Event ev;
while(SDL_PollEvent(&ev)){
if(ev.type == SDL_MOUSEMOTION){
if (mouse_active) {
mx += ev.motion.xrel * 2;
my += ev.motion.yrel * 2;
}
}else if(ev.type == SDL_MOUSEBUTTONDOWN || ev.type == SDL_MOUSEBUTTONUP){
int b = 0;
int btn = ev.button.button;
if(btn == SDL_BUTTON_LEFT) b = 0;
if(btn == SDL_BUTTON_MIDDLE) b = 2;
if(btn == SDL_BUTTON_RIGHT) b = 1;
Key_Event(K_MOUSE1 + b, ev.type == SDL_MOUSEBUTTONDOWN);
}else if(ev.type == SDL_MOUSEWHEEL){
int k;
if(ev.wheel.y > 0){
k = K_MWHEELUP;
}else if(ev.wheel.y < 0){
k = K_MWHEELDOWN;
}
Key_Event(k, 1);
Key_Event(k, 0);
}else if(ev.type == SDL_KEYDOWN || ev.type == SDL_KEYUP){
int key = ev.key.keysym.sym;
if(key == SDLK_RETURN) key = K_ENTER;
if(key == SDLK_ESCAPE) key = K_ESCAPE;
if(key == SDLK_BACKSPACE) key = K_BACKSPACE;
if(key == SDLK_LEFT) key = K_LEFTARROW;
if(key == SDLK_RIGHT) key = K_RIGHTARROW;
if(key == SDLK_UP) key = K_UPARROW;
if(key == SDLK_DOWN) key = K_DOWNARROW;
if(key == SDLK_LSHIFT) key = K_SHIFT;
if(key == SDLK_RSHIFT) key = K_SHIFT;
if(key == SDLK_LALT) key = K_ALT;
if(key == SDLK_RALT) key = K_ALT;
if(key == SDLK_LCTRL) key = K_CTRL;
if(key == SDLK_RCTRL) key = K_CTRL;
if(key == SDLK_LGUI) key = K_SUPER;
if(key == SDLK_RGUI) key = K_SUPER;
if(SDLK_a <= key && key <= SDLK_z) key = key - SDLK_a + 'a';
if(SDLK_0 <= key && key <= SDLK_9) key = key - SDLK_0 + '0';
Key_Event(key, ev.type == SDL_KEYDOWN);
}
}
}
void Port_GrabPointer(int toggle){
if(toggle){
SDL_ShowCursor(0);
}
SDL_SetWindowMouseGrab(win, toggle);
SDL_SetWindowKeyboardGrab(win, toggle);
if(toggle){
SDL_SetRelativeMouseMode(SDL_TRUE);
SDL_SetHint(SDL_HINT_MOUSE_RELATIVE_MODE_WARP, "0");
}
}
void Port_Shutdown(void){
SDL_Quit();
}
void Port_SwapBuffer(void){
SDL_GL_SwapWindow(win);
}
#endif

View file

@ -17,6 +17,7 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifdef USE_MINIAUDIO
#include <miniaudio.h>
#define NEW_WAY
@ -37,7 +38,7 @@ int quit = 0;
unsigned char dma_buffer[BUFFER_SIZE];
ma_event ev;
ma_mutex mx;
ma_mutex mutex;
ma_bool8 ready = MA_FALSE;
@ -61,7 +62,7 @@ void data_callback(ma_device* device, void* out, const void* in, ma_uint32 frame
return;
}
ma_mutex_lock(&mx);
ma_mutex_lock(&mutex);
#ifdef NEW_WAY
if(arrlen(buffer_list) > 0){
buffer_t* buf = &buffer_list[0];
@ -102,7 +103,7 @@ void data_callback(ma_device* device, void* out, const void* in, ma_uint32 frame
total += bsz / 2;
#endif
ma_mutex_unlock(&mx);
ma_mutex_unlock(&mutex);
}
qboolean SNDDMA_Init(void)
@ -120,7 +121,7 @@ qboolean SNDDMA_Init(void)
}
ma_event_init(&ev);
ma_mutex_init(&mx);
ma_mutex_init(&mutex);
shm = &sn;
shm->splitbuffer = 0;
@ -186,7 +187,7 @@ void SNDDMA_Shutdown(void)
ma_device_uninit(&device);
snd_inited = 0;
ma_event_uninit(&ev);
ma_mutex_uninit(&mx);
ma_mutex_uninit(&mutex);
}
}
@ -213,13 +214,13 @@ void SNDDMA_Submit(void)
oldtime = paintedtime;
buf.buffer = malloc(buf.size);
ma_mutex_lock(&mx);
ma_mutex_lock(&mutex);
memcpy(buf.buffer, dma_buffer, buf.size);
arrput(buffer_list, buf);
ma_mutex_unlock(&mx);
ma_mutex_unlock(&mutex);
#else
ma_event_signal(&ev);
#endif
ready = MA_TRUE;
}
#endif

118
src/snd_sdl2.c Normal file
View file

@ -0,0 +1,118 @@
/*
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 the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifdef USE_SDL2
#include "quakedef.h"
int snd_inited;
int total = 0;
#define BUFFER_SIZE 4096*4
unsigned char dma_buffer[BUFFER_SIZE];
SDL_AudioSpec spec;
SDL_AudioDeviceID dev;
qboolean SNDDMA_Init(void)
{
int rc;
int fmt;
int tmp;
int i;
char *s;
int caps;
if (snd_inited) {
printf("Sound already init'd\n");
return 0;
}
shm = &sn;
shm->splitbuffer = 0;
Con_Printf("16 bit stereo sound initialized\n");
spec.freq = 44100;
spec.format = AUDIO_S16;
spec.channels = 2;
spec.samples = sizeof(dma_buffer) / 4;
spec.callback = NULL;
spec.userdata = NULL;
SDL_InitSubSystem(SDL_INIT_AUDIO);
dev = SDL_OpenAudioDevice(NULL, 0, &spec, NULL, 0);
shm->samplebits = 16;
shm->channels = 2;
shm->speed = spec.freq;
shm->soundalive = qtrue;
shm->samples = sizeof(dma_buffer) / (shm->samplebits/8);
shm->samplepos = 0;
shm->submission_chunk = 1;
shm->buffer = (unsigned char *)dma_buffer;
snd_inited = 1;
SDL_PauseAudioDevice(dev, 0);
return 1;
}
int SNDDMA_GetDMAPos(void)
{
return 0;
}
int SNDDMA_GetSamples(void)
{
return total;
}
void SNDDMA_Shutdown(void)
{
if (snd_inited) {
SDL_PauseAudioDevice(dev, 1);
SDL_ClearQueuedAudio(dev);
SDL_CloseAudioDevice(dev);
snd_inited = 0;
}
}
/*
==============
SNDDMA_Submit
Send sound to device if buffer isn't really the dma buffer
===============
*/
int oldtime = 0;
void SNDDMA_Submit(void)
{
int t1 = paintedtime;
int t2 = oldtime;
int sz;
if(SDL_GetQueuedAudioSize(dev)) return;
oldtime = paintedtime;
sz = (t1 - t2) * 4;
SDL_QueueAudio(dev, dma_buffer, sz);
total += sz / 4;
}
#endif

View file

@ -1,864 +0,0 @@
/*
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 the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// sys_win.c -- Win32 system interface code
#include "quakedef.h"
#include "errno.h"
#include "resource.h"
#include "conproc.h"
#include <direct.h>
#define CONSOLE_ERROR_TIMEOUT 60.0 // # of seconds to wait on Sys_Error running
// dedicated before exiting
#define PAUSE_SLEEP 50 // sleep time on pause or minimization
#define NOT_FOCUS_SLEEP 20 // sleep time when not focus
int starttime;
qboolean ActiveApp, Minimized;
qboolean WinNT;
static double pfreq;
static double curtime = 0.0;
static double lastcurtime = 0.0;
static int lowshift;
qboolean isDedicated;
static qboolean sc_return_on_enter = qfalse;
HANDLE hinput, houtput;
static char *tracking_tag = "Clams & Mooses";
static HANDLE tevent;
static HANDLE hFile;
static HANDLE heventParent;
static HANDLE heventChild;
void MaskExceptions (void);
void Sys_InitFloatTime (void);
void Sys_PushFPCW_SetHigh (void);
void Sys_PopFPCW (void);
volatile int sys_checksum;
int VID_ForceUnlockedAndReturnState(void){
return 0;
}
void VID_ForceLockState(int x){
(void)x;
}
/*
================
Sys_PageIn
================
*/
void Sys_PageIn (void *ptr, int size)
{
byte *x;
int j, m, n;
// touch all the memory to make sure it's there. The 16-page skip is to
// keep Win 95 from thinking we're trying to page ourselves in (we are
// doing that, of course, but there's no reason we shouldn't)
x = (byte *)ptr;
for (n=0 ; n<4 ; n++)
{
for (m=0 ; m<(size - 16 * 0x1000) ; m += 4)
{
sys_checksum += *(int *)&x[m];
sys_checksum += *(int *)&x[m + 16 * 0x1000];
}
}
}
/*
===============================================================================
FILE IO
===============================================================================
*/
#define MAX_HANDLES 10
FILE *sys_handles[MAX_HANDLES];
int findhandle (void)
{
int i;
for (i=1 ; i<MAX_HANDLES ; i++)
if (!sys_handles[i])
return i;
Sys_Error ("out of handles");
return -1;
}
/*
================
filelength
================
*/
int qfilelength (FILE *f)
{
int pos;
int end;
int t;
t = VID_ForceUnlockedAndReturnState ();
pos = ftell (f);
fseek (f, 0, SEEK_END);
end = ftell (f);
fseek (f, pos, SEEK_SET);
VID_ForceLockState (t);
return end;
}
int Sys_FileOpenRead (char *path, int *hndl)
{
FILE *f;
int i, retval;
int t;
t = VID_ForceUnlockedAndReturnState ();
i = findhandle ();
f = fopen(path, "rb");
if (!f)
{
*hndl = -1;
retval = -1;
}
else
{
sys_handles[i] = f;
*hndl = i;
retval = qfilelength(f);
}
VID_ForceLockState (t);
return retval;
}
int Sys_FileOpenWrite (char *path)
{
FILE *f;
int i;
int t;
t = VID_ForceUnlockedAndReturnState ();
i = findhandle ();
f = fopen(path, "wb");
if (!f)
Sys_Error ("Error opening %s: %s", path,strerror(errno));
sys_handles[i] = f;
VID_ForceLockState (t);
return i;
}
void Sys_FileClose (int handle)
{
int t;
t = VID_ForceUnlockedAndReturnState ();
fclose (sys_handles[handle]);
sys_handles[handle] = NULL;
VID_ForceLockState (t);
}
void Sys_FileSeek (int handle, int position)
{
int t;
t = VID_ForceUnlockedAndReturnState ();
fseek (sys_handles[handle], position, SEEK_SET);
VID_ForceLockState (t);
}
int Sys_FileRead (int handle, void *dest, int count)
{
int t, x;
t = VID_ForceUnlockedAndReturnState ();
x = fread (dest, 1, count, sys_handles[handle]);
VID_ForceLockState (t);
return x;
}
int Sys_FileWrite (int handle, void *data, int count)
{
int t, x;
t = VID_ForceUnlockedAndReturnState ();
x = fwrite (data, 1, count, sys_handles[handle]);
VID_ForceLockState (t);
return x;
}
int Sys_FileTime (char *path)
{
FILE *f;
int t, retval;
t = VID_ForceUnlockedAndReturnState ();
f = fopen(path, "rb");
if (f)
{
fclose(f);
retval = 1;
}
else
{
retval = -1;
}
VID_ForceLockState (t);
return retval;
}
void Sys_mkdir (char *path)
{
_mkdir (path);
}
/*
===============================================================================
SYSTEM IO
===============================================================================
*/
/*
================
Sys_MakeCodeWriteable
================
*/
void Sys_MakeCodeWriteable (unsigned long startaddr, unsigned long length)
{
DWORD flOldProtect;
if (!VirtualProtect((LPVOID)startaddr, length, PAGE_READWRITE, &flOldProtect))
Sys_Error("Protection change failed\n");
}
void Sys_SetFPCW (void)
{
}
void Sys_PushFPCW_SetHigh (void)
{
}
void Sys_PopFPCW (void)
{
}
void MaskExceptions (void)
{
}
/*
================
Sys_Init
================
*/
void Sys_Init (void)
{
LARGE_INTEGER PerformanceFreq;
unsigned int lowpart, highpart;
OSVERSIONINFO vinfo;
MaskExceptions ();
Sys_SetFPCW ();
if (!QueryPerformanceFrequency (&PerformanceFreq))
Sys_Error ("No hardware timer available");
// get 32 out of the 64 time bits such that we have around
// 1 microsecond resolution
lowpart = (unsigned int)PerformanceFreq.LowPart;
highpart = (unsigned int)PerformanceFreq.HighPart;
lowshift = 0;
while (highpart || (lowpart > 2000000.0))
{
lowshift++;
lowpart >>= 1;
lowpart |= (highpart & 1) << 31;
highpart >>= 1;
}
pfreq = 1.0 / (double)lowpart;
Sys_InitFloatTime ();
vinfo.dwOSVersionInfoSize = sizeof(vinfo);
if (!GetVersionEx (&vinfo))
Sys_Error ("Couldn't get OS info");
if ((vinfo.dwMajorVersion < 4) ||
(vinfo.dwPlatformId == VER_PLATFORM_WIN32s))
{
Sys_Error ("WinQuake requires at least Win95 or NT 4.0");
}
if (vinfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
WinNT = qtrue;
else
WinNT = qfalse;
}
void Sys_Error (char *error, ...)
{
va_list argptr;
char text[1024], text2[1024];
char *text3 = "Press Enter to exit\n";
char *text4 = "***********************************\n";
char *text5 = "\n";
DWORD dummy;
double starttime;
static int in_sys_error0 = 0;
static int in_sys_error1 = 0;
static int in_sys_error2 = 0;
static int in_sys_error3 = 0;
if (!in_sys_error3)
{
in_sys_error3 = 1;
VID_ForceUnlockedAndReturnState ();
}
va_start (argptr, error);
vsprintf (text, error, argptr);
va_end (argptr);
if (isDedicated)
{
va_start (argptr, error);
vsprintf (text, error, argptr);
va_end (argptr);
sprintf (text2, "ERROR: %s\n", text);
WriteFile (houtput, text5, strlen (text5), &dummy, NULL);
WriteFile (houtput, text4, strlen (text4), &dummy, NULL);
WriteFile (houtput, text2, strlen (text2), &dummy, NULL);
WriteFile (houtput, text3, strlen (text3), &dummy, NULL);
WriteFile (houtput, text4, strlen (text4), &dummy, NULL);
starttime = Sys_FloatTime ();
sc_return_on_enter = qtrue; // so Enter will get us out of here
while (!Sys_ConsoleInput () &&
((Sys_FloatTime () - starttime) < CONSOLE_ERROR_TIMEOUT))
{
}
}
else
{
// switch to windowed so the message box is visible, unless we already
// tried that and failed
if (!in_sys_error0)
{
in_sys_error0 = 1;
// VID_SetDefaultMode ();
MessageBox(NULL, text, "Quake Error",
MB_OK | MB_SETFOREGROUND | MB_ICONSTOP);
}
else
{
MessageBox(NULL, text, "Double Quake Error",
MB_OK | MB_SETFOREGROUND | MB_ICONSTOP);
}
}
if (!in_sys_error1)
{
in_sys_error1 = 1;
Host_Shutdown ();
}
// shut down QHOST hooks if necessary
if (!in_sys_error2)
{
in_sys_error2 = 1;
DeinitConProc ();
}
exit (1);
}
void Sys_Printf (char *fmt, ...)
{
va_list argptr;
char text[1024];
DWORD dummy;
if (isDedicated)
{
va_start (argptr,fmt);
vsprintf (text, fmt, argptr);
va_end (argptr);
WriteFile(houtput, text, strlen (text), &dummy, NULL);
}
}
void Sys_Quit (void)
{
VID_ForceUnlockedAndReturnState ();
Host_Shutdown();
if (tevent)
CloseHandle (tevent);
if (isDedicated)
FreeConsole ();
// shut down QHOST hooks if necessary
DeinitConProc ();
exit (0);
}
/*
================
Sys_FloatTime
================
*/
double Sys_FloatTime (void)
{
static int sametimecount;
static unsigned int oldtime;
static int first = 1;
LARGE_INTEGER PerformanceCount;
unsigned int temp, t2;
double time;
Sys_PushFPCW_SetHigh ();
QueryPerformanceCounter (&PerformanceCount);
temp = ((unsigned int)PerformanceCount.LowPart >> lowshift) |
((unsigned int)PerformanceCount.HighPart << (32 - lowshift));
if (first)
{
oldtime = temp;
first = 0;
}
else
{
// check for turnover or backward time
if ((temp <= oldtime) && ((oldtime - temp) < 0x10000000))
{
oldtime = temp; // so we can't get stuck
}
else
{
t2 = temp - oldtime;
time = (double)t2 * pfreq;
oldtime = temp;
curtime += time;
if (curtime == lastcurtime)
{
sametimecount++;
if (sametimecount > 100000)
{
curtime += 1.0;
sametimecount = 0;
}
}
else
{
sametimecount = 0;
}
lastcurtime = curtime;
}
}
Sys_PopFPCW ();
return curtime;
}
/*
================
Sys_InitFloatTime
================
*/
void Sys_InitFloatTime (void)
{
int j;
Sys_FloatTime ();
j = COM_CheckParm("-starttime");
if (j)
{
curtime = (double) (Q_atof(com_argv[j+1]));
}
else
{
curtime = 0.0;
}
lastcurtime = curtime;
}
char *Sys_ConsoleInput (void)
{
static char text[256];
static int len;
INPUT_RECORD recs[1024];
int count;
int i;
int ch;
DWORD numread, numevents, dummy;
if (!isDedicated)
return NULL;
for ( ;; )
{
if (!GetNumberOfConsoleInputEvents (hinput, &numevents))
Sys_Error ("Error getting # of console events");
if (numevents <= 0)
break;
if (!ReadConsoleInput(hinput, recs, 1, &numread))
Sys_Error ("Error reading console input");
if (numread != 1)
Sys_Error ("Couldn't read console input");
if (recs[0].EventType == KEY_EVENT)
{
if (!recs[0].Event.KeyEvent.bKeyDown)
{
ch = recs[0].Event.KeyEvent.uChar.AsciiChar;
switch (ch)
{
case '\r':
WriteFile(houtput, "\r\n", 2, &dummy, NULL);
if (len)
{
text[len] = 0;
len = 0;
return text;
}
else if (sc_return_on_enter)
{
// special case to allow exiting from the error handler on Enter
text[0] = '\r';
len = 0;
return text;
}
break;
case '\b':
WriteFile(houtput, "\b \b", 3, &dummy, NULL);
if (len)
{
len--;
}
break;
default:
if (ch >= ' ')
{
WriteFile(houtput, &ch, 1, &dummy, NULL);
text[len] = ch;
len = (len + 1) & 0xff;
}
break;
}
}
}
}
return NULL;
}
void Sys_Sleep (void)
{
Sleep (1);
}
/*
==============================================================================
WINDOWS CRAP
==============================================================================
*/
/*
==================
WinMain
==================
*/
void SleepUntilInput (int time)
{
MsgWaitForMultipleObjects(1, &tevent, FALSE, time, QS_ALLINPUT);
}
/*
==================
WinMain
==================
*/
HINSTANCE global_hInstance;
int global_nCmdShow;
char *argv[MAX_NUM_ARGVS];
static char *empty_string = "";
HWND hwnd_dialog;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
quakeparms_t parms;
double time, oldtime, newtime;
static char cwd[1024];
int t;
RECT rect;
/* previous instances do not exist in Win32 */
if (hPrevInstance)
return 0;
global_hInstance = hInstance;
global_nCmdShow = nCmdShow;
if (!GetCurrentDirectory (sizeof(cwd), cwd))
Sys_Error ("Couldn't determine current directory");
if (cwd[Q_strlen(cwd)-1] == '/')
cwd[Q_strlen(cwd)-1] = 0;
parms.basedir = cwd;
parms.cachedir = NULL;
parms.argc = 1;
argv[0] = empty_string;
while (*lpCmdLine && (parms.argc < MAX_NUM_ARGVS))
{
while (*lpCmdLine && ((*lpCmdLine <= 32) || (*lpCmdLine > 126)))
lpCmdLine++;
if (*lpCmdLine)
{
argv[parms.argc] = lpCmdLine;
parms.argc++;
while (*lpCmdLine && ((*lpCmdLine > 32) && (*lpCmdLine <= 126)))
lpCmdLine++;
if (*lpCmdLine)
{
*lpCmdLine = 0;
lpCmdLine++;
}
}
}
parms.argv = argv;
COM_InitArgv (parms.argc, parms.argv);
parms.argc = com_argc;
parms.argv = com_argv;
isDedicated = (COM_CheckParm ("-dedicated") != 0);
if (!isDedicated)
{
hwnd_dialog = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, NULL);
if (hwnd_dialog)
{
if (GetWindowRect (hwnd_dialog, &rect))
{
if (rect.left > (rect.top * 2))
{
SetWindowPos (hwnd_dialog, 0,
(rect.left / 2) - ((rect.right - rect.left) / 2),
rect.top, 0, 0,
SWP_NOZORDER | SWP_NOSIZE);
}
}
ShowWindow (hwnd_dialog, SW_SHOWDEFAULT);
UpdateWindow (hwnd_dialog);
SetForegroundWindow (hwnd_dialog);
}
}
// take the greater of all the available memory or half the total memory,
// but at least 8 Mb and no more than 16 Mb, unless they explicitly
// request otherwise
parms.memsize = 16 * 1024 * 1024;
if (COM_CheckParm ("-heapsize"))
{
t = COM_CheckParm("-heapsize") + 1;
if (t < com_argc)
parms.memsize = Q_atoi (com_argv[t]) * 1024;
}
parms.membase = malloc (parms.memsize);
if (!parms.membase)
Sys_Error ("Not enough memory free; check disk space\n");
Sys_PageIn (parms.membase, parms.memsize);
tevent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (!tevent)
Sys_Error ("Couldn't create event");
if (isDedicated)
{
if (!AllocConsole ())
{
Sys_Error ("Couldn't create dedicated server console");
}
hinput = GetStdHandle (STD_INPUT_HANDLE);
houtput = GetStdHandle (STD_OUTPUT_HANDLE);
// give QHOST a chance to hook into the console
if ((t = COM_CheckParm ("-HFILE")) > 0)
{
if (t < com_argc)
hFile = (HANDLE)Q_atoi (com_argv[t+1]);
}
if ((t = COM_CheckParm ("-HPARENT")) > 0)
{
if (t < com_argc)
heventParent = (HANDLE)Q_atoi (com_argv[t+1]);
}
if ((t = COM_CheckParm ("-HCHILD")) > 0)
{
if (t < com_argc)
heventChild = (HANDLE)Q_atoi (com_argv[t+1]);
}
InitConProc (hFile, heventParent, heventChild);
}
Sys_Init ();
// because sound is off until we become active
// S_BlockSound ();
Sys_Printf ("Host_Init\n");
Host_Init (&parms);
oldtime = Sys_FloatTime ();
/* main window message loop */
while (1)
{
if (isDedicated)
{
newtime = Sys_FloatTime ();
time = newtime - oldtime;
while (time < sys_ticrate.value )
{
Sys_Sleep();
newtime = Sys_FloatTime ();
time = newtime - oldtime;
}
}
else
{
// yield the CPU for a little while when paused, minimized, or not the focus
if ((cl.paused && (!ActiveApp && 1)) || Minimized || block_drawing)
{
// SleepUntilInput (PAUSE_SLEEP);
// scr_skipupdate = 1; // no point in bothering to draw
}
else if (!ActiveApp && 1)
{
// SleepUntilInput (NOT_FOCUS_SLEEP);
}
newtime = Sys_FloatTime ();
time = newtime - oldtime;
}
Host_Frame (time);
oldtime = newtime;
}
/* return success of application */
return TRUE;
}