a dos port, as a dig at eukara about his xbox port project.
mouse+kb+soundblaster devices should work. you can compile a dedicated server, but the lack of any networking support makes it a bit pointless. the software renderer will work, but its crap and gets absolutely dire framerates. there's no code to init mesa or anything, so its crappy-software rendering only. I doubt anything useful will ever result from this, but it was still interesting to do. possibly the only useful thing to come from this will be from limiting ram use. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5104 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
5d2ff1286d
commit
445e7f476b
15 changed files with 1859 additions and 473 deletions
|
@ -289,6 +289,12 @@ ifeq ($(FTE_TARGET),morphos)
|
||||||
endif
|
endif
|
||||||
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
|
#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)
|
ifeq ($(FTE_TARGET),linux32)
|
||||||
FTE_TARGET=linux
|
FTE_TARGET=linux
|
||||||
|
@ -360,6 +366,7 @@ CLIENT_DIR=$(BASE_DIR)/client
|
||||||
GL_DIR=$(BASE_DIR)/gl
|
GL_DIR=$(BASE_DIR)/gl
|
||||||
D3D_DIR=$(BASE_DIR)/d3d
|
D3D_DIR=$(BASE_DIR)/d3d
|
||||||
VK_DIR=$(BASE_DIR)/vk
|
VK_DIR=$(BASE_DIR)/vk
|
||||||
|
SW_DIR=$(BASE_DIR)/sw
|
||||||
SERVER_DIR=$(BASE_DIR)/server
|
SERVER_DIR=$(BASE_DIR)/server
|
||||||
COMMON_DIR=$(BASE_DIR)/common
|
COMMON_DIR=$(BASE_DIR)/common
|
||||||
HTTP_DIR=$(BASE_DIR)/http
|
HTTP_DIR=$(BASE_DIR)/http
|
||||||
|
@ -399,6 +406,9 @@ endif
|
||||||
ifeq ($(FTE_TARGET),cyg)
|
ifeq ($(FTE_TARGET),cyg)
|
||||||
BASELDFLAGS=-lm
|
BASELDFLAGS=-lm
|
||||||
endif
|
endif
|
||||||
|
ifeq ($(FTE_TARGET),dos)
|
||||||
|
BASELDFLAGS=-lm
|
||||||
|
endif
|
||||||
ifeq ($(FTE_TARGET),morphos)
|
ifeq ($(FTE_TARGET),morphos)
|
||||||
BASELDFLAGS=-lm
|
BASELDFLAGS=-lm
|
||||||
endif
|
endif
|
||||||
|
@ -1369,6 +1379,30 @@ ifeq ($(FTE_TARGET),morphos)
|
||||||
SV_CFLAGS=$(SERVER_ONLY_CFLAGS)
|
SV_CFLAGS=$(SERVER_ONLY_CFLAGS)
|
||||||
endif
|
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)
|
ifeq ($(FTE_TARGET),cyg)
|
||||||
SV_DIR=sv_cygwin
|
SV_DIR=sv_cygwin
|
||||||
|
@ -1510,7 +1544,7 @@ ifneq ($(OUT_DIR),)
|
||||||
endif
|
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)),)
|
ifneq ($(findstring -DSPEEX_STATIC, $(CFLAGS)),)
|
||||||
#add these to statically link libspeex
|
#add these to statically link libspeex
|
||||||
|
|
|
@ -1,452 +1,465 @@
|
||||||
/*
|
/*
|
||||||
===========================================================================
|
===========================================================================
|
||||||
Copyright (C) 1999-2005 Id Software, Inc.
|
Copyright (C) 1999-2005 Id Software, Inc.
|
||||||
|
|
||||||
This file is part of Quake III Arena source code.
|
This file is part of Quake III Arena source code.
|
||||||
|
|
||||||
Quake III Arena source code is free software; you can redistribute it
|
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
|
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,
|
published by the Free Software Foundation; either version 2 of the License,
|
||||||
or (at your option) any later version.
|
or (at your option) any later version.
|
||||||
|
|
||||||
Quake III Arena source code is distributed in the hope that it will be
|
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
|
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
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
|
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
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
===========================================================================
|
===========================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __Q_PLATFORM_H
|
#ifndef __Q_PLATFORM_H
|
||||||
#define __Q_PLATFORM_H
|
#define __Q_PLATFORM_H
|
||||||
|
|
||||||
// this is for determining if we have an asm version of a C function
|
// this is for determining if we have an asm version of a C function
|
||||||
#define idx64 0
|
#define idx64 0
|
||||||
|
|
||||||
#ifdef Q3_VM
|
#ifdef Q3_VM
|
||||||
|
|
||||||
#define id386 0
|
#define id386 0
|
||||||
#define idppc 0
|
#define idppc 0
|
||||||
#define idppc_altivec 0
|
#define idppc_altivec 0
|
||||||
#define idsparc 0
|
#define idsparc 0
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#if (defined _M_IX86 || defined __i386__) && !defined(C_ONLY)
|
#if (defined _M_IX86 || defined __i386__) && !defined(C_ONLY)
|
||||||
#define id386 1
|
#define id386 1
|
||||||
#else
|
#else
|
||||||
#define id386 0
|
#define id386 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (defined(powerc) || defined(powerpc) || defined(ppc) || \
|
#if (defined(powerc) || defined(powerpc) || defined(ppc) || \
|
||||||
defined(__ppc) || defined(__ppc__)) && !defined(C_ONLY)
|
defined(__ppc) || defined(__ppc__)) && !defined(C_ONLY)
|
||||||
#define idppc 1
|
#define idppc 1
|
||||||
#if defined(__VEC__)
|
#if defined(__VEC__)
|
||||||
#define idppc_altivec 1
|
#define idppc_altivec 1
|
||||||
#ifdef MACOS_X // Apple's GCC does this differently than the FSF.
|
#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) \
|
#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)
|
(vector unsigned char) (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p)
|
||||||
#else
|
#else
|
||||||
#define VECCONST_UINT8(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) \
|
#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}
|
(vector unsigned char) {a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p}
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
#define idppc_altivec 0
|
#define idppc_altivec 0
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
#define idppc 0
|
#define idppc 0
|
||||||
#define idppc_altivec 0
|
#define idppc_altivec 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__sparc__) && !defined(C_ONLY)
|
#if defined(__sparc__) && !defined(C_ONLY)
|
||||||
#define idsparc 1
|
#define idsparc 1
|
||||||
#else
|
#else
|
||||||
#define idsparc 0
|
#define idsparc 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef __ASM_I386__ // don't include the C bits if included from qasm.h
|
#ifndef __ASM_I386__ // don't include the C bits if included from qasm.h
|
||||||
|
|
||||||
// for windows fastcall option
|
// for windows fastcall option
|
||||||
#define QDECL
|
#define QDECL
|
||||||
|
|
||||||
//================================================================= WIN64/32 ===
|
//================================================================= WIN64/32 ===
|
||||||
|
|
||||||
#if defined(_WIN64) || defined(__WIN64__)
|
#if defined(_WIN64) || defined(__WIN64__)
|
||||||
|
|
||||||
#undef idx64
|
#undef idx64
|
||||||
#define idx64 1
|
#define idx64 1
|
||||||
|
|
||||||
#undef QDECL
|
#undef QDECL
|
||||||
#define QDECL __cdecl
|
#define QDECL __cdecl
|
||||||
|
|
||||||
#if defined( _MSC_VER )
|
#if defined( _MSC_VER )
|
||||||
#define OS_STRING "win_msvc64"
|
#define OS_STRING "win_msvc64"
|
||||||
#elif defined __MINGW64__
|
#elif defined __MINGW64__
|
||||||
#define OS_STRING "win_mingw64"
|
#define OS_STRING "win_mingw64"
|
||||||
#else
|
#else
|
||||||
#define OS_STRING "win64"
|
#define OS_STRING "win64"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ID_INLINE static __inline
|
#define ID_INLINE static __inline
|
||||||
#define PATH_SEP '\\'
|
#define PATH_SEP '\\'
|
||||||
|
|
||||||
#if defined( __WIN64__ )
|
#if defined( __WIN64__ )
|
||||||
#define ARCH_STRING "x86_64"
|
#define ARCH_STRING "x86_64"
|
||||||
#elif defined _M_ALPHA
|
#elif defined _M_ALPHA
|
||||||
#define ARCH_STRING "AXP"
|
#define ARCH_STRING "AXP"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define Q3_LITTLE_ENDIAN
|
#define Q3_LITTLE_ENDIAN
|
||||||
|
|
||||||
#define DLL_EXT ".dll"
|
#define DLL_EXT ".dll"
|
||||||
|
|
||||||
#elif defined(_WIN32) || defined(__WIN32__)
|
#elif defined(_WIN32) || defined(__WIN32__)
|
||||||
|
|
||||||
#undef QDECL
|
#undef QDECL
|
||||||
#define QDECL __cdecl
|
#define QDECL __cdecl
|
||||||
|
|
||||||
#if defined( _MSC_VER )
|
#if defined( _MSC_VER )
|
||||||
#define OS_STRING "win_msvc"
|
#define OS_STRING "win_msvc"
|
||||||
#elif defined __MINGW32__
|
#elif defined __MINGW32__
|
||||||
#define OS_STRING "win_mingw"
|
#define OS_STRING "win_mingw"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ID_INLINE static __inline
|
#define ID_INLINE static __inline
|
||||||
#define PATH_SEP '\\'
|
#define PATH_SEP '\\'
|
||||||
|
|
||||||
#if defined( _M_IX86 ) || defined( __i386__ )
|
#if defined( _M_IX86 ) || defined( __i386__ )
|
||||||
#define ARCH_STRING "x86"
|
#define ARCH_STRING "x86"
|
||||||
#elif defined _M_ALPHA
|
#elif defined _M_ALPHA
|
||||||
#define ARCH_STRING "AXP"
|
#define ARCH_STRING "AXP"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define Q3_LITTLE_ENDIAN
|
#define Q3_LITTLE_ENDIAN
|
||||||
|
|
||||||
#define DLL_EXT ".dll"
|
#define DLL_EXT ".dll"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//============================================================== MAC OS X ===
|
//============================================================== MAC OS X ===
|
||||||
|
|
||||||
#if defined(MACOS_X) || defined(__APPLE_CC__)
|
#if defined(MACOS_X) || defined(__APPLE_CC__)
|
||||||
|
|
||||||
// make sure this is defined, just for sanity's sake...
|
// make sure this is defined, just for sanity's sake...
|
||||||
#ifndef MACOS_X
|
#ifndef MACOS_X
|
||||||
#define MACOS_X
|
#define MACOS_X
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define OS_STRING "macosx"
|
#define OS_STRING "macosx"
|
||||||
#define ID_INLINE static inline
|
#define ID_INLINE static inline
|
||||||
#define PATH_SEP '/'
|
#define PATH_SEP '/'
|
||||||
|
|
||||||
#ifdef __ppc__
|
#ifdef __ppc__
|
||||||
#define ARCH_STRING "ppc"
|
#define ARCH_STRING "ppc"
|
||||||
#define Q3_BIG_ENDIAN
|
#define Q3_BIG_ENDIAN
|
||||||
#elif defined __i386__
|
#elif defined __i386__
|
||||||
#define ARCH_STRING "i386"
|
#define ARCH_STRING "i386"
|
||||||
#define Q3_LITTLE_ENDIAN
|
#define Q3_LITTLE_ENDIAN
|
||||||
#elif defined __x86_64__
|
#elif defined __x86_64__
|
||||||
#undef idx64
|
#undef idx64
|
||||||
#define idx64 1
|
#define idx64 1
|
||||||
#define ARCH_STRING "x86_64"
|
#define ARCH_STRING "x86_64"
|
||||||
#define Q3_LITTLE_ENDIAN
|
#define Q3_LITTLE_ENDIAN
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define DLL_EXT ".dylib"
|
#define DLL_EXT ".dylib"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//================================================================= LINUX ===
|
//================================================================= LINUX ===
|
||||||
|
|
||||||
#if defined(__linux__) || defined(__FreeBSD_kernel__) || defined(ANDROID) || defined(__ANDROID__)
|
#if defined(__linux__) || defined(__FreeBSD_kernel__) || defined(ANDROID) || defined(__ANDROID__)
|
||||||
|
|
||||||
#include <endian.h>
|
#include <endian.h>
|
||||||
|
|
||||||
#if defined(ANDROID) || defined(__ANDROID__)
|
#if defined(ANDROID) || defined(__ANDROID__)
|
||||||
#define OS_STRING "android"
|
#define OS_STRING "android"
|
||||||
#elif defined(__linux__)
|
#elif defined(__linux__)
|
||||||
#define OS_STRING "linux"
|
#define OS_STRING "linux"
|
||||||
#else
|
#else
|
||||||
#define OS_STRING "kFreeBSD"
|
#define OS_STRING "kFreeBSD"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ID_INLINE static inline
|
#define ID_INLINE static inline
|
||||||
#define PATH_SEP '/'
|
#define PATH_SEP '/'
|
||||||
|
|
||||||
#if defined __i386__
|
#if defined __i386__
|
||||||
#define ARCH_STRING "i386"
|
#define ARCH_STRING "i386"
|
||||||
#elif defined __x86_64__
|
#elif defined __x86_64__
|
||||||
#undef idx64
|
#undef idx64
|
||||||
#define idx64 1
|
#define idx64 1
|
||||||
#define ARCH_STRING "x86_64"
|
#define ARCH_STRING "x86_64"
|
||||||
#elif defined __powerpc64__
|
#elif defined __powerpc64__
|
||||||
#define ARCH_STRING "ppc64"
|
#define ARCH_STRING "ppc64"
|
||||||
#elif defined __powerpc__
|
#elif defined __powerpc__
|
||||||
#define ARCH_STRING "ppc"
|
#define ARCH_STRING "ppc"
|
||||||
#elif defined __s390__
|
#elif defined __s390__
|
||||||
#define ARCH_STRING "s390"
|
#define ARCH_STRING "s390"
|
||||||
#elif defined __s390x__
|
#elif defined __s390x__
|
||||||
#define ARCH_STRING "s390x"
|
#define ARCH_STRING "s390x"
|
||||||
#elif defined __ia64__
|
#elif defined __ia64__
|
||||||
#define ARCH_STRING "ia64"
|
#define ARCH_STRING "ia64"
|
||||||
#elif defined __alpha__
|
#elif defined __alpha__
|
||||||
#define ARCH_STRING "alpha"
|
#define ARCH_STRING "alpha"
|
||||||
#elif defined __sparc__
|
#elif defined __sparc__
|
||||||
#define ARCH_STRING "sparc"
|
#define ARCH_STRING "sparc"
|
||||||
#elif defined __arm__
|
#elif defined __arm__
|
||||||
#define ARCH_STRING "arm"
|
#define ARCH_STRING "arm"
|
||||||
#elif defined __cris__
|
#elif defined __cris__
|
||||||
#define ARCH_STRING "cris"
|
#define ARCH_STRING "cris"
|
||||||
#elif defined __hppa__
|
#elif defined __hppa__
|
||||||
#define ARCH_STRING "hppa"
|
#define ARCH_STRING "hppa"
|
||||||
#elif defined __mips__
|
#elif defined __mips__
|
||||||
#define ARCH_STRING "mips"
|
#define ARCH_STRING "mips"
|
||||||
#elif defined __sh__
|
#elif defined __sh__
|
||||||
#define ARCH_STRING "sh"
|
#define ARCH_STRING "sh"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if __FLOAT_WORD_ORDER == __BIG_ENDIAN
|
#if __FLOAT_WORD_ORDER == __BIG_ENDIAN
|
||||||
#define Q3_BIG_ENDIAN
|
#define Q3_BIG_ENDIAN
|
||||||
#else
|
#else
|
||||||
#define Q3_LITTLE_ENDIAN
|
#define Q3_LITTLE_ENDIAN
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define DLL_EXT ".so"
|
#define DLL_EXT ".so"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//=================================================================== BSD ===
|
//=================================================================== BSD ===
|
||||||
|
|
||||||
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
|
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <machine/endian.h>
|
#include <machine/endian.h>
|
||||||
|
|
||||||
#ifndef __BSD__
|
#ifndef __BSD__
|
||||||
#define __BSD__
|
#define __BSD__
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__FreeBSD__)
|
#if defined(__FreeBSD__)
|
||||||
#define OS_STRING "freebsd"
|
#define OS_STRING "freebsd"
|
||||||
#elif defined(__OpenBSD__)
|
#elif defined(__OpenBSD__)
|
||||||
#define OS_STRING "openbsd"
|
#define OS_STRING "openbsd"
|
||||||
#elif defined(__NetBSD__)
|
#elif defined(__NetBSD__)
|
||||||
#define OS_STRING "netbsd"
|
#define OS_STRING "netbsd"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ID_INLINE static inline
|
#define ID_INLINE static inline
|
||||||
#define PATH_SEP '/'
|
#define PATH_SEP '/'
|
||||||
|
|
||||||
#ifdef __i386__
|
#ifdef __i386__
|
||||||
#define ARCH_STRING "i386"
|
#define ARCH_STRING "i386"
|
||||||
#elif defined __amd64__
|
#elif defined __amd64__
|
||||||
#undef idx64
|
#undef idx64
|
||||||
#define idx64 1
|
#define idx64 1
|
||||||
#define ARCH_STRING "amd64"
|
#define ARCH_STRING "amd64"
|
||||||
#elif defined __axp__
|
#elif defined __axp__
|
||||||
#define ARCH_STRING "alpha"
|
#define ARCH_STRING "alpha"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if BYTE_ORDER == BIG_ENDIAN
|
#if BYTE_ORDER == BIG_ENDIAN
|
||||||
#define Q3_BIG_ENDIAN
|
#define Q3_BIG_ENDIAN
|
||||||
#else
|
#else
|
||||||
#define Q3_LITTLE_ENDIAN
|
#define Q3_LITTLE_ENDIAN
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define DLL_EXT ".so"
|
#define DLL_EXT ".so"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//================================================================= SUNOS ===
|
//================================================================= SUNOS ===
|
||||||
|
|
||||||
#ifdef __sun
|
#ifdef __sun
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <sys/byteorder.h>
|
#include <sys/byteorder.h>
|
||||||
|
|
||||||
#define OS_STRING "solaris"
|
#define OS_STRING "solaris"
|
||||||
#define ID_INLINE static inline
|
#define ID_INLINE static inline
|
||||||
#define PATH_SEP '/'
|
#define PATH_SEP '/'
|
||||||
|
|
||||||
#ifdef __i386__
|
#ifdef __i386__
|
||||||
#define ARCH_STRING "i386"
|
#define ARCH_STRING "i386"
|
||||||
#elif defined __sparc
|
#elif defined __sparc
|
||||||
#define ARCH_STRING "sparc"
|
#define ARCH_STRING "sparc"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined( _BIG_ENDIAN )
|
#if defined( _BIG_ENDIAN )
|
||||||
#define Q3_BIG_ENDIAN
|
#define Q3_BIG_ENDIAN
|
||||||
#elif defined( _LITTLE_ENDIAN )
|
#elif defined( _LITTLE_ENDIAN )
|
||||||
#define Q3_LITTLE_ENDIAN
|
#define Q3_LITTLE_ENDIAN
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define DLL_EXT ".so"
|
#define DLL_EXT ".so"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//================================================================== IRIX ===
|
//================================================================== IRIX ===
|
||||||
|
|
||||||
#ifdef __sgi
|
#ifdef __sgi
|
||||||
|
|
||||||
#define OS_STRING "irix"
|
#define OS_STRING "irix"
|
||||||
#define ID_INLINE static __inline
|
#define ID_INLINE static __inline
|
||||||
#define PATH_SEP '/'
|
#define PATH_SEP '/'
|
||||||
|
|
||||||
#define ARCH_STRING "mips"
|
#define ARCH_STRING "mips"
|
||||||
|
|
||||||
#define Q3_BIG_ENDIAN // SGI's MIPS are always big endian
|
#define Q3_BIG_ENDIAN // SGI's MIPS are always big endian
|
||||||
|
|
||||||
#define DLL_EXT ".so"
|
#define DLL_EXT ".so"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//=============================================================== MORPHOS ===
|
//=============================================================== MORPHOS ===
|
||||||
|
|
||||||
#ifdef __MORPHOS__
|
#ifdef __MORPHOS__
|
||||||
|
|
||||||
#define OS_STRING "morphos"
|
#define OS_STRING "morphos"
|
||||||
#define ID_INLINE static inline
|
#define ID_INLINE static inline
|
||||||
#define PATH_SEP '/'
|
#define PATH_SEP '/'
|
||||||
|
|
||||||
#define ARCH_STRING "ppc"
|
#define ARCH_STRING "ppc"
|
||||||
|
|
||||||
#define Q3_BIG_ENDIAN
|
#define Q3_BIG_ENDIAN
|
||||||
|
|
||||||
#define DLL_EXT ".so"
|
#define DLL_EXT ".so"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __CYGWIN__
|
#ifdef __CYGWIN__
|
||||||
#define OS_STRING "cygwin"
|
#define OS_STRING "cygwin"
|
||||||
#define ID_INLINE static inline
|
#define ID_INLINE static inline
|
||||||
#define PATH_SEP '/'
|
#define PATH_SEP '/'
|
||||||
|
|
||||||
#define ARCH_STRING "x86"
|
#define ARCH_STRING "x86"
|
||||||
|
|
||||||
#define Q3_BIG_ENDIAN
|
#define Q3_LITTLE_ENDIAN
|
||||||
|
|
||||||
#define DLL_EXT ".dll"
|
#define DLL_EXT ".dll"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef FTE_TARGET_WEB
|
#ifdef __DJGPP__
|
||||||
#define OS_STRING "emscripten"
|
#define OS_STRING "msdos"
|
||||||
#define ID_INLINE static inline
|
#define ID_INLINE static inline
|
||||||
#define PATH_SEP '/'
|
#define PATH_SEP '/'
|
||||||
|
|
||||||
#define ARCH_STRING "web"
|
#define ARCH_STRING "dos"
|
||||||
|
|
||||||
#define Q3_LITTLE_ENDIAN
|
#define Q3_LITTLE_ENDIAN
|
||||||
|
|
||||||
#define DLL_EXT ".so"
|
#define DLL_EXT ".dll"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef NACL
|
|
||||||
#define OS_STRING "nacl"
|
#ifdef FTE_TARGET_WEB
|
||||||
#define ID_INLINE static inline
|
#define OS_STRING "emscripten"
|
||||||
#define PATH_SEP '/'
|
#define ID_INLINE static inline
|
||||||
|
#define PATH_SEP '/'
|
||||||
#define ARCH_STRING "web"
|
|
||||||
|
#define ARCH_STRING "web"
|
||||||
#define Q3_LITTLE_ENDIAN
|
|
||||||
|
#define Q3_LITTLE_ENDIAN
|
||||||
#define DLL_EXT ".so"
|
|
||||||
#endif
|
#define DLL_EXT ".so"
|
||||||
|
#endif
|
||||||
//================================================================== Q3VM ===
|
|
||||||
|
#ifdef NACL
|
||||||
#ifdef Q3_VM
|
#define OS_STRING "nacl"
|
||||||
|
#define ID_INLINE static inline
|
||||||
#define OS_STRING "q3vm"
|
#define PATH_SEP '/'
|
||||||
#define ID_INLINE static
|
|
||||||
#define PATH_SEP '/'
|
#define ARCH_STRING "web"
|
||||||
|
|
||||||
#define ARCH_STRING "bytecode"
|
#define Q3_LITTLE_ENDIAN
|
||||||
|
|
||||||
#define DLL_EXT ".qvm"
|
#define DLL_EXT ".so"
|
||||||
|
#endif
|
||||||
#endif
|
|
||||||
|
//================================================================== Q3VM ===
|
||||||
//===========================================================================
|
|
||||||
|
#ifdef Q3_VM
|
||||||
//catch missing defines in above blocks
|
|
||||||
#if !defined( OS_STRING )
|
#define OS_STRING "q3vm"
|
||||||
#define ARCH_STRING "unknown"
|
#define ID_INLINE static
|
||||||
//#error "Operating system not supported"
|
#define PATH_SEP '/'
|
||||||
#endif
|
|
||||||
|
#define ARCH_STRING "bytecode"
|
||||||
#if !defined( ARCH_STRING )
|
|
||||||
#define ARCH_STRING "unk"
|
#define DLL_EXT ".qvm"
|
||||||
//#error "Architecture not supported"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ID_INLINE
|
//===========================================================================
|
||||||
#define ID_INLINE static
|
|
||||||
//#error "ID_INLINE not defined"
|
//catch missing defines in above blocks
|
||||||
#endif
|
#if !defined( OS_STRING )
|
||||||
|
#define ARCH_STRING "unknown"
|
||||||
#ifndef PATH_SEP
|
//#error "Operating system not supported"
|
||||||
#define PATH_SEP '/'
|
#endif
|
||||||
//#error "PATH_SEP not defined"
|
|
||||||
#endif
|
#if !defined( ARCH_STRING )
|
||||||
|
#define ARCH_STRING "unk"
|
||||||
#ifndef DLL_EXT
|
//#error "Architecture not supported"
|
||||||
#define DLL_EXT ".so"
|
#endif
|
||||||
//#error "DLL_EXT not defined"
|
|
||||||
#endif
|
#ifndef ID_INLINE
|
||||||
|
#define ID_INLINE static
|
||||||
|
//#error "ID_INLINE not defined"
|
||||||
//endianness
|
#endif
|
||||||
short ShortSwap (short l);
|
|
||||||
int LongSwap (int l);
|
#ifndef PATH_SEP
|
||||||
float FloatSwap (const float *f);
|
#define PATH_SEP '/'
|
||||||
|
//#error "PATH_SEP not defined"
|
||||||
#if defined( Q3_BIG_ENDIAN ) && defined( Q3_LITTLE_ENDIAN )
|
#endif
|
||||||
#error "Endianness defined as both big and little"
|
|
||||||
#elif defined( Q3_BIG_ENDIAN )
|
#ifndef DLL_EXT
|
||||||
|
#define DLL_EXT ".so"
|
||||||
#define LittleShort(x) ShortSwap(x)
|
//#error "DLL_EXT not defined"
|
||||||
#define LittleLong(x) LongSwap(x)
|
#endif
|
||||||
#define LittleFloat(x) FloatSwap(&x)
|
|
||||||
#define BigShort
|
|
||||||
#define BigLong
|
//endianness
|
||||||
#define BigFloat
|
short ShortSwap (short l);
|
||||||
|
int LongSwap (int l);
|
||||||
#elif defined( Q3_LITTLE_ENDIAN )
|
float FloatSwap (const float *f);
|
||||||
|
|
||||||
#define LittleShort
|
#if defined( Q3_BIG_ENDIAN ) && defined( Q3_LITTLE_ENDIAN )
|
||||||
#define LittleLong
|
#error "Endianness defined as both big and little"
|
||||||
#define LittleFloat
|
#elif defined( Q3_BIG_ENDIAN )
|
||||||
#define BigShort(x) ShortSwap(x)
|
|
||||||
#define BigLong(x) LongSwap(x)
|
#define LittleShort(x) ShortSwap(x)
|
||||||
#define BigFloat(x) FloatSwap(&x)
|
#define LittleLong(x) LongSwap(x)
|
||||||
|
#define LittleFloat(x) FloatSwap(&x)
|
||||||
#elif defined( Q3_VM )
|
#define BigShort
|
||||||
|
#define BigLong
|
||||||
#define LittleShort
|
#define BigFloat
|
||||||
#define LittleLong
|
|
||||||
#define LittleFloat
|
#elif defined( Q3_LITTLE_ENDIAN )
|
||||||
#define BigShort
|
|
||||||
#define BigLong
|
#define LittleShort
|
||||||
#define BigFloat
|
#define LittleLong
|
||||||
|
#define LittleFloat
|
||||||
#else
|
#define BigShort(x) ShortSwap(x)
|
||||||
#error "Endianness not defined"
|
#define BigLong(x) LongSwap(x)
|
||||||
#endif
|
#define BigFloat(x) FloatSwap(&x)
|
||||||
|
|
||||||
|
#elif defined( Q3_VM )
|
||||||
//platform string
|
|
||||||
#ifdef NDEBUG
|
#define LittleShort
|
||||||
#define PLATFORM_STRING OS_STRING "-" ARCH_STRING
|
#define LittleLong
|
||||||
#else
|
#define LittleFloat
|
||||||
#define PLATFORM_STRING OS_STRING "-" ARCH_STRING "-debug"
|
#define BigShort
|
||||||
#endif
|
#define BigLong
|
||||||
|
#define BigFloat
|
||||||
#endif
|
|
||||||
|
#else
|
||||||
#endif
|
#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
|
||||||
|
|
|
@ -91,7 +91,13 @@ cvar_t snd_noextraupdate = CVARAF( "s_noextraupdate", "0",
|
||||||
"snd_noextraupdate", 0);
|
"snd_noextraupdate", 0);
|
||||||
cvar_t snd_show = CVARAF( "s_show", "0",
|
cvar_t snd_show = CVARAF( "s_show", "0",
|
||||||
"snd_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.");
|
"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",
|
cvar_t snd_inactive = CVARAFD( "s_inactive", "1",
|
||||||
"snd_inactive", CVAR_ARCHIVE,
|
"snd_inactive", CVAR_ARCHIVE,
|
||||||
|
@ -1507,11 +1513,16 @@ extern sounddriver_t XAUDIO2_Output;
|
||||||
extern sounddriver_t DSOUND_Output;
|
extern sounddriver_t DSOUND_Output;
|
||||||
#endif
|
#endif
|
||||||
sounddriver_t SDL_Output;
|
sounddriver_t SDL_Output;
|
||||||
|
#ifdef __linux__
|
||||||
sounddriver_t ALSA_Output;
|
sounddriver_t ALSA_Output;
|
||||||
|
#endif
|
||||||
sounddriver_t OSS_Output;
|
sounddriver_t OSS_Output;
|
||||||
#ifdef AVAIL_OPENAL
|
#ifdef AVAIL_OPENAL
|
||||||
extern sounddriver_t OPENAL_Output;
|
extern sounddriver_t OPENAL_Output;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef __DJGPP__
|
||||||
|
extern sounddriver_t SBLASTER_Output;
|
||||||
|
#endif
|
||||||
|
|
||||||
sounddriver pSNDIO_InitCard;
|
sounddriver pSNDIO_InitCard;
|
||||||
sounddriver pOSS_InitCard;
|
sounddriver pOSS_InitCard;
|
||||||
|
@ -1546,6 +1557,9 @@ static sounddriver_t *outputdrivers[] =
|
||||||
&ALSA_Output, //pure shite
|
&ALSA_Output, //pure shite
|
||||||
#endif
|
#endif
|
||||||
&OSS_Output, //good, but not likely to work any more
|
&OSS_Output, //good, but not likely to work any more
|
||||||
|
#ifdef __DJGPP__
|
||||||
|
&SBLASTER_Output, //zomgwtfdos?
|
||||||
|
#endif
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
590
engine/client/snd_sblaster.c
Normal file
590
engine/client/snd_sblaster.c
Normal file
|
@ -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 <quakedef.h>
|
||||||
|
|
||||||
|
#include <dos.h>
|
||||||
|
#include <dpmi.h>
|
||||||
|
#include <go32.h>
|
||||||
|
#include <sys/nearptr.h>
|
||||||
|
|
||||||
|
#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
|
||||||
|
};
|
||||||
|
|
185
engine/client/sys_dos.c
Normal file
185
engine/client/sys_dos.c
Normal file
|
@ -0,0 +1,185 @@
|
||||||
|
#include <quakedef.h>
|
||||||
|
|
||||||
|
//because cake.
|
||||||
|
#include "sys_linux.c"
|
||||||
|
|
||||||
|
#include <dos.h>
|
||||||
|
#include <dpmi.h>
|
||||||
|
_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<<i))
|
||||||
|
IN_KeyEvent(dosmousedeviceid, !!(mouse_buttons&(1u<<i)), K_MOUSE1+i, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Sys_SendKeyEvents();
|
||||||
|
}
|
||||||
|
void INS_ReInit(void)
|
||||||
|
{
|
||||||
|
dosmousedeviceid = 0;
|
||||||
|
mouse_buttons = 0;
|
||||||
|
mouse_numbuttons = 0;
|
||||||
|
|
||||||
|
regs.x.ax = 0;
|
||||||
|
dos_int86(0x33);
|
||||||
|
if (!regs.x.ax)
|
||||||
|
{
|
||||||
|
Con_Printf ("No mouse found\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mouse_numbuttons = regs.x.bx;
|
||||||
|
if (mouse_numbuttons >= 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);
|
||||||
|
}
|
|
@ -36,7 +36,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#ifndef __CYGWIN__
|
#if !defined(__CYGWIN__) && !defined(__DJGPP__)
|
||||||
#include <sys/ipc.h>
|
#include <sys/ipc.h>
|
||||||
#include <sys/shm.h>
|
#include <sys/shm.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -46,7 +46,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#ifndef __MACOSX__
|
#if !defined(__MACOSX__) && !defined(__DJGPP__)
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef MULTITHREAD
|
#ifdef MULTITHREAD
|
||||||
|
@ -255,8 +255,10 @@ void Sys_Printf (char *fmt, ...)
|
||||||
void Sys_Quit (void)
|
void Sys_Quit (void)
|
||||||
{
|
{
|
||||||
Host_Shutdown();
|
Host_Shutdown();
|
||||||
|
#ifndef __DJGPP__
|
||||||
if (!noconinput)
|
if (!noconinput)
|
||||||
fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY);
|
fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef USE_LIBTOOL
|
#ifdef USE_LIBTOOL
|
||||||
lt_dlexit();
|
lt_dlexit();
|
||||||
|
@ -400,9 +402,11 @@ void Sys_Error (const char *error, ...)
|
||||||
va_list argptr;
|
va_list argptr;
|
||||||
char string[1024];
|
char string[1024];
|
||||||
|
|
||||||
|
#ifndef __DJGPP__
|
||||||
// change stdin to non blocking
|
// change stdin to non blocking
|
||||||
if (!noconinput)
|
if (!noconinput)
|
||||||
fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY);
|
fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY);
|
||||||
|
#endif
|
||||||
|
|
||||||
va_start (argptr,error);
|
va_start (argptr,error);
|
||||||
vsnprintf (string,sizeof(string)-1, error,argptr);
|
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
|
// Sleeps for microseconds
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
|
|
||||||
static volatile int oktogo;
|
|
||||||
|
|
||||||
void alarm_handler(int x)
|
|
||||||
{
|
|
||||||
oktogo=1;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *Sys_ConsoleInput(void)
|
char *Sys_ConsoleInput(void)
|
||||||
{
|
{
|
||||||
#if 1
|
#if 1
|
||||||
|
@ -853,7 +850,9 @@ char *Sys_ConsoleInput(void)
|
||||||
|
|
||||||
// if (!qrenderer)
|
// if (!qrenderer)
|
||||||
{
|
{
|
||||||
|
Con_Printf("ConsoleInput\n");
|
||||||
len = read (0, text, sizeof(text));
|
len = read (0, text, sizeof(text));
|
||||||
|
Con_Printf("ConsoleInput read %i\n", len);
|
||||||
if (len < 1)
|
if (len < 1)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -948,13 +947,17 @@ int main (int c, const char **v)
|
||||||
|
|
||||||
|
|
||||||
noconinput = COM_CheckParm("-noconinput");
|
noconinput = COM_CheckParm("-noconinput");
|
||||||
|
#ifndef __DJGPP__
|
||||||
if (!noconinput)
|
if (!noconinput)
|
||||||
fcntl(0, F_SETFL, fcntl (0, F_GETFL, 0) | FNDELAY);
|
fcntl(0, F_SETFL, fcntl (0, F_GETFL, 0) | FNDELAY);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef SUBSERVERS
|
#ifdef SUBSERVERS
|
||||||
if (COM_CheckParm("-clusterslave"))
|
if (COM_CheckParm("-clusterslave"))
|
||||||
isDedicated = nostdout = isClusterSlave = true;
|
isDedicated = nostdout = isClusterSlave = true;
|
||||||
#endif
|
#endif
|
||||||
|
if (COM_CheckParm("-dedicated"))
|
||||||
|
isDedicated = true;
|
||||||
|
|
||||||
if (COM_CheckParm("-nostdout"))
|
if (COM_CheckParm("-nostdout"))
|
||||||
nostdout = 1;
|
nostdout = 1;
|
||||||
|
@ -963,7 +966,6 @@ int main (int c, const char **v)
|
||||||
|
|
||||||
for (i = 1; i < parms.argc; i++)
|
for (i = 1; i < parms.argc; i++)
|
||||||
{
|
{
|
||||||
Con_Printf("Arg%i == %s\n", i, parms.argv[i]);
|
|
||||||
if (!parms.argv[i])
|
if (!parms.argv[i])
|
||||||
continue;
|
continue;
|
||||||
if (*parms.argv[i] == '+' || *parms.argv[i] == '-')
|
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.
|
//from the OS. This will cause problems with framebuffer-only setups.
|
||||||
qboolean Sys_GetDesktopParameters(int *width, int *height, int *bpp, int *refreshrate)
|
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
|
//this about sums up the problem with this function
|
||||||
return false;
|
return false;
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -356,7 +356,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//software rendering is just too glitchy, don't use it.
|
//software rendering is just too glitchy, don't use it.
|
||||||
#if defined(SWQUAKE) && !defined(_DEBUG)
|
#if defined(SWQUAKE) && !defined(_DEBUG) && !defined(__DJGPP__)
|
||||||
#undef SWQUAKE
|
#undef SWQUAKE
|
||||||
#endif
|
#endif
|
||||||
#if (defined(D3D8QUAKE) || defined(D3D9QUAKE) || defined(D3D11QUAKE)) && !defined(D3DQUAKE)
|
#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.
|
#undef WEBCLIENT //http/ftp clients.
|
||||||
#endif
|
#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
|
#ifdef FTE_TARGET_WEB
|
||||||
//sandboxing...
|
//sandboxing...
|
||||||
#undef HAVE_TCP //websockets are not real tcp.
|
#undef HAVE_TCP //websockets are not real tcp.
|
||||||
|
|
|
@ -71,7 +71,7 @@ void Mod_DoCRC(model_t *mod, char *buffer, int buffersize)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#if defined(_WIN32) || defined(__DJGPP__)
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#else
|
#else
|
||||||
#include <alloca.h>
|
#include <alloca.h>
|
||||||
|
|
|
@ -1717,7 +1717,7 @@ void MSG_ReadPos (vec3_t pos)
|
||||||
pos[2] = MSG_ReadCoord();
|
pos[2] = MSG_ReadCoord();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(Q2SERVER) || !defined(SERVERONLY)
|
#if 1//defined(Q2SERVER) || !defined(SERVERONLY)
|
||||||
#define Q2NUMVERTEXNORMALS 162
|
#define Q2NUMVERTEXNORMALS 162
|
||||||
vec3_t bytedirs[Q2NUMVERTEXNORMALS] =
|
vec3_t bytedirs[Q2NUMVERTEXNORMALS] =
|
||||||
{
|
{
|
||||||
|
@ -2652,7 +2652,7 @@ unsigned int unicode_charofsfrombyteofs(const char *str, unsigned int byteofs, q
|
||||||
return chars;
|
return chars;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef FTE_TARGET_WEB
|
#if defined(FTE_TARGET_WEB) || defined(__DJGPP__)
|
||||||
//targets that don't support towupper/towlower...
|
//targets that don't support towupper/towlower...
|
||||||
#define towupper Q_towupper
|
#define towupper Q_towupper
|
||||||
#define towlower Q_towlower
|
#define towlower Q_towlower
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#endif
|
#endif
|
||||||
#include "com_mesh.h"
|
#include "com_mesh.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#if defined(_WIN32) || defined(__DJGPP__)
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#else
|
#else
|
||||||
#include <alloca.h>
|
#include <alloca.h>
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
#include "glquake.h"
|
#include "glquake.h"
|
||||||
#ifndef SERVERONLY
|
#ifndef SERVERONLY
|
||||||
|
|
||||||
#ifdef _WIN32
|
#if defined(_WIN32) || defined(__DJGPP__)
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#else
|
#else
|
||||||
#include <alloca.h>
|
#include <alloca.h>
|
||||||
|
|
|
@ -6057,7 +6057,7 @@ static qboolean Terr_Brush_DeleteId(heightmap_t *hm, unsigned int brushid)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#if defined(_WIN32) || defined(__DJGPP__)
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#else
|
#else
|
||||||
#include <alloca.h>
|
#include <alloca.h>
|
||||||
|
|
|
@ -120,6 +120,8 @@ struct q2gclient_s
|
||||||
// this point in the structure
|
// this point in the structure
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#if defined(Q2SERVER) || defined(Q2CLIENT)
|
||||||
typedef struct q2entity_state_s
|
typedef struct q2entity_state_s
|
||||||
{
|
{
|
||||||
int number; // edict index
|
int number; // edict index
|
||||||
|
@ -141,6 +143,8 @@ typedef struct q2entity_state_s
|
||||||
// events only go out for a single frame, they
|
// events only go out for a single frame, they
|
||||||
// are automatically cleared each frame
|
// are automatically cleared each frame
|
||||||
} q2entity_state_t;
|
} q2entity_state_t;
|
||||||
|
#endif
|
||||||
|
#if defined(Q2SERVER)
|
||||||
|
|
||||||
|
|
||||||
struct q2edict_s
|
struct q2edict_s
|
||||||
|
|
|
@ -660,6 +660,165 @@ void SWBE_ClearVBO(struct vbo_s *vbo)
|
||||||
void SWBE_UploadAllLightmaps(void)
|
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)
|
void SWBE_SelectEntity(struct entity_s *ent)
|
||||||
{
|
{
|
||||||
float modelmatrix[16];
|
float modelmatrix[16];
|
||||||
|
@ -670,7 +829,7 @@ void SWBE_SelectEntity(struct entity_s *ent)
|
||||||
return;
|
return;
|
||||||
shaderstate.curentity = ent;
|
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);
|
Matrix4_Multiply(r_refdef.m_projection, modelviewmatrix, shaderstate.m_mvp);
|
||||||
shaderstate.viewplane[0] = vpn[0];//-modelviewmatrix[0];//0*4+2];
|
shaderstate.viewplane[0] = vpn[0];//-modelviewmatrix[0];//0*4+2];
|
||||||
shaderstate.viewplane[1] = vpn[1];//-modelviewmatrix[1];//1*4+2];
|
shaderstate.viewplane[1] = vpn[1];//-modelviewmatrix[1];//1*4+2];
|
||||||
|
|
365
engine/sw/sw_viddos.c
Normal file
365
engine/sw/sw_viddos.c
Normal file
|
@ -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 <dpmi.h>
|
||||||
|
#include <go32.h>
|
||||||
|
#include <sys/farptr.h>
|
||||||
|
|
||||||
|
|
||||||
|
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<sizeof(VESA_INFO); c++)
|
||||||
|
_farpokeb(_dos_ds, dosbuf+c, 0);
|
||||||
|
|
||||||
|
dosmemput("VBE2", 4, dosbuf);
|
||||||
|
|
||||||
|
/* call the VESA function */
|
||||||
|
r.x.ax = 0x4F00;
|
||||||
|
r.x.di = dosbuf & 0xF;
|
||||||
|
r.x.es = (dosbuf>>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<sizeof(MODE_INFO); c++)
|
||||||
|
_farpokeb(_dos_ds, dosbuf+c, 0);
|
||||||
|
|
||||||
|
/* call the VESA function */
|
||||||
|
r.x.ax = 0x4F01;
|
||||||
|
r.x.di = dosbuf & 0xF;
|
||||||
|
r.x.es = (dosbuf>>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<number_of_modes; c++)
|
||||||
|
{
|
||||||
|
/* get information about this mode */
|
||||||
|
if (get_mode_info(mode_list[c]) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* check the flags field to make sure this is a color graphics mode,
|
||||||
|
* and that it is supported by the current hardware */
|
||||||
|
if ((mode_info.ModeAttributes & 0x19) != 0x19)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* check that this mode is the right size */
|
||||||
|
if ((mode_info.XResolution != w) || (mode_info.YResolution != h))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* check that there is only one color plane */
|
||||||
|
if (mode_info.NumberOfPlanes != 1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* check that it is a packed-pixel mode (other values are used for
|
||||||
|
* different memory layouts, eg. 6 for a truecolor resolution) */
|
||||||
|
if (mode_info.MemoryModel != ((bpp==8)?4:6))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* check that this is an 8-bit (256 color) mode */
|
||||||
|
if (mode_info.BitsPerPixel != bpp)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* if it passed all those checks, this must be the mode we want! */
|
||||||
|
return mode_list[c];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* oh dear, there was no mode matching the one we wanted! */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int set_vesa_mode(int w, int h, int bpp)
|
||||||
|
{
|
||||||
|
__dpmi_regs r;
|
||||||
|
int mode_number;
|
||||||
|
|
||||||
|
/* find the number for this mode */
|
||||||
|
mode_number = find_vesa_mode(w, h, bpp);
|
||||||
|
if (!mode_number)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* call the VESA mode set function */
|
||||||
|
r.x.ax = 0x4F02;
|
||||||
|
r.x.bx = mode_number;
|
||||||
|
__dpmi_int(0x10, &r);
|
||||||
|
if (r.h.ah)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* it worked! */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_vesa_bank(int bank_number)
|
||||||
|
{
|
||||||
|
__dpmi_regs r;
|
||||||
|
|
||||||
|
r.x.ax = 0x4F05;
|
||||||
|
r.x.bx = 0;
|
||||||
|
r.x.dx = bank_number;
|
||||||
|
__dpmi_int(0x10, &r);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void copy_to_vesa_screen(char *memory_buffer, int screen_size)
|
||||||
|
{
|
||||||
|
//FIXME: use OffScreenMemOffset if possible.
|
||||||
|
|
||||||
|
int bank_size = mode_info.WinSize*1024;
|
||||||
|
int bank_granularity = mode_info.WinGranularity*1024;
|
||||||
|
int bank_number = 0;
|
||||||
|
int todo = screen_size;
|
||||||
|
int copy_size;
|
||||||
|
|
||||||
|
while (todo > 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
|
Loading…
Reference in a new issue