diff --git a/engine/Makefile b/engine/Makefile index 830bc1d8e..2e6dfcfb3 100644 --- a/engine/Makefile +++ b/engine/Makefile @@ -289,6 +289,12 @@ ifeq ($(FTE_TARGET),morphos) endif endif +ifeq ($(FTE_TARGET),dos) + #at least from dos. + CC=i586-pc-msdosdjgpp-gcc + CFLAGS+=-DNO_ZLIB +endif + #if you have an x86, you can get gcc to build binaries using 3 different ABIs, instead of builds for just the default ABI ifeq ($(FTE_TARGET),linux32) FTE_TARGET=linux @@ -360,6 +366,7 @@ CLIENT_DIR=$(BASE_DIR)/client GL_DIR=$(BASE_DIR)/gl D3D_DIR=$(BASE_DIR)/d3d VK_DIR=$(BASE_DIR)/vk +SW_DIR=$(BASE_DIR)/sw SERVER_DIR=$(BASE_DIR)/server COMMON_DIR=$(BASE_DIR)/common HTTP_DIR=$(BASE_DIR)/http @@ -399,6 +406,9 @@ endif ifeq ($(FTE_TARGET),cyg) BASELDFLAGS=-lm endif +ifeq ($(FTE_TARGET),dos) + BASELDFLAGS=-lm +endif ifeq ($(FTE_TARGET),morphos) BASELDFLAGS=-lm endif @@ -1369,6 +1379,30 @@ ifeq ($(FTE_TARGET),morphos) SV_CFLAGS=$(SERVER_ONLY_CFLAGS) endif +ifeq ($(FTE_TARGET),dos) + EXEPOSTFIX=.exe + SV_DIR=sv_dos + GLB_DIR=gl_dos + MB_DIR=m_dos + MCL_DIR=mcl_dos + MINGL_DIR=mingl_dos + VKB_DIR=vk_dos + VKCL_DIR=vkcl_dos + + IMAGELDFLAGS= + OGGVORBISLDFLAGS= + + SOFTWARE_OBJS=sw_rast.o sw_backend.o sw_image.o + + M_LDFLAGS= + M_CFLAGS=-DSWQUAKE -DNO_ZLIB + MCL_OBJS=$(SOFTWARE_OBJS) $(D3DGL_OBJS) sw_viddos.o cd_null.o sys_dos.o snd_sblaster.o + M_EXE_NAME=../$(EXE_NAME)$(EXEPOSTFIX) + SV_EXE_NAME=../$(EXE_NAME)sv$(BITS)$(EXEPOSTFIX) + VK_EXE_NAME=../$(EXE_NAME)-vk$(BITS)$(EXEPOSTFIX) + + VKCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) $(BOTLIB_OBJS) cd_null.o sys_dos.o snd_sblaster.o +endif ifeq ($(FTE_TARGET),cyg) SV_DIR=sv_cygwin @@ -1510,7 +1544,7 @@ ifneq ($(OUT_DIR),) endif -VPATH = $(BASE_DIR) : $(CLIENT_DIR) : $(GL_DIR) : $(COMMON_DIR) : $(SERVER_DIR) : $(HTTP_DIR) : $(BASE_DIR)/irc : $(BASE_DIR)/email : $(QUX_DIR) : $(PROGS_DIR) : $(NACL_DIR) : $(D3D_DIR) : $(VK_DIR) : $(BOTLIB_DIR) : $(BASE_DIR)/libs/speex/libspeex : $(BASE_DIR)/web +VPATH = $(BASE_DIR) : $(CLIENT_DIR) : $(GL_DIR) : $(SW_DIR) : $(COMMON_DIR) : $(SERVER_DIR) : $(HTTP_DIR) : $(BASE_DIR)/irc : $(BASE_DIR)/email : $(QUX_DIR) : $(PROGS_DIR) : $(NACL_DIR) : $(D3D_DIR) : $(VK_DIR) : $(BOTLIB_DIR) : $(BASE_DIR)/libs/speex/libspeex : $(BASE_DIR)/web ifneq ($(findstring -DSPEEX_STATIC, $(CFLAGS)),) #add these to statically link libspeex diff --git a/engine/botlib/q_platform.h b/engine/botlib/q_platform.h index 9fccad88c..09a7ca234 100644 --- a/engine/botlib/q_platform.h +++ b/engine/botlib/q_platform.h @@ -1,452 +1,465 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code 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. - -Quake III Arena source code 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 Quake III Arena source code; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ - -#ifndef __Q_PLATFORM_H -#define __Q_PLATFORM_H - -// this is for determining if we have an asm version of a C function -#define idx64 0 - -#ifdef Q3_VM - -#define id386 0 -#define idppc 0 -#define idppc_altivec 0 -#define idsparc 0 - -#else - -#if (defined _M_IX86 || defined __i386__) && !defined(C_ONLY) -#define id386 1 -#else -#define id386 0 -#endif - -#if (defined(powerc) || defined(powerpc) || defined(ppc) || \ - defined(__ppc) || defined(__ppc__)) && !defined(C_ONLY) -#define idppc 1 -#if defined(__VEC__) -#define idppc_altivec 1 -#ifdef MACOS_X // Apple's GCC does this differently than the FSF. -#define VECCONST_UINT8(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) \ - (vector unsigned char) (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) -#else -#define VECCONST_UINT8(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) \ - (vector unsigned char) {a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p} -#endif -#else -#define idppc_altivec 0 -#endif -#else -#define idppc 0 -#define idppc_altivec 0 -#endif - -#if defined(__sparc__) && !defined(C_ONLY) -#define idsparc 1 -#else -#define idsparc 0 -#endif - -#endif - -#ifndef __ASM_I386__ // don't include the C bits if included from qasm.h - -// for windows fastcall option -#define QDECL - -//================================================================= WIN64/32 === - -#if defined(_WIN64) || defined(__WIN64__) - -#undef idx64 -#define idx64 1 - -#undef QDECL -#define QDECL __cdecl - -#if defined( _MSC_VER ) -#define OS_STRING "win_msvc64" -#elif defined __MINGW64__ -#define OS_STRING "win_mingw64" -#else -#define OS_STRING "win64" -#endif - -#define ID_INLINE static __inline -#define PATH_SEP '\\' - -#if defined( __WIN64__ ) -#define ARCH_STRING "x86_64" -#elif defined _M_ALPHA -#define ARCH_STRING "AXP" -#endif - -#define Q3_LITTLE_ENDIAN - -#define DLL_EXT ".dll" - -#elif defined(_WIN32) || defined(__WIN32__) - -#undef QDECL -#define QDECL __cdecl - -#if defined( _MSC_VER ) -#define OS_STRING "win_msvc" -#elif defined __MINGW32__ -#define OS_STRING "win_mingw" -#endif - -#define ID_INLINE static __inline -#define PATH_SEP '\\' - -#if defined( _M_IX86 ) || defined( __i386__ ) -#define ARCH_STRING "x86" -#elif defined _M_ALPHA -#define ARCH_STRING "AXP" -#endif - -#define Q3_LITTLE_ENDIAN - -#define DLL_EXT ".dll" - -#endif - -//============================================================== MAC OS X === - -#if defined(MACOS_X) || defined(__APPLE_CC__) - -// make sure this is defined, just for sanity's sake... -#ifndef MACOS_X -#define MACOS_X -#endif - -#define OS_STRING "macosx" -#define ID_INLINE static inline -#define PATH_SEP '/' - -#ifdef __ppc__ -#define ARCH_STRING "ppc" -#define Q3_BIG_ENDIAN -#elif defined __i386__ -#define ARCH_STRING "i386" -#define Q3_LITTLE_ENDIAN -#elif defined __x86_64__ -#undef idx64 -#define idx64 1 -#define ARCH_STRING "x86_64" -#define Q3_LITTLE_ENDIAN -#endif - -#define DLL_EXT ".dylib" - -#endif - -//================================================================= LINUX === - -#if defined(__linux__) || defined(__FreeBSD_kernel__) || defined(ANDROID) || defined(__ANDROID__) - -#include - -#if defined(ANDROID) || defined(__ANDROID__) -#define OS_STRING "android" -#elif defined(__linux__) -#define OS_STRING "linux" -#else -#define OS_STRING "kFreeBSD" -#endif - -#define ID_INLINE static inline -#define PATH_SEP '/' - -#if defined __i386__ -#define ARCH_STRING "i386" -#elif defined __x86_64__ -#undef idx64 -#define idx64 1 -#define ARCH_STRING "x86_64" -#elif defined __powerpc64__ -#define ARCH_STRING "ppc64" -#elif defined __powerpc__ -#define ARCH_STRING "ppc" -#elif defined __s390__ -#define ARCH_STRING "s390" -#elif defined __s390x__ -#define ARCH_STRING "s390x" -#elif defined __ia64__ -#define ARCH_STRING "ia64" -#elif defined __alpha__ -#define ARCH_STRING "alpha" -#elif defined __sparc__ -#define ARCH_STRING "sparc" -#elif defined __arm__ -#define ARCH_STRING "arm" -#elif defined __cris__ -#define ARCH_STRING "cris" -#elif defined __hppa__ -#define ARCH_STRING "hppa" -#elif defined __mips__ -#define ARCH_STRING "mips" -#elif defined __sh__ -#define ARCH_STRING "sh" -#endif - -#if __FLOAT_WORD_ORDER == __BIG_ENDIAN -#define Q3_BIG_ENDIAN -#else -#define Q3_LITTLE_ENDIAN -#endif - -#define DLL_EXT ".so" - -#endif - -//=================================================================== BSD === - -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) - -#include -#include - -#ifndef __BSD__ - #define __BSD__ -#endif - -#if defined(__FreeBSD__) -#define OS_STRING "freebsd" -#elif defined(__OpenBSD__) -#define OS_STRING "openbsd" -#elif defined(__NetBSD__) -#define OS_STRING "netbsd" -#endif - -#define ID_INLINE static inline -#define PATH_SEP '/' - -#ifdef __i386__ -#define ARCH_STRING "i386" -#elif defined __amd64__ -#undef idx64 -#define idx64 1 -#define ARCH_STRING "amd64" -#elif defined __axp__ -#define ARCH_STRING "alpha" -#endif - -#if BYTE_ORDER == BIG_ENDIAN -#define Q3_BIG_ENDIAN -#else -#define Q3_LITTLE_ENDIAN -#endif - -#define DLL_EXT ".so" - -#endif - -//================================================================= SUNOS === - -#ifdef __sun - -#include -#include - -#define OS_STRING "solaris" -#define ID_INLINE static inline -#define PATH_SEP '/' - -#ifdef __i386__ -#define ARCH_STRING "i386" -#elif defined __sparc -#define ARCH_STRING "sparc" -#endif - -#if defined( _BIG_ENDIAN ) -#define Q3_BIG_ENDIAN -#elif defined( _LITTLE_ENDIAN ) -#define Q3_LITTLE_ENDIAN -#endif - -#define DLL_EXT ".so" - -#endif - -//================================================================== IRIX === - -#ifdef __sgi - -#define OS_STRING "irix" -#define ID_INLINE static __inline -#define PATH_SEP '/' - -#define ARCH_STRING "mips" - -#define Q3_BIG_ENDIAN // SGI's MIPS are always big endian - -#define DLL_EXT ".so" - -#endif - -//=============================================================== MORPHOS === - -#ifdef __MORPHOS__ - -#define OS_STRING "morphos" -#define ID_INLINE static inline -#define PATH_SEP '/' - -#define ARCH_STRING "ppc" - -#define Q3_BIG_ENDIAN - -#define DLL_EXT ".so" - -#endif - -#ifdef __CYGWIN__ -#define OS_STRING "cygwin" -#define ID_INLINE static inline -#define PATH_SEP '/' - -#define ARCH_STRING "x86" - -#define Q3_BIG_ENDIAN - -#define DLL_EXT ".dll" - -#endif - -#ifdef FTE_TARGET_WEB -#define OS_STRING "emscripten" -#define ID_INLINE static inline -#define PATH_SEP '/' - -#define ARCH_STRING "web" - -#define Q3_LITTLE_ENDIAN - -#define DLL_EXT ".so" -#endif - -#ifdef NACL -#define OS_STRING "nacl" -#define ID_INLINE static inline -#define PATH_SEP '/' - -#define ARCH_STRING "web" - -#define Q3_LITTLE_ENDIAN - -#define DLL_EXT ".so" -#endif - -//================================================================== Q3VM === - -#ifdef Q3_VM - -#define OS_STRING "q3vm" -#define ID_INLINE static -#define PATH_SEP '/' - -#define ARCH_STRING "bytecode" - -#define DLL_EXT ".qvm" - -#endif - -//=========================================================================== - -//catch missing defines in above blocks -#if !defined( OS_STRING ) -#define ARCH_STRING "unknown" -//#error "Operating system not supported" -#endif - -#if !defined( ARCH_STRING ) -#define ARCH_STRING "unk" -//#error "Architecture not supported" -#endif - -#ifndef ID_INLINE -#define ID_INLINE static -//#error "ID_INLINE not defined" -#endif - -#ifndef PATH_SEP -#define PATH_SEP '/' -//#error "PATH_SEP not defined" -#endif - -#ifndef DLL_EXT -#define DLL_EXT ".so" -//#error "DLL_EXT not defined" -#endif - - -//endianness -short ShortSwap (short l); -int LongSwap (int l); -float FloatSwap (const float *f); - -#if defined( Q3_BIG_ENDIAN ) && defined( Q3_LITTLE_ENDIAN ) -#error "Endianness defined as both big and little" -#elif defined( Q3_BIG_ENDIAN ) - -#define LittleShort(x) ShortSwap(x) -#define LittleLong(x) LongSwap(x) -#define LittleFloat(x) FloatSwap(&x) -#define BigShort -#define BigLong -#define BigFloat - -#elif defined( Q3_LITTLE_ENDIAN ) - -#define LittleShort -#define LittleLong -#define LittleFloat -#define BigShort(x) ShortSwap(x) -#define BigLong(x) LongSwap(x) -#define BigFloat(x) FloatSwap(&x) - -#elif defined( Q3_VM ) - -#define LittleShort -#define LittleLong -#define LittleFloat -#define BigShort -#define BigLong -#define BigFloat - -#else -#error "Endianness not defined" -#endif - - -//platform string -#ifdef NDEBUG -#define PLATFORM_STRING OS_STRING "-" ARCH_STRING -#else -#define PLATFORM_STRING OS_STRING "-" ARCH_STRING "-debug" -#endif - -#endif - -#endif +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code 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. + +Quake III Arena source code 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 Quake III Arena source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#ifndef __Q_PLATFORM_H +#define __Q_PLATFORM_H + +// this is for determining if we have an asm version of a C function +#define idx64 0 + +#ifdef Q3_VM + +#define id386 0 +#define idppc 0 +#define idppc_altivec 0 +#define idsparc 0 + +#else + +#if (defined _M_IX86 || defined __i386__) && !defined(C_ONLY) +#define id386 1 +#else +#define id386 0 +#endif + +#if (defined(powerc) || defined(powerpc) || defined(ppc) || \ + defined(__ppc) || defined(__ppc__)) && !defined(C_ONLY) +#define idppc 1 +#if defined(__VEC__) +#define idppc_altivec 1 +#ifdef MACOS_X // Apple's GCC does this differently than the FSF. +#define VECCONST_UINT8(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) \ + (vector unsigned char) (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) +#else +#define VECCONST_UINT8(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) \ + (vector unsigned char) {a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p} +#endif +#else +#define idppc_altivec 0 +#endif +#else +#define idppc 0 +#define idppc_altivec 0 +#endif + +#if defined(__sparc__) && !defined(C_ONLY) +#define idsparc 1 +#else +#define idsparc 0 +#endif + +#endif + +#ifndef __ASM_I386__ // don't include the C bits if included from qasm.h + +// for windows fastcall option +#define QDECL + +//================================================================= WIN64/32 === + +#if defined(_WIN64) || defined(__WIN64__) + +#undef idx64 +#define idx64 1 + +#undef QDECL +#define QDECL __cdecl + +#if defined( _MSC_VER ) +#define OS_STRING "win_msvc64" +#elif defined __MINGW64__ +#define OS_STRING "win_mingw64" +#else +#define OS_STRING "win64" +#endif + +#define ID_INLINE static __inline +#define PATH_SEP '\\' + +#if defined( __WIN64__ ) +#define ARCH_STRING "x86_64" +#elif defined _M_ALPHA +#define ARCH_STRING "AXP" +#endif + +#define Q3_LITTLE_ENDIAN + +#define DLL_EXT ".dll" + +#elif defined(_WIN32) || defined(__WIN32__) + +#undef QDECL +#define QDECL __cdecl + +#if defined( _MSC_VER ) +#define OS_STRING "win_msvc" +#elif defined __MINGW32__ +#define OS_STRING "win_mingw" +#endif + +#define ID_INLINE static __inline +#define PATH_SEP '\\' + +#if defined( _M_IX86 ) || defined( __i386__ ) +#define ARCH_STRING "x86" +#elif defined _M_ALPHA +#define ARCH_STRING "AXP" +#endif + +#define Q3_LITTLE_ENDIAN + +#define DLL_EXT ".dll" + +#endif + +//============================================================== MAC OS X === + +#if defined(MACOS_X) || defined(__APPLE_CC__) + +// make sure this is defined, just for sanity's sake... +#ifndef MACOS_X +#define MACOS_X +#endif + +#define OS_STRING "macosx" +#define ID_INLINE static inline +#define PATH_SEP '/' + +#ifdef __ppc__ +#define ARCH_STRING "ppc" +#define Q3_BIG_ENDIAN +#elif defined __i386__ +#define ARCH_STRING "i386" +#define Q3_LITTLE_ENDIAN +#elif defined __x86_64__ +#undef idx64 +#define idx64 1 +#define ARCH_STRING "x86_64" +#define Q3_LITTLE_ENDIAN +#endif + +#define DLL_EXT ".dylib" + +#endif + +//================================================================= LINUX === + +#if defined(__linux__) || defined(__FreeBSD_kernel__) || defined(ANDROID) || defined(__ANDROID__) + +#include + +#if defined(ANDROID) || defined(__ANDROID__) +#define OS_STRING "android" +#elif defined(__linux__) +#define OS_STRING "linux" +#else +#define OS_STRING "kFreeBSD" +#endif + +#define ID_INLINE static inline +#define PATH_SEP '/' + +#if defined __i386__ +#define ARCH_STRING "i386" +#elif defined __x86_64__ +#undef idx64 +#define idx64 1 +#define ARCH_STRING "x86_64" +#elif defined __powerpc64__ +#define ARCH_STRING "ppc64" +#elif defined __powerpc__ +#define ARCH_STRING "ppc" +#elif defined __s390__ +#define ARCH_STRING "s390" +#elif defined __s390x__ +#define ARCH_STRING "s390x" +#elif defined __ia64__ +#define ARCH_STRING "ia64" +#elif defined __alpha__ +#define ARCH_STRING "alpha" +#elif defined __sparc__ +#define ARCH_STRING "sparc" +#elif defined __arm__ +#define ARCH_STRING "arm" +#elif defined __cris__ +#define ARCH_STRING "cris" +#elif defined __hppa__ +#define ARCH_STRING "hppa" +#elif defined __mips__ +#define ARCH_STRING "mips" +#elif defined __sh__ +#define ARCH_STRING "sh" +#endif + +#if __FLOAT_WORD_ORDER == __BIG_ENDIAN +#define Q3_BIG_ENDIAN +#else +#define Q3_LITTLE_ENDIAN +#endif + +#define DLL_EXT ".so" + +#endif + +//=================================================================== BSD === + +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + +#include +#include + +#ifndef __BSD__ + #define __BSD__ +#endif + +#if defined(__FreeBSD__) +#define OS_STRING "freebsd" +#elif defined(__OpenBSD__) +#define OS_STRING "openbsd" +#elif defined(__NetBSD__) +#define OS_STRING "netbsd" +#endif + +#define ID_INLINE static inline +#define PATH_SEP '/' + +#ifdef __i386__ +#define ARCH_STRING "i386" +#elif defined __amd64__ +#undef idx64 +#define idx64 1 +#define ARCH_STRING "amd64" +#elif defined __axp__ +#define ARCH_STRING "alpha" +#endif + +#if BYTE_ORDER == BIG_ENDIAN +#define Q3_BIG_ENDIAN +#else +#define Q3_LITTLE_ENDIAN +#endif + +#define DLL_EXT ".so" + +#endif + +//================================================================= SUNOS === + +#ifdef __sun + +#include +#include + +#define OS_STRING "solaris" +#define ID_INLINE static inline +#define PATH_SEP '/' + +#ifdef __i386__ +#define ARCH_STRING "i386" +#elif defined __sparc +#define ARCH_STRING "sparc" +#endif + +#if defined( _BIG_ENDIAN ) +#define Q3_BIG_ENDIAN +#elif defined( _LITTLE_ENDIAN ) +#define Q3_LITTLE_ENDIAN +#endif + +#define DLL_EXT ".so" + +#endif + +//================================================================== IRIX === + +#ifdef __sgi + +#define OS_STRING "irix" +#define ID_INLINE static __inline +#define PATH_SEP '/' + +#define ARCH_STRING "mips" + +#define Q3_BIG_ENDIAN // SGI's MIPS are always big endian + +#define DLL_EXT ".so" + +#endif + +//=============================================================== MORPHOS === + +#ifdef __MORPHOS__ + +#define OS_STRING "morphos" +#define ID_INLINE static inline +#define PATH_SEP '/' + +#define ARCH_STRING "ppc" + +#define Q3_BIG_ENDIAN + +#define DLL_EXT ".so" + +#endif + +#ifdef __CYGWIN__ +#define OS_STRING "cygwin" +#define ID_INLINE static inline +#define PATH_SEP '/' + +#define ARCH_STRING "x86" + +#define Q3_LITTLE_ENDIAN + +#define DLL_EXT ".dll" + +#endif + +#ifdef __DJGPP__ +#define OS_STRING "msdos" +#define ID_INLINE static inline +#define PATH_SEP '/' + +#define ARCH_STRING "dos" + +#define Q3_LITTLE_ENDIAN + +#define DLL_EXT ".dll" +#endif + + +#ifdef FTE_TARGET_WEB +#define OS_STRING "emscripten" +#define ID_INLINE static inline +#define PATH_SEP '/' + +#define ARCH_STRING "web" + +#define Q3_LITTLE_ENDIAN + +#define DLL_EXT ".so" +#endif + +#ifdef NACL +#define OS_STRING "nacl" +#define ID_INLINE static inline +#define PATH_SEP '/' + +#define ARCH_STRING "web" + +#define Q3_LITTLE_ENDIAN + +#define DLL_EXT ".so" +#endif + +//================================================================== Q3VM === + +#ifdef Q3_VM + +#define OS_STRING "q3vm" +#define ID_INLINE static +#define PATH_SEP '/' + +#define ARCH_STRING "bytecode" + +#define DLL_EXT ".qvm" + +#endif + +//=========================================================================== + +//catch missing defines in above blocks +#if !defined( OS_STRING ) +#define ARCH_STRING "unknown" +//#error "Operating system not supported" +#endif + +#if !defined( ARCH_STRING ) +#define ARCH_STRING "unk" +//#error "Architecture not supported" +#endif + +#ifndef ID_INLINE +#define ID_INLINE static +//#error "ID_INLINE not defined" +#endif + +#ifndef PATH_SEP +#define PATH_SEP '/' +//#error "PATH_SEP not defined" +#endif + +#ifndef DLL_EXT +#define DLL_EXT ".so" +//#error "DLL_EXT not defined" +#endif + + +//endianness +short ShortSwap (short l); +int LongSwap (int l); +float FloatSwap (const float *f); + +#if defined( Q3_BIG_ENDIAN ) && defined( Q3_LITTLE_ENDIAN ) +#error "Endianness defined as both big and little" +#elif defined( Q3_BIG_ENDIAN ) + +#define LittleShort(x) ShortSwap(x) +#define LittleLong(x) LongSwap(x) +#define LittleFloat(x) FloatSwap(&x) +#define BigShort +#define BigLong +#define BigFloat + +#elif defined( Q3_LITTLE_ENDIAN ) + +#define LittleShort +#define LittleLong +#define LittleFloat +#define BigShort(x) ShortSwap(x) +#define BigLong(x) LongSwap(x) +#define BigFloat(x) FloatSwap(&x) + +#elif defined( Q3_VM ) + +#define LittleShort +#define LittleLong +#define LittleFloat +#define BigShort +#define BigLong +#define BigFloat + +#else +#error "Endianness not defined" +#endif + + +//platform string +#ifdef NDEBUG +#define PLATFORM_STRING OS_STRING "-" ARCH_STRING +#else +#define PLATFORM_STRING OS_STRING "-" ARCH_STRING "-debug" +#endif + +#endif + +#endif diff --git a/engine/client/snd_dma.c b/engine/client/snd_dma.c index d2b2f346d..4bed5d99a 100644 --- a/engine/client/snd_dma.c +++ b/engine/client/snd_dma.c @@ -91,7 +91,13 @@ cvar_t snd_noextraupdate = CVARAF( "s_noextraupdate", "0", "snd_noextraupdate", 0); cvar_t snd_show = CVARAF( "s_show", "0", "snd_show", 0); -cvar_t snd_khz = CVARAFD( "s_khz", "48", +#ifdef __DJGPP__ +#define DEFAULT_SND_KHZ "11" +#else +//fixme: are android devices more likely to use 44.1khz? +#define DEFAULT_SND_KHZ "48" //most modern systems should go with 48khz audio (dvd quality). various hardware codecs support nothing else. +#endif +cvar_t snd_khz = CVARAFD( "s_khz", DEFAULT_SND_KHZ, "snd_khz", CVAR_ARCHIVE, "Sound speed, in kilohertz. Common values are 11, 22, 44, 48. Values above 1000 are explicitly in hertz."); cvar_t snd_inactive = CVARAFD( "s_inactive", "1", "snd_inactive", CVAR_ARCHIVE, @@ -1507,11 +1513,16 @@ extern sounddriver_t XAUDIO2_Output; extern sounddriver_t DSOUND_Output; #endif sounddriver_t SDL_Output; +#ifdef __linux__ sounddriver_t ALSA_Output; +#endif sounddriver_t OSS_Output; #ifdef AVAIL_OPENAL extern sounddriver_t OPENAL_Output; #endif +#ifdef __DJGPP__ +extern sounddriver_t SBLASTER_Output; +#endif sounddriver pSNDIO_InitCard; sounddriver pOSS_InitCard; @@ -1546,6 +1557,9 @@ static sounddriver_t *outputdrivers[] = &ALSA_Output, //pure shite #endif &OSS_Output, //good, but not likely to work any more +#ifdef __DJGPP__ + &SBLASTER_Output, //zomgwtfdos? +#endif NULL }; typedef struct { diff --git a/engine/client/snd_sblaster.c b/engine/client/snd_sblaster.c new file mode 100644 index 000000000..2d4ecfaeb --- /dev/null +++ b/engine/client/snd_sblaster.c @@ -0,0 +1,590 @@ +/* +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. + +*/ + + +//I had one at least, back in the day. +//should be fine for dosbox, if nothing else. + +//warning: this sound code doesn't seem to cope well with low framerates. the dma buffer is too small. +//4096 bytes 16bit stereo means 1024 samples. so less than 10 fps and the mixer will miss buffer wraps. + + +#include + +#include +#include +#include +#include + +#define SDRVNAME "SoundBlaster" + +/* +=============================================================================== + +BLASTER SUPPORT + +=============================================================================== +*/ + +_go32_dpmi_seginfo dma_buffer_memory; +static short *dma_buffer=0; //realigned pointer +quintptr_t dma_buffer_phys; //realigned physical address - must be within the first 16mb +static int dma_size; +static int dma; + +static int dsp_port; +static int irq; +static int low_dma; +static int high_dma; +static int mixer_port; +static int mpu401_port; + +static int dsp_version; +static int dsp_minor_version; + +static int timeconstant=-1; +static int oldmixervalue; + +static int mode_reg; +static int flipflop_reg; +static int disable_reg; +static int clear_reg; + +static soundcardinfo_t *becauseglobalssuck; //just protects against multiple devices being spawned at once. + + +static void PrintBits (qbyte b) +{ + int i; + char str[9]; + + for (i=0 ; i<8 ; i++) + str[i] = '0' + ((b & (1<<(7-i))) > 0); + + str[8] = 0; + Con_Printf ("%s (%i)", str, b); +} + +// ======================================================================= +// Interprets BLASTER variable +// ======================================================================= + +static int GetBLASTER(void) +{ + char *BLASTER; + char *param; + + BLASTER = getenv("BLASTER"); + if (!BLASTER) + return 0; + + param = strchr(BLASTER, 'A'); + if (!param) + param = strchr(BLASTER, 'a'); + if (!param) + return 0; + sscanf(param+1, "%x", &dsp_port); + + param = strchr(BLASTER, 'I'); + if (!param) + param = strchr(BLASTER, 'i'); + if (!param) + return 0; + sscanf(param+1, "%d", &irq); + + param = strchr(BLASTER, 'D'); + if (!param) + param = strchr(BLASTER, 'd'); + if (!param) + return 0; + sscanf(param+1, "%d", &low_dma); + + param = strchr(BLASTER, 'H'); + if (!param) + param = strchr(BLASTER, 'h'); + if (param) + sscanf(param+1, "%d", &high_dma); + + param = strchr(BLASTER, 'M'); + if (!param) + param = strchr(BLASTER, 'm'); + if (param) + sscanf(param+1, "%x", &mixer_port); + else + mixer_port = dsp_port; + + param = strchr(BLASTER, 'P'); + if (!param) + param = strchr(BLASTER, 'p'); + if (param) + sscanf(param+1, "%x", &mpu401_port); + + return 1; + +} + +// ================================================================== +// Resets DSP. Returns 0 on success. +// ================================================================== + +static int ResetDSP(void) +{ + volatile int i; + + outportb(dsp_port + 6, 1); + for (i=65536 ; i ; i--) ; + outportb(dsp_port + 6, 0); + for (i=65536 ; i ; i--) + { + if (!(inportb(dsp_port + 0xe) & 0x80)) continue; + if (inportb(dsp_port + 0xa) == 0xaa) break; + } + if (i) return 0; + else return 1; + +} + +static int ReadDSP(void) +{ + while (!(inportb(dsp_port+0xe)&0x80)) ; + return inportb(dsp_port+0xa); +} + +static void WriteDSP(int val) +{ + while ((inportb(dsp_port+0xc)&0x80)) ; + outportb(dsp_port+0xc, val); +} + +static int ReadMixer(int addr) +{ + outportb(mixer_port+4, addr); + return inportb(mixer_port+5); +} + +static void WriteMixer(int addr, int val) +{ + outportb(mixer_port+4, addr); + outportb(mixer_port+5, val); +} + +/* +================ +StartSB + +================ +*/ +static void StartSB(soundcardinfo_t *sc) +{ + int i; + +// version 4.xx startup code + if (dsp_version >= 4) + { + Con_Printf("Version 4 SB startup\n"); + WriteDSP(0xd1); // turn on speaker + + WriteDSP(0x41); + + WriteDSP(sc->sn.speed>>8); + WriteDSP(sc->sn.speed&0xff); + + WriteDSP(0xb6); // 16-bit output + WriteDSP(0x30); // stereo + WriteDSP((sc->sn.samples-1) & 0xff); // # of samples - 1 + WriteDSP((sc->sn.samples-1) >> 8); + } +// version 3.xx startup code + else if (dsp_version == 3) + { + Con_Printf("Version 3 SB startup\n"); + WriteDSP(0xd1); // turn on speaker + + oldmixervalue = ReadMixer (0xe); + WriteMixer (0xe, oldmixervalue | 0x2);// turn on stereo + + WriteDSP(0x14); // send one byte + WriteDSP(0x0); + WriteDSP(0x0); + + for (i=0 ; i<0x10000 ; i++) + inportb(dsp_port+0xe); // ack the dsp + + timeconstant = 65536-(256000000/(sc->sn.numchannels*sc->sn.speed)); + WriteDSP(0x40); + WriteDSP(timeconstant>>8); + + WriteMixer (0xe, ReadMixer(0xe) | 0x20);// turn off filter + + WriteDSP(0x48); + WriteDSP((sc->sn.samples-1) & 0xff); // # of samples - 1 + WriteDSP((sc->sn.samples-1) >> 8); + + WriteDSP(0x90); // high speed 8 bit stereo + } +// normal speed mono + else + { + Con_Printf("Version 2 SB startup\n"); + WriteDSP(0xd1); // turn on speaker + + timeconstant = 65536-(256000000/(sc->sn.numchannels*sc->sn.speed)); + WriteDSP(0x40); + WriteDSP(timeconstant>>8); + + WriteDSP(0x48); + WriteDSP((sc->sn.samples-1) & 0xff); // # of samples - 1 + WriteDSP((sc->sn.samples-1) >> 8); + + WriteDSP(0x1c); // normal speed 8 bit mono + } +} + +static const int page_reg[] = { 0x87, 0x83, 0x81, 0x82, 0x8f, 0x8b, 0x89, 0x8a }; +static const int addr_reg[] = { 0, 2, 4, 6, 0xc0, 0xc4, 0xc8, 0xcc }; +static const int count_reg[] = { 1, 3, 5, 7, 0xc2, 0xc6, 0xca, 0xce }; + +/* +================ +StartDMA + +================ +*/ +static void StartDMA(void) +{ + int mode; + +// use a high dma channel if specified + if (high_dma && dsp_version >= 4) // 8 bit snd can never use 16 bit dma + dma = high_dma; + else + dma = low_dma; + + Con_Printf ("Using DMA channel %i\n", dma); + + if (dma > 3) + { + mode_reg = 0xd6; + flipflop_reg = 0xd8; + disable_reg = 0xd4; + clear_reg = 0xdc; + } + else + { + mode_reg = 0xb; + flipflop_reg = 0xc; + disable_reg = 0xa; + clear_reg = 0xe; + } + + outportb(disable_reg, dma|4); // disable channel + // set mode- see "undocumented pc", p.876 + mode = (1<<6) // single-cycle + +(0<<5) // address increment + +(1<<4) // auto-init dma + +(2<<2) // read + +(dma&3); // channel # + outportb(mode_reg, mode); + +// set address + // set page + outportb(page_reg[dma], dma_buffer_phys >> 16); + + if (dma > 3) + { // address is in words + outportb(flipflop_reg, 0); // prepare to send 16-bit value + outportb(addr_reg[dma], (dma_buffer_phys>>1) & 0xff); + outportb(addr_reg[dma], (dma_buffer_phys>>9) & 0xff); + + outportb(flipflop_reg, 0); // prepare to send 16-bit value + outportb(count_reg[dma], ((dma_size>>1)-1) & 0xff); + outportb(count_reg[dma], ((dma_size>>1)-1) >> 8); + } + else + { // address is in bytes + outportb(flipflop_reg, 0); // prepare to send 16-bit value + outportb(addr_reg[dma], dma_buffer_phys & 0xff); + outportb(addr_reg[dma], (dma_buffer_phys>>8) & 0xff); + + outportb(flipflop_reg, 0); // prepare to send 16-bit value + outportb(count_reg[dma], (dma_size-1) & 0xff); + outportb(count_reg[dma], (dma_size-1) >> 8); + } + + outportb(clear_reg, 0); // clear write mask + outportb(disable_reg, dma&~4); +} + +/* +============== +BLASTER_GetDMAPos + +return the current sample position (in mono samples read) +inside the recirculating dma buffer, so the mixing code will know +how many sample are required to fill it up. +=============== +*/ +static unsigned int SBLASTER_GetDMAPos(soundcardinfo_t *sc) +{ + int count; + +// this function is called often. acknowledge the transfer completions +// all the time so that it loops + if (dsp_version >= 4) + inportb(dsp_port+0xf); // 16 bit audio + else + inportb(dsp_port+0xe); // 8 bit audio + +// clear 16-bit reg flip-flop +// load the current dma count register + if (dma < 4) + { + outportb(0xc, 0); + count = inportb(dma*2+1); + count += inportb(dma*2+1) << 8; + if (sc->sn.samplebits == 16) + count /= 2; + count = sc->sn.samples - (count+1); + } + else + { + outportb(0xd8, 0); + count = inportb(0xc0+(dma-4)*4+2); + count += inportb(0xc0+(dma-4)*4+2) << 8; + if (sc->sn.samplebits == 8) + count *= 2; + count = sc->sn.samples - (count+1); + } + +// Con_Printf("DMA pos = 0x%x\n", count); + +// sc->sn.samplepos = count & (sc->sn.samples-1); + return count; + +} + +/* +============== +BLASTER_Shutdown + +Reset the sound device for exiting +=============== +*/ +static void SBLASTER_Shutdown(soundcardinfo_t *sc) +{ + if (becauseglobalssuck == sc) + becauseglobalssuck = NULL; + + if (dsp_version >= 4) + { + } + else if (dsp_version == 3) + { + ResetDSP (); // stop high speed mode + WriteMixer (0xe, oldmixervalue); // turn stereo off and filter on + } + else + { + + } + + WriteDSP(0xd3); // turn off speaker + ResetDSP (); + + outportb(disable_reg, dma|4); // disable dma channel + + _go32_dpmi_free_dos_memory(&dma_buffer_memory); +} + +//simple ring buffer +static void *SBLASTER_LockBuffer(soundcardinfo_t *sc, unsigned int *sampidx) +{ + return sc->sn.buffer; +} + +//that's permanently locked +static void SBLASTER_UnlockBuffer(soundcardinfo_t *sc, void *buffer) +{ +} + +//that the hardware has direct access to. +static void SBLASTER_Submit (soundcardinfo_t *sc, int start, int end) +{ +} + +//returns the address of some memory. +//ctx is required to free the memory afterwards +static qboolean dosmem_alloc(_go32_dpmi_seginfo *ctx, size_t size) +{ + ctx->size = (size+15)>>4; + if (_go32_dpmi_allocate_dos_memory(ctx)) + return false; //failed + return true; +} + +static quintptr_t dosmem_phys(_go32_dpmi_seginfo *ctx) +{ + return ctx->rm_segment<<4; +} +static void *dosmem_ptr(_go32_dpmi_seginfo *ctx) +{ + __djgpp_nearptr_enable(); + return (void*)(__djgpp_conventional_base+dosmem_phys(ctx)); +} + + +/* +================== +BLASTER_Init + +Returns false if nothing is found. +================== +*/ +static qboolean SBLASTER_InitCard(soundcardinfo_t *sc, const char *pcmname) +{ + int size; + int p; + + if (becauseglobalssuck) + return 0; + +// +// must have a blaster variable set +// + if (!GetBLASTER()) + { + Con_NotifyBox ( + "The BLASTER environment variable\n" + "is not set, sound effects are\n" + "disabled. See README.TXT for help.\n" + ); + return 0; + } + + if (ResetDSP()) + { + Con_Printf("Could not reset SB"); + return 0; + } + +// +// get dsp version +// + WriteDSP(0xe1); + dsp_version = ReadDSP(); + dsp_minor_version = ReadDSP(); + +// we need at least v2 for auto-init dma + if (dsp_version < 2) + { + Con_Printf ("Sound blaster must be at least v2.0\n"); + return 0; + } + +// allow command line parm to set quality down + p = COM_CheckParm ("-dsp"); + if (p && p < com_argc - 1) + { + p = Q_atoi (com_argv[p+1]); + if (p < 2 || p > 4) + Con_Printf ("-dsp parameter can only be 2, 3, or 4\n"); + else if (p > dsp_version) + Con_Printf ("Can't -dsp %i on v%i hardware\n", p, dsp_version); + else + dsp_version = p; + } + + +// everyone does 11khz sampling rate unless told otherwise +// sc->sn.speed = 11025; +// rc = COM_CheckParm("-sspeed"); +// if (rc) +// sc->sn.speed = Q_atoi(com_argv[rc+1]); + +// version 4 cards (sb 16) do 16 bit stereo + if (dsp_version >= 4) + { + if (sc->sn.numchannels != 1) + sc->sn.numchannels = 2; + if (sc->sn.samplebits != 8) + sc->sn.samplebits = 16; + } +// version 3 cards (sb pro) do 8 bit stereo + else if (dsp_version == 3) + { + if (sc->sn.numchannels != 1) + sc->sn.numchannels = 2; + sc->sn.samplebits = 8; + } +// v2 cards do 8 bit mono + else + { + sc->sn.numchannels = 1; + sc->sn.samplebits = 8; + } + + sc->Lock = SBLASTER_LockBuffer; + sc->Unlock = SBLASTER_UnlockBuffer; + sc->Shutdown = SBLASTER_Shutdown; + sc->GetDMAPos = SBLASTER_GetDMAPos; + sc->Submit = SBLASTER_Submit; + + size = 4096; + +// allocate 8k and get a 4k-aligned buffer from it + if (!dosmem_alloc(&dma_buffer_memory, size*2)) + { + Con_Printf("Couldn't allocate sound dma buffer"); + return false; + } + dma_buffer_phys = ((dosmem_phys(&dma_buffer_memory) + size) & ~(size-1)); + dma_buffer = (short *)((qbyte*)dosmem_ptr(&dma_buffer_memory) + dma_buffer_phys-dosmem_phys(&dma_buffer_memory)); + + dma_size = size; + memset(dma_buffer, 0, dma_size); + + sc->sn.samples = size/(sc->sn.samplebits/8); + sc->sn.samplepos = 0; + sc->sn.buffer = (unsigned char *) dma_buffer; + sc->sn.samples = size/(sc->sn.samplebits/8); + + StartDMA(); + StartSB(sc); + + becauseglobalssuck = sc; + + return true; +} + + + + +static qboolean QDECL SBLASTER_Enumerate(void (QDECL *cb) (const char *drivername, const char *devicecode, const char *readablename)) +{ + return false; +} + +sounddriver_t SBLASTER_Output = +{ + SDRVNAME, + SBLASTER_InitCard, + SBLASTER_Enumerate +}; + diff --git a/engine/client/sys_dos.c b/engine/client/sys_dos.c new file mode 100644 index 000000000..d7e050425 --- /dev/null +++ b/engine/client/sys_dos.c @@ -0,0 +1,185 @@ +#include + +//because cake. +#include "sys_linux.c" + +#include +#include +_go32_dpmi_registers regs; +int dos_int86(int vec) +{ + int rc; + regs.x.ss = regs.x.sp = 0; + rc = _go32_dpmi_simulate_int(vec, ®s); + return rc || (regs.x.flags & 1); +} + + +static int mouse_buttons; +static int mouse_numbuttons; +static unsigned int dosmousedeviceid; + +static unsigned int doskeyboarddeviceid; + +#define KBRINGSIZE 256 +static struct +{ + unsigned char buf[KBRINGSIZE]; + int write; + int read; +} kbring; + +void TheKBHandler(void) +{ //this needs to be kept simple and small. + //we write to a really simple ringbuffer to avoid needing to lock various code/data pages. + kbring.buf[kbring.write++&(KBRINGSIZE-1)] = inportb(0x60); + outportb(0x20, 0x20); +} + +unsigned char keymap[256] = +{ + //this is a copy of the US keymap from vanilla quake. + //its so very tempting to switch it to a UK keymap... + +// 0 1 2 3 4 5 6 7 +// 8 9 A B C D E F + 0 , 27, '1', '2', '3', '4', '5', '6', + '7', '8', '9', '0', '-', '=', K_BACKSPACE,K_TAB, // 0 + 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', + 'o', 'p', '[', ']', 13 , K_CTRL, 'a', 's', // 1 + 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', + '\'' , '`', K_LSHIFT,'\\', 'z', 'x', 'c', 'v', // 2 + 'b', 'n', 'm', ',', '.', '/', K_RSHIFT, '*', + K_ALT, ' ', 0 , K_F1, K_F2, K_F3, K_F4, K_F5, // 3 + K_F6, K_F7, K_F8, K_F9, K_F10, 0 , 0 , K_HOME, + K_UPARROW, K_PGUP, '-', K_LEFTARROW,'5', K_RIGHTARROW,'+', K_END, // 4 + K_DOWNARROW,K_PGDN, K_INS, K_DEL, 0, 0 , 0, K_F11, + K_F12, 0 , 0 , 0 , 0 , 0 , 0 , 0, // 5 + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0, + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0, // 6 + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0, + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0, // 7 + +// 0 1 2 3 4 5 6 7 +// 8 9 A B C D E F + 0 , 27, '!', '@', '#', '$', '%', '^', + '&', '*', '(', ')', '_', '+', K_BACKSPACE,K_TAB, // 0 + 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', + 'O', 'P', '{', '}', 13 , K_CTRL, 'A', 'S', // 1 + 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', + '\"', '~', K_LSHIFT,'|', 'Z', 'X', 'C', 'V', // 2 + 'B', 'N', 'M', '<', '>', '?', K_RSHIFT, '*', + K_ALT, ' ', 0 , K_F1, K_F2, K_F3, K_F4, K_F5, // 3 + K_F6, K_F7, K_F8, K_F9, K_F10, 0 , 0 , K_HOME, + K_UPARROW, K_PGUP, '_', K_LEFTARROW,'%', K_RIGHTARROW,'+', K_END, // 4 + K_DOWNARROW,K_PGDN, K_INS, K_DEL, 0, 0, 0, K_F11, + K_F12, 0 , 0 , 0 , 0 , 0 , 0 , 0, // 5 + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0, + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0, // 6 + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0, + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 // 7 +}; + +void INS_Init(void) +{ + //make sure the kb handler and its data won't get paged out. + _go32_dpmi_lock_code((void *) TheKBHandler, 512); + _go32_dpmi_lock_data((void *) &kbring, sizeof(kbring)); + + //set up our interrupt handler. + _go32_dpmi_seginfo info; + info.pm_offset = (int) TheKBHandler; + _go32_dpmi_allocate_iret_wrapper(&info); + _go32_dpmi_set_protected_mode_interrupt_vector(9, &info); +} + +void Sys_SendKeyEvents(void) +{ //this is kinda silly, but the handler can't do it if we want to be correct with respect to virtual memory. + static int shift_down; + while (kbring.read != kbring.write) + { //keyboard maps are complicated, annoyingly so. left/right/extended.... and don't get me started on sysreq. some keys don't even have release events! + unsigned char c = kbring.buf[kbring.read++&(KBRINGSIZE-1)]; + unsigned int qkey, ukey; + + qkey = keymap[c&0x7f]; + ukey = (qkey >= 32 && qkey < 127)?keymap[(c&0x7f)|(shift_down?128:0)]:0; + if (c == 0xe0) + { //extended keys... + if (kbring.buf[kbring.read&(KBRINGSIZE-1)] == 0x1d) + qkey = K_RSHIFT; + else + continue; //annoying extended keys. + ukey = 0; + kbring.read++; + } + if (qkey == K_LSHIFT) + shift_down = (shift_down&~1) | ((c&0x80)?0:1); + if (qkey == K_RSHIFT) + shift_down = (shift_down&~2) | ((c&0x80)?0:2); +// Con_Printf("Keyboard: %x\n", c); + IN_KeyEvent(doskeyboarddeviceid, !(c&0x80), qkey, ukey); + } +} + +void INS_Move(float *movements, int pnum) +{ +} +void INS_Commands(void) +{ + if (!mouse_numbuttons) + return; + + regs.x.ax = 11; // read move + dos_int86(0x33); + if (regs.x.cx || regs.x.dx) + { + IN_MouseMove(dosmousedeviceid, false, (short)regs.x.cx, (short)regs.x.dx, 0, 0); + + Con_Printf("Mouse Move: %i %i\n", (short)regs.x.cx, (short)regs.x.dx); + } + + regs.x.ax = 3; // read buttons + dos_int86(0x33); + int b = mouse_buttons ^ regs.x.bx; + mouse_buttons = regs.x.bx; + for (int i = 0; i < mouse_numbuttons; i++) + { + if (b&(1u<= 255) + mouse_numbuttons = 2; + if (mouse_numbuttons > 10) + mouse_numbuttons = 10; + Con_Printf("%d-button mouse available\n", mouse_numbuttons); +} +void INS_Shutdown(void) +{ +} +void INS_EnumerateDevices(void *ctx, void(*callback)(void *ctx, const char *type, const char *devicename, unsigned int *qdevid)) +{ + callback(ctx, "mouse", "dosmouse", &dosmousedeviceid); + callback(ctx, "keyboard", "doskeyboard", &doskeyboarddeviceid); +} + +void Sys_Sleep (double seconds) +{ + usleep(seconds * 1000000); +} diff --git a/engine/client/sys_linux.c b/engine/client/sys_linux.c index 5b762f4c9..e1a4ba772 100644 --- a/engine/client/sys_linux.c +++ b/engine/client/sys_linux.c @@ -36,7 +36,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include #include #include -#ifndef __CYGWIN__ +#if !defined(__CYGWIN__) && !defined(__DJGPP__) #include #include #endif @@ -46,7 +46,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include #include #include -#ifndef __MACOSX__ +#if !defined(__MACOSX__) && !defined(__DJGPP__) #include #endif #ifdef MULTITHREAD @@ -255,8 +255,10 @@ void Sys_Printf (char *fmt, ...) void Sys_Quit (void) { Host_Shutdown(); +#ifndef __DJGPP__ if (!noconinput) fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY); +#endif #ifdef USE_LIBTOOL lt_dlexit(); @@ -400,9 +402,11 @@ void Sys_Error (const char *error, ...) va_list argptr; char string[1024]; +#ifndef __DJGPP__ // change stdin to non blocking if (!noconinput) fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY); +#endif va_start (argptr,error); vsnprintf (string,sizeof(string)-1, error,argptr); @@ -827,13 +831,6 @@ static void Friendly_Crash_Handler(int sig, siginfo_t *info, void *vcontext) // Sleeps for microseconds // ======================================================================= -static volatile int oktogo; - -void alarm_handler(int x) -{ - oktogo=1; -} - char *Sys_ConsoleInput(void) { #if 1 @@ -853,7 +850,9 @@ char *Sys_ConsoleInput(void) // if (!qrenderer) { +Con_Printf("ConsoleInput\n"); len = read (0, text, sizeof(text)); +Con_Printf("ConsoleInput read %i\n", len); if (len < 1) return NULL; @@ -948,13 +947,17 @@ int main (int c, const char **v) noconinput = COM_CheckParm("-noconinput"); +#ifndef __DJGPP__ if (!noconinput) fcntl(0, F_SETFL, fcntl (0, F_GETFL, 0) | FNDELAY); +#endif #ifdef SUBSERVERS if (COM_CheckParm("-clusterslave")) isDedicated = nostdout = isClusterSlave = true; #endif + if (COM_CheckParm("-dedicated")) + isDedicated = true; if (COM_CheckParm("-nostdout")) nostdout = 1; @@ -963,7 +966,6 @@ int main (int c, const char **v) for (i = 1; i < parms.argc; i++) { - Con_Printf("Arg%i == %s\n", i, parms.argv[i]); if (!parms.argv[i]) continue; if (*parms.argv[i] == '+' || *parms.argv[i] == '-') @@ -1033,7 +1035,7 @@ void Sys_ServerActivity(void) //from the OS. This will cause problems with framebuffer-only setups. qboolean Sys_GetDesktopParameters(int *width, int *height, int *bpp, int *refreshrate) { -#ifdef __MACOSX__ +#if defined(__MACOSX__) || defined(__DJGPP__) //this about sums up the problem with this function return false; #else diff --git a/engine/common/bothdefs.h b/engine/common/bothdefs.h index 65fa4e67a..f5c0afd6b 100644 --- a/engine/common/bothdefs.h +++ b/engine/common/bothdefs.h @@ -356,7 +356,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #endif //software rendering is just too glitchy, don't use it. -#if defined(SWQUAKE) && !defined(_DEBUG) +#if defined(SWQUAKE) && !defined(_DEBUG) && !defined(__DJGPP__) #undef SWQUAKE #endif #if (defined(D3D8QUAKE) || defined(D3D9QUAKE) || defined(D3D11QUAKE)) && !defined(D3DQUAKE) @@ -444,6 +444,26 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #undef WEBCLIENT //http/ftp clients. #endif +#ifdef __DJGPP__ + //no bsd sockets library. + #undef HAVE_TCP + #undef HAVE_PACKET + #undef SUPPORT_ICE + //too lazy to deal with no dlopen + #undef PLUGINS + #undef Q2SERVER + #undef Q3SERVER + #undef Q2CLIENT //fixme... + #undef Q3CLIENT //might as well. + //too lazy to write the code to boot up more cores. dosbox would probably hate it so why bother. + #undef MULTITHREAD + //too lazy to deal with various libraries + #undef VOICECHAT + #undef AVAIL_JPEGLIB + #undef AVAIL_PNGLIB + #undef AVAIL_OGGVORBIS +#endif + #ifdef FTE_TARGET_WEB //sandboxing... #undef HAVE_TCP //websockets are not real tcp. diff --git a/engine/common/com_mesh.c b/engine/common/com_mesh.c index f602a8111..221befc30 100644 --- a/engine/common/com_mesh.c +++ b/engine/common/com_mesh.c @@ -71,7 +71,7 @@ void Mod_DoCRC(model_t *mod, char *buffer, int buffersize) -#ifdef _WIN32 +#if defined(_WIN32) || defined(__DJGPP__) #include #else #include diff --git a/engine/common/common.c b/engine/common/common.c index 58547c521..6fcb42676 100644 --- a/engine/common/common.c +++ b/engine/common/common.c @@ -1717,7 +1717,7 @@ void MSG_ReadPos (vec3_t pos) pos[2] = MSG_ReadCoord(); } -#if defined(Q2SERVER) || !defined(SERVERONLY) +#if 1//defined(Q2SERVER) || !defined(SERVERONLY) #define Q2NUMVERTEXNORMALS 162 vec3_t bytedirs[Q2NUMVERTEXNORMALS] = { @@ -2652,7 +2652,7 @@ unsigned int unicode_charofsfrombyteofs(const char *str, unsigned int byteofs, q return chars; } -#ifdef FTE_TARGET_WEB +#if defined(FTE_TARGET_WEB) || defined(__DJGPP__) //targets that don't support towupper/towlower... #define towupper Q_towupper #define towlower Q_towlower diff --git a/engine/common/gl_q2bsp.c b/engine/common/gl_q2bsp.c index c5c62b459..6ea6c8f86 100644 --- a/engine/common/gl_q2bsp.c +++ b/engine/common/gl_q2bsp.c @@ -4,7 +4,7 @@ #endif #include "com_mesh.h" -#ifdef _WIN32 +#if defined(_WIN32) || defined(__DJGPP__) #include #else #include diff --git a/engine/gl/gl_alias.c b/engine/gl/gl_alias.c index 9dda6e643..bd2273ed2 100644 --- a/engine/gl/gl_alias.c +++ b/engine/gl/gl_alias.c @@ -17,7 +17,7 @@ #include "glquake.h" #ifndef SERVERONLY -#ifdef _WIN32 +#if defined(_WIN32) || defined(__DJGPP__) #include #else #include diff --git a/engine/gl/gl_heightmap.c b/engine/gl/gl_heightmap.c index 6f66fb4ad..9a448cbda 100644 --- a/engine/gl/gl_heightmap.c +++ b/engine/gl/gl_heightmap.c @@ -6057,7 +6057,7 @@ static qboolean Terr_Brush_DeleteId(heightmap_t *hm, unsigned int brushid) } -#ifdef _WIN32 +#if defined(_WIN32) || defined(__DJGPP__) #include #else #include diff --git a/engine/server/q2game.h b/engine/server/q2game.h index c56535d46..cfd6394ff 100644 --- a/engine/server/q2game.h +++ b/engine/server/q2game.h @@ -120,6 +120,8 @@ struct q2gclient_s // this point in the structure }; +#endif +#if defined(Q2SERVER) || defined(Q2CLIENT) typedef struct q2entity_state_s { int number; // edict index @@ -141,6 +143,8 @@ typedef struct q2entity_state_s // events only go out for a single frame, they // are automatically cleared each frame } q2entity_state_t; +#endif +#if defined(Q2SERVER) struct q2edict_s diff --git a/engine/sw/sw_backend.c b/engine/sw/sw_backend.c index 89b5ee11d..949a03de9 100644 --- a/engine/sw/sw_backend.c +++ b/engine/sw/sw_backend.c @@ -660,6 +660,165 @@ void SWBE_ClearVBO(struct vbo_s *vbo) void SWBE_UploadAllLightmaps(void) { } +static void SWR_RotateForEntity (float *m, float *modelview, const entity_t *e, const model_t *mod) +{ + if ((e->flags & RF_WEAPONMODEL) && r_refdef.playerview->viewentity > 0) + { + float em[16]; + float vm[16]; + + if (e->flags & RF_WEAPONMODELNOBOB) + { + vm[0] = vpn[0]; + vm[1] = vpn[1]; + vm[2] = vpn[2]; + vm[3] = 0; + + vm[4] = -vright[0]; + vm[5] = -vright[1]; + vm[6] = -vright[2]; + vm[7] = 0; + + vm[8] = vup[0]; + vm[9] = vup[1]; + vm[10] = vup[2]; + vm[11] = 0; + + vm[12] = r_refdef.vieworg[0]; + vm[13] = r_refdef.vieworg[1]; + vm[14] = r_refdef.vieworg[2]; + vm[15] = 1; + } + else + { + vm[0] = r_refdef.playerview->vw_axis[0][0]; + vm[1] = r_refdef.playerview->vw_axis[0][1]; + vm[2] = r_refdef.playerview->vw_axis[0][2]; + vm[3] = 0; + + vm[4] = r_refdef.playerview->vw_axis[1][0]; + vm[5] = r_refdef.playerview->vw_axis[1][1]; + vm[6] = r_refdef.playerview->vw_axis[1][2]; + vm[7] = 0; + + vm[8] = r_refdef.playerview->vw_axis[2][0]; + vm[9] = r_refdef.playerview->vw_axis[2][1]; + vm[10] = r_refdef.playerview->vw_axis[2][2]; + vm[11] = 0; + + vm[12] = r_refdef.playerview->vw_origin[0]; + vm[13] = r_refdef.playerview->vw_origin[1]; + vm[14] = r_refdef.playerview->vw_origin[2]; + vm[15] = 1; + } + + em[0] = e->axis[0][0]; + em[1] = e->axis[0][1]; + em[2] = e->axis[0][2]; + em[3] = 0; + + em[4] = e->axis[1][0]; + em[5] = e->axis[1][1]; + em[6] = e->axis[1][2]; + em[7] = 0; + + em[8] = e->axis[2][0]; + em[9] = e->axis[2][1]; + em[10] = e->axis[2][2]; + em[11] = 0; + + em[12] = e->origin[0]; + em[13] = e->origin[1]; + em[14] = e->origin[2]; + em[15] = 1; + + Matrix4_Multiply(vm, em, m); + } + else + { + m[0] = e->axis[0][0]; + m[1] = e->axis[0][1]; + m[2] = e->axis[0][2]; + m[3] = 0; + + m[4] = e->axis[1][0]; + m[5] = e->axis[1][1]; + m[6] = e->axis[1][2]; + m[7] = 0; + + m[8] = e->axis[2][0]; + m[9] = e->axis[2][1]; + m[10] = e->axis[2][2]; + m[11] = 0; + + m[12] = e->origin[0]; + m[13] = e->origin[1]; + m[14] = e->origin[2]; + m[15] = 1; + } + + if (e->scale != 1 && e->scale != 0) //hexen 2 stuff + { +#ifdef HEXEN2 + float z; + float escale; + escale = e->scale; + switch(e->drawflags&SCALE_TYPE_MASK) + { + default: + case SCALE_TYPE_UNIFORM: + VectorScale((m+0), escale, (m+0)); + VectorScale((m+4), escale, (m+4)); + VectorScale((m+8), escale, (m+8)); + break; + case SCALE_TYPE_XYONLY: + VectorScale((m+0), escale, (m+0)); + VectorScale((m+4), escale, (m+4)); + break; + case SCALE_TYPE_ZONLY: + VectorScale((m+8), escale, (m+8)); + break; + } + if (mod && (e->drawflags&SCALE_TYPE_MASK) != SCALE_TYPE_XYONLY) + { + switch(e->drawflags&SCALE_ORIGIN_MASK) + { + case SCALE_ORIGIN_CENTER: + z = ((mod->maxs[2] + mod->mins[2]) * (1-escale))/2; + VectorMA((m+12), z, e->axis[2], (m+12)); + break; + case SCALE_ORIGIN_BOTTOM: + VectorMA((m+12), mod->mins[2]*(1-escale), e->axis[2], (m+12)); + break; + case SCALE_ORIGIN_TOP: + VectorMA((m+12), -mod->maxs[2], e->axis[2], (m+12)); + break; + } + } +#else + VectorScale((m+0), e->scale, (m+0)); + VectorScale((m+4), e->scale, (m+4)); + VectorScale((m+8), e->scale, (m+8)); +#endif + } + else if (mod && !strcmp(mod->name, "progs/eyes.mdl")) + { + /*resize eyes, to make them easier to see*/ + m[14] -= (22 + 8); + VectorScale((m+0), 2, (m+0)); + VectorScale((m+4), 2, (m+4)); + VectorScale((m+8), 2, (m+8)); + } + if (mod && !ruleset_allow_larger_models.ival && mod->clampscale != 1 && mod->type == mod_alias) + { //possibly this should be on a per-frame basis, but that's a real pain to do + Con_DPrintf("Rescaling %s by %f\n", mod->name, mod->clampscale); + VectorScale((m+0), mod->clampscale, (m+0)); + VectorScale((m+4), mod->clampscale, (m+4)); + VectorScale((m+8), mod->clampscale, (m+8)); + } + + Matrix4_Multiply(r_refdef.m_view, m, modelview); +} void SWBE_SelectEntity(struct entity_s *ent) { float modelmatrix[16]; @@ -670,7 +829,7 @@ void SWBE_SelectEntity(struct entity_s *ent) return; shaderstate.curentity = ent; - R_RotateForEntity(modelmatrix, modelviewmatrix, shaderstate.curentity, shaderstate.curentity->model); + SWR_RotateForEntity(modelmatrix, modelviewmatrix, shaderstate.curentity, shaderstate.curentity->model); Matrix4_Multiply(r_refdef.m_projection, modelviewmatrix, shaderstate.m_mvp); shaderstate.viewplane[0] = vpn[0];//-modelviewmatrix[0];//0*4+2]; shaderstate.viewplane[1] = vpn[1];//-modelviewmatrix[1];//1*4+2]; diff --git a/engine/sw/sw_viddos.c b/engine/sw/sw_viddos.c new file mode 100644 index 000000000..57f5774a2 --- /dev/null +++ b/engine/sw/sw_viddos.c @@ -0,0 +1,365 @@ +#include "quakedef.h" +#ifdef SWQUAKE +#include "sw.h" + + + + +/* from http://www.delorie.com/djgpp/doc/ug/graphics/vesa.html */ +typedef struct VESA_INFO +{ + unsigned char VESASignature[4]; + unsigned short VESAVersion __attribute__ ((packed)); + unsigned long OEMStringPtr __attribute__ ((packed)); + unsigned char Capabilities[4]; + unsigned long VideoModePtr __attribute__ ((packed)); + unsigned short TotalMemory __attribute__ ((packed)); + unsigned short OemSoftwareRev __attribute__ ((packed)); + unsigned long OemVendorNamePtr __attribute__ ((packed)); + unsigned long OemProductNamePtr __attribute__ ((packed)); + unsigned long OemProductRevPtr __attribute__ ((packed)); + unsigned char Reserved[222]; + unsigned char OemData[256]; +} VESA_INFO; + + + +#include +#include +#include + + +static VESA_INFO vesa_info; + + +static int get_vesa_info() +{ + __dpmi_regs r; + long dosbuf; + int c; + + /* use the conventional memory transfer buffer */ + dosbuf = __tb & 0xFFFFF; + + /* initialize the buffer to zero */ + for (c=0; c>4) & 0xFFFF; + __dpmi_int(0x10, &r); + + /* quit if there was an error */ + if (r.h.ah) + return -1; + + /* copy the resulting data into our structure */ + dosmemget(dosbuf, sizeof(VESA_INFO), &vesa_info); + + /* check that we got the right magic marker value */ + if (strncmp(vesa_info.VESASignature, "VESA", 4) != 0) + return -1; + + /* it worked! */ + return 0; +} + + +typedef struct MODE_INFO +{ + unsigned short ModeAttributes __attribute__ ((packed)); + unsigned char WinAAttributes; + unsigned char WinBAttributes; + unsigned short WinGranularity __attribute__ ((packed)); + unsigned short WinSize __attribute__ ((packed)); + unsigned short WinASegment __attribute__ ((packed)); + unsigned short WinBSegment __attribute__ ((packed)); + unsigned long WinFuncPtr __attribute__ ((packed)); + unsigned short BytesPerScanLine __attribute__ ((packed)); + unsigned short XResolution __attribute__ ((packed)); + unsigned short YResolution __attribute__ ((packed)); + unsigned char XCharSize; + unsigned char YCharSize; + unsigned char NumberOfPlanes; + unsigned char BitsPerPixel; + unsigned char NumberOfBanks; + unsigned char MemoryModel; + unsigned char BankSize; + unsigned char NumberOfImagePages; + unsigned char Reserved_page; + unsigned char RedMaskSize; + unsigned char RedMaskPos; + unsigned char GreenMaskSize; + unsigned char GreenMaskPos; + unsigned char BlueMaskSize; + unsigned char BlueMaskPos; + unsigned char ReservedMaskSize; + unsigned char ReservedMaskPos; + unsigned char DirectColorModeInfo; + unsigned long PhysBasePtr __attribute__ ((packed)); + unsigned long OffScreenMemOffset __attribute__ ((packed)); + unsigned short OffScreenMemSize __attribute__ ((packed)); + unsigned char Reserved[206]; +} MODE_INFO; + + +static MODE_INFO mode_info; + + +static int get_mode_info(int mode) +{ + __dpmi_regs r; + long dosbuf; + int c; + + /* use the conventional memory transfer buffer */ + dosbuf = __tb & 0xFFFFF; + + /* initialize the buffer to zero */ + for (c=0; c>4) & 0xFFFF; + r.x.cx = mode; + __dpmi_int(0x10, &r); + + /* quit if there was an error */ + if (r.h.ah) + return -1; + + /* copy the resulting data into our structure */ + dosmemget(dosbuf, sizeof(MODE_INFO), &mode_info); + + /* it worked! */ + return 0; +} + + +static int find_vesa_mode(int w, int h, int bpp) +{ + int mode_list[256]; + int number_of_modes; + long mode_ptr; + int c; + + /* check that the VESA driver exists, and get information about it */ + if (get_vesa_info() != 0) + return 0; + + /* convert the mode list pointer from seg:offset to a linear address */ + mode_ptr = ((vesa_info.VideoModePtr & 0xFFFF0000) >> 12) + (vesa_info.VideoModePtr & 0xFFFF); + + number_of_modes = 0; + + /* read the list of available modes */ + while (_farpeekw(_dos_ds, mode_ptr) != 0xFFFF) + { + mode_list[number_of_modes] = _farpeekw(_dos_ds, mode_ptr); + number_of_modes++; + mode_ptr += 2; + } + + /* scan through the list of modes looking for the one that we want */ + for (c=0; c 0) + { + /* select the appropriate bank */ + set_vesa_bank(bank_number); + + /* how much can we copy in one go? */ + if (todo > bank_size) + copy_size = bank_size; + else + copy_size = todo; + + /* copy a bank of data to the screen */ + dosmemput(memory_buffer, copy_size, 0xA0000); + + /* move on to the next bank of data */ + todo -= copy_size; + memory_buffer += copy_size; + bank_number += bank_size/bank_granularity; + } +} + + +extern int nostdout; //we flag with 0x800 to disable printfs while displaying stuff. +static qboolean videoatexitregistered; +static void videoatexit(void) +{ + if (nostdout & 0x800) + { + nostdout &= ~0x800; + + __dpmi_regs r; + r.x.ax = 0x0000 | 3; + __dpmi_int(0x10, &r); + } +} + + +static unsigned int *backbuffer; +static unsigned int *depthbuffer; +static unsigned int framenumber; + +//#define NORENDER + +qboolean SW_VID_Init(rendererstate_t *info, unsigned char *palette) +{ + int bpp = info->bpp; + vid.pixelwidth = info->width; + vid.pixelheight = info->height; + + if (bpp != 32) + bpp = 32; //sw renderer supports only this + +#ifndef NORENDER + nostdout |= 0x800; + if (set_vesa_mode(vid.pixelwidth, vid.pixelheight, bpp) < 0) + return false; +#endif + + if (!videoatexitregistered) + { + videoatexitregistered = true; + atexit(videoatexit); + } + + backbuffer = BZ_Malloc(vid.pixelwidth * vid.pixelheight * sizeof(*backbuffer)); + if (!backbuffer) + return false; + depthbuffer = BZ_Malloc(vid.pixelwidth * vid.pixelheight * sizeof(*depthbuffer)); + if (!depthbuffer) + return false; + + return true; +} +void SW_VID_DeInit(void) +{ + BZ_Free(backbuffer); + backbuffer = NULL; + BZ_Free(depthbuffer); + depthbuffer = NULL; +} +qboolean SW_VID_ApplyGammaRamps (unsigned int rampcount, unsigned short *ramps) +{ //no gamma ramps with VESA. + return false; +} +char *SW_VID_GetRGBInfo(int *bytestride, int *truevidwidth, int *truevidheight, enum uploadfmt *fmt) +{ + void *ret = BZ_Malloc(vid.pixelwidth*vid.pixelheight*4); + if (!ret) + return NULL; + + memcpy(ret, backbuffer, vid.pixelwidth*vid.pixelheight*4); + *bytestride = vid.pixelwidth*4; + *truevidwidth = vid.pixelwidth; + *truevidheight = vid.pixelheight; + *fmt = TF_BGRX32; + return ret; +} +void SW_VID_SetWindowCaption(const char *msg) +{ +} +void SW_VID_SwapBuffers(void) +{ +#ifndef NORENDER + copy_to_vesa_screen((char*)backbuffer, vid.pixelwidth*vid.pixelheight*4); +#endif + framenumber++; +} +void SW_VID_UpdateViewport(wqcom_t *com) +{ + com->viewport.cbuf = backbuffer + vid.pixelwidth*(vid.pixelheight-1); + com->viewport.dbuf = depthbuffer; + com->viewport.width = vid.pixelwidth; + com->viewport.height = vid.pixelheight; + com->viewport.stride = -vid.pixelwidth; //this is in pixels. which is stupid. + com->viewport.framenum = framenumber; +} + +#endif