Merge branch 'windows'

This brings in support for Microsoft Windows. While more testing is
necessary, the code seems to work quite well (tested by playing through
the first 3 units). Supported Windows versions are Windows XP and
above. Remaining problems are:
- The keyboard layout is always US QWERTY. This is due to a bug
  in SDL. While a work around is possible, most likely it won't
  be applied to Yamagi Quake II.
- The SDL sound backend needs the "dsound" SDL driver which is
  unavailable for 64 bit apllications on 64 bit Windows and
  Windows 8. Users should use the OpenAL backend.
- There me be problems if the %PROFILEDIR% containts unicode
  characters.
This commit is contained in:
Yamagi Burmeister 2012-06-18 09:33:40 +02:00
commit ba9d83e084
48 changed files with 11871 additions and 1415 deletions

View file

@ -47,27 +47,19 @@ Some hints:
===============================================================================
1. Port Yamagi Quake II to Microsoft Windows
1. Port Yamagi Quake II to Mac OS X
Difficulty: Hard
Knowledge: Microsoft Windows, good understanding of the Quake II source,
SDL-ABI, (experience with 64 bit problems)
Difficulty: Medium
Knowledge: Mac OS X API, good knowledge of src/unix/
While Quake II was released on Microsoft Windows, support for the plattform was
removed in the early stages of Yamagi Quake II. Looking back this was a bad
decision. Goal of this project is a backport to Microsoft Windows. This
requieres at least three steps:
1. Import the platform specific stuff for Windows from Icculus Q2, clean it up
and bring it to feature parity with the Unix stuff in src/unix. The nativ
sound, render and input backends should be replaced by the SDL backends in
src/sdl.
2. Go through the source and remove all unixisms.
And optional (Win64 support isn't required since 32 bit binaries are
working nice, but it be would nice to have):
3. Since Windows 64 has another binary model than all unixoid platform there
will most likely new 64 bit problems. Identify and resolve these.
A port to Mac OS X is a frequently requested feature but can't be done
by the Yamagi Quake II developers due to the lack of hardware. Since Mac
OS X is just another unixoid platform porting the game should be easy,
the most notable difference to FreeBSD and Linux is the MACH-O binary
format. So at least all calls to dlopen(), dlsym() and dlclose() must be
replaced by the corresponding Mac OS X functions. All other platform
dependend stuff should be hidden by SDL, but there may be some SDL bugs
on OS X.
===============================================================================
@ -102,7 +94,7 @@ Difficulty: Medium
Knowledge: How to debug hard to read code
While the baseq2 game modul was cleaned up and made more robust by adding
hundreds of sanity checks both addons (xatrix and rogue) still require a lot
hundreds of sanity checks, both addons (xatrix and rogue) still require a lot
of work. Go through the code, read it and understand it. Remove bugs, and add
the missing sanity checks. Test (e.g. play) and add implement map quirks.
Especially the coop-support of both addons is still fragile at best.
@ -115,10 +107,10 @@ Difficulty: Hard
Knowledge: How to work with broken code
Zaero is an unofficial but popular addon to Quake II. It was release as
freeware. The Yamagi Quake II did an inital port, but it's unfinished and
still buggy. Grab the source (take a look at our Github organization), clean
it and debug it. Zaero will need some extensive testing, have fun while
playing :)
freeware. The Yamagi Quake II developers did an inital port, but it's
unfinished and still buggy. Grab the source (take a look at our Github
organization), clean it and debug it. Zaero will need some extensive
testing, have fun while playing. :)
===============================================================================

265
Makefile
View file

@ -4,7 +4,7 @@
# Just type "make" to compile the #
# - SDL Client (quake2) #
# - Server (q2ded) #
# - SDL OpenGL-Refresher (ref_gl.so) #
# - SDL OpenGL-Refresher (ref_gl.so or ref_gl.dll) #
# - Quake II Game (baseq2) #
# #
# Base dependencies: #
@ -14,6 +14,7 @@
# Platforms: #
# - Linux #
# - FreeBSD #
# - Windows (MinGW) #
# ------------------------------------------------------ #
# User configurable options
@ -31,37 +32,52 @@ WITH_CDA:=yes
WITH_OGG:=yes
# Enables the optional OpenAL sound system.
# To use it your system needs libopenal.so.1 (we
# recommend openal-soft) installed
# To use it your system needs libopenal.so.1
# or openal32.dll (we recommend openal-soft)
# installed
WITH_OPENAL:=yes
# Enables retexturing support. Adds a dependency to
# libjpeg
# Enables retexturing support. Adds
# a dependency to libjpeg
WITH_RETEXTURING:=yes
# Set the gamma via X11 and not via SDL. This works
# around problems in some SDL version. Adds dependencies
# to pkg-config, libX11 and libXxf86vm
# to pkg-config, libX11 and libXxf86vm. Unsupported on
# Windows.
WITH_X11GAMMA:=no
# Enables opening of ZIP files (also known as .pk3 packs).
# Enables opening of ZIP files (also known as .pk3 paks).
# Adds a dependency to libz
WITH_ZIP:=yes
# Enable systemwide installation of game assets
WITH_SYSTEMWIDE:=no
# this will set the default SYSTEMDIR, a non-empty string would actually be used
WITH_SYSTEMDIR:=""
# This will set the default SYSTEMDIR, a non-empty string
# would actually be used. On Windows normals slashes (/)
# instead of backslashed (\) should be used!
WITH_SYSTEMDIR:=
# ====================================================== #
# !!! DO NOT ALTER ANYTHING BELOW THIS LINE !!! #
# ====================================================== #
# Check the OS type
# Detect the OS
ifdef SystemRoot
OSTYPE := Windows
else
OSTYPE := $(shell uname -s)
endif
# Detect the architecture
ifeq ($(OSTYPE), Windows)
# At this time only i386 is supported on Windows
ARCH := i386
else
# Some platforms call it "amd64" and some "x86_64"
ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/amd64/x86_64/)
endif
# Refuse all other platforms as a firewall against PEBKAC
# (You'll need some #ifdef for your unsupported plattform!)
@ -103,16 +119,18 @@ endif
# ----------
# Extra CFLAGS for SDL
ifneq ($(OSTYPE), Windows)
SDLCFLAGS := $(shell sdl-config --cflags)
endif
# ----------
# Extra CFLAGS for X11
ifneq ($(OSTYPE), Windows)
ifeq ($(WITH_X11GAMMA),yes)
X11CFLAGS := $(shell pkg-config x11 --cflags)
X11CFLAGS += $(shell pkg-config xxf86vm --cflags)
else
X11CFLAGS :=
endif
endif
# ----------
@ -131,21 +149,27 @@ ifeq ($(OSTYPE),Linux)
LDFLAGS := -L/usr/lib -lm -ldl
else ifeq ($(OSTYPE),FreeBSD)
LDFLAGS := -L/usr/local/lib -lm
else ifeq ($(OSTYPE),Windows)
LDFLAGS := -lws2_32 -lwinmm
endif
# ----------
# Extra LDFLAGS for SDL
ifeq ($(OSTYPE), Windows)
SDLLDFLAGS := -lSDL
else
SDLLDFLAGS := $(shell sdl-config --libs)
endif
# ----------
# Extra LDFLAGS for X11
ifneq ($(OSTYPE), Windows)
ifeq ($(WITH_X11GAMMA),yes)
X11LDFLAGS := $(shell pkg-config x11 --libs)
X11LDFLAGS += $(shell pkg-config xxf86vm --libs)
else
X11LDFLAGS :=
endif
endif
# ----------
@ -161,26 +185,79 @@ endif
# ----------
# Phony targets
.PHONY : all client game icon refresher server
# ----------
# Builds everything
all: client server refresher game
# ----------
# Special target to compile
# the icon on Windows
ifeq ($(OSTYPE), Windows)
icon:
@echo "===> WR build/icon/icon.res"
${Q}stuff/misc/mkdir -p build/icon
${Q}windres stuff\icon\icon.rc -O COFF -o build\icon\icon.res
endif
# ----------
# Cleanup
ifeq ($(OSTYPE), Windows)
clean:
@echo "===> CLEAN"
@-rmdir /S /Q release build
else
clean:
@echo "===> CLEAN"
${Q}rm -Rf build release
endif
# ----------
# The client
ifeq ($(OSTYPE), Windows)
client:
@echo '===> Building quake2'
@echo "===> Building quake2.exe"
${Q}stuff/misc/mkdir.exe -p release
$(MAKE) release/quake2.exe
build/client/%.o: %.c
@echo "===> CC $<"
${Q}stuff/misc/mkdir.exe -p $(@D)
${Q}$(CC) -c $(CFLAGS) $(SDLCFLAGS) $(INCLUDE) -o $@ $<
ifeq ($(WITH_CDA),yes)
release/quake2.exe : CFLAGS += -DCDA
endif
ifeq ($(WITH_OGG),yes)
release/quake2.exe : CFLAGS += -DOGG
release/quake2.exe : LDFLAGS += -lvorbisfile -lvorbis -logg
endif
ifeq ($(WITH_OPENAL),yes)
release/quake2.exe : CFLAGS += -DUSE_OPENAL -DDEFAULT_OPENAL_DRIVER='"openal32.dll"'
endif
ifeq ($(WITH_ZIP),yes)
release/quake2.exe : CFLAGS += -DZIP
release/quake2.exe : LDFLAGS += -lz
endif
release/quake2.exe : LDFLAGS += -mwindows
else
client:
@echo "===> Building quake2"
${Q}mkdir -p release
$(MAKE) release/quake2
build/client/%.o: %.c
@echo '===> CC $<'
@echo "===> CC $<"
${Q}mkdir -p $(@D)
${Q}$(CC) -c $(CFLAGS) $(SDLCFLAGS) $(INCLUDE) -o $@ $<
@ -201,19 +278,39 @@ ifeq ($(WITH_ZIP),yes)
release/quake2 : CFLAGS += -DZIP
release/quake2 : LDFLAGS += -lz
endif
endif
# ----------
# The server
ifeq ($(OSTYPE), Windows)
server:
@echo '===> Building q2ded'
@echo "===> Building q2ded"
${Q}stuff/misc/mkdir.exe -p release
$(MAKE) release/q2ded.exe
build/server/%.o: %.c
@echo "===> CC $<"
${Q}stuff/misc/mkdir.exe -p $(@D)
${Q}$(CC) -c $(CFLAGS) $(INCLUDE) -o $@ $<
release/q2ded.exe : CFLAGS += -DDEDICATED_ONLY
release/q2ded.exe : LDFLAGS += -lz
ifeq ($(WITH_ZIP),yes)
release/q2ded.exe : CFLAGS += -DZIP
release/q2ded.exe : LDFLAGS += -lz
endif
else
server:
@echo "===> Building q2ded"
${Q}mkdir -p release
$(MAKE) release/q2ded
build/server/%.o: %.c
@echo '===> CC $<'
@echo "===> CC $<"
${Q}mkdir -p $(@D)
${Q}$(CC) -c $(CFLAGS) $(INCLUDE) -o $@ $<
${Q}$(CC) -c $(CFLAGS) $(INCLUDE) -o $@ $<
release/q2ded : CFLAGS += -DDEDICATED_ONLY
release/q2ded : LDFLAGS += -lz
@ -222,17 +319,36 @@ ifeq ($(WITH_ZIP),yes)
release/q2ded : CFLAGS += -DZIP
release/q2ded : LDFLAGS += -lz
endif
endif
# ----------
# The refresher
ifeq ($(OSTYPE), Windows)
refresher:
@echo '===> Building ref_gl.so'
@echo "===> Building ref_gl.dll"
${Q}stuff/misc/mkdir.exe -p release
$(MAKE) release/ref_gl.dll
build/refresher/%.o: %.c
@echo "===> CC $<"
${Q}stuff/misc/mkdir.exe -p $(@D)
${Q}$(CC) -c $(CFLAGS) $(SDLCFLAGS) $(X11CFLAGS) $(INCLUDE) -o $@ $<
release/ref_gl.dll : LDFLAGS += -shared
ifeq ($(WITH_RETEXTURING),yes)
release/ref_gl.dll : CFLAGS += -DRETEXTURE
release/ref_gl.dll : LDFLAGS += -ljpeg
endif
else
refresher:
@echo "===> Building ref_gl.so"
${Q}mkdir -p release
$(MAKE) release/ref_gl.so
build/refresher/%.o: %.c
@echo '===> CC $<'
@echo "===> CC $<"
${Q}mkdir -p $(@D)
${Q}$(CC) -c $(CFLAGS) $(SDLCFLAGS) $(X11CFLAGS) $(INCLUDE) -o $@ $<
@ -247,23 +363,38 @@ ifeq ($(WITH_RETEXTURING),yes)
release/ref_gl.so : CFLAGS += -DRETEXTURE
release/ref_gl.so : LDFLAGS += -ljpeg
endif
endif
# ----------
# The baseq2 game
ifeq ($(OSTYPE), Windows)
game:
@echo '===> Building baseq2/game.so'
@echo "===> Building baseq2/game.dll"
${Q}stuff/misc/mkdir.exe -p release/baseq2
$(MAKE) release/baseq2/game.dll
build/baseq2/%.o: %.c
@echo "===> CC $<"
${Q}stuff/misc/mkdir.exe -p $(@D)
${Q}$(CC) -c $(CFLAGS) $(INCLUDE) -o $@ $<
release/baseq2/game.dll : LDFLAGS += -shared
else
game:
@echo "===> Building baseq2/game.so"
${Q}mkdir -p release/baseq2
$(MAKE) release/baseq2/game.so
build/baseq2/%.o: %.c
@echo '===> CC $<'
@echo "===> CC $<"
${Q}mkdir -p $(@D)
${Q}$(CC) -c $(CFLAGS) $(INCLUDE) -o $@ $<
release/baseq2/game.so : CFLAGS += -fPIC
release/baseq2/game.so : LDFLAGS += -shared
endif
# ----------
# Used by the game
@ -350,6 +481,7 @@ CLIENT_OBJS_ := \
src/common/crc.o \
src/common/cvar.o \
src/common/filesystem.o \
src/common/glob.o \
src/common/md4.o \
src/common/misc.o \
src/common/netchan.o \
@ -384,8 +516,18 @@ CLIENT_OBJS_ := \
src/server/sv_save.o \
src/server/sv_send.o \
src/server/sv_user.o \
src/server/sv_world.o \
src/unix/glob.o \
src/server/sv_world.o
ifeq ($(OSTYPE), Windows)
CLIENT_OBJS_ += \
src/windows/conproc.o \
src/windows/mem.o \
src/windows/network.o \
src/windows/qal.o \
src/windows/system.o \
src/windows/vid.o
else
CLIENT_OBJS_ += \
src/unix/hunk.o \
src/unix/main.o \
src/unix/network.o \
@ -393,6 +535,7 @@ CLIENT_OBJS_ := \
src/unix/signalhandler.o \
src/unix/system.o \
src/unix/vid.o
endif
# ----------
@ -401,6 +544,7 @@ SERVER_OBJS_ := \
src/common/crc.o \
src/common/cvar.o \
src/common/filesystem.o \
src/common/glob.o \
src/common/md4.o \
src/common/misc.o \
src/common/netchan.o \
@ -432,13 +576,22 @@ SERVER_OBJS_ := \
src/server/sv_save.o \
src/server/sv_send.o \
src/server/sv_user.o \
src/server/sv_world.o \
src/unix/glob.o \
src/server/sv_world.o
ifeq ($(OSTYPE), Windows)
SERVER_OBJS_ += \
src/windows/conproc.o \
src/windows/mem.o \
src/windows/network.o \
src/windows/system.o
else
SERVER_OBJS_ += \
src/unix/hunk.o \
src/unix/main.o \
src/unix/network.o \
src/unix/signalhandler.o \
src/unix/system.o
endif
# ----------
@ -463,10 +616,18 @@ OPENGL_OBJS_ = \
src/refresh/files/wal.o \
src/sdl/input.o \
src/sdl/refresh.o \
src/common/shared/shared.o \
src/unix/glob.o \
src/common/glob.o \
src/common/shared/shared.o
ifeq ($(OSTYPE), Windows)
OPENGL_OBJS_ += \
src/windows/mem.o \
src/windows/qgl.o
else
OPENGL_OBJS_ += \
src/unix/hunk.o \
src/unix/qgl.o
endif
# ----------
@ -495,23 +656,47 @@ GAME_DEPS= $(GAME_OBJS:.o=.d)
# ----------
# release/quake2
ifeq ($(OSTYPE), Windows)
release/quake2.exe : $(CLIENT_OBJS) icon
@echo "===> LD $@"
${Q}$(CC) build/icon/icon.res $(CLIENT_OBJS) $(LDFLAGS) $(SDLLDFLAGS) -o $@
else
release/quake2 : $(CLIENT_OBJS)
@echo '===> LD $@'
@echo "===> LD $@"
${Q}$(CC) $(CLIENT_OBJS) $(LDFLAGS) $(SDLLDFLAGS) -o $@
endif
# release/q2ded
ifeq ($(OSTYPE), Windows)
release/q2ded.exe : $(SERVER_OBJS) icon
@echo "===> LD $@.exe"
${Q}$(CC) build/icon/icon.res $(SERVER_OBJS) $(LDFLAGS) -o $@
else
release/q2ded : $(SERVER_OBJS)
@echo '===> LD $@'
@echo "===> LD $@"
${Q}$(CC) $(SERVER_OBJS) $(LDFLAGS) -o $@
endif
# release/ref_gl.so
ifeq ($(OSTYPE), Windows)
release/ref_gl.dll : $(OPENGL_OBJS)
@echo "===> LD $@"
${Q}$(CC) $(OPENGL_OBJS) $(LDFLAGS) $(SDLLDFLAGS) -o $@
else
release/ref_gl.so : $(OPENGL_OBJS)
@echo '===> LD $@'
@echo "===> LD $@"
${Q}$(CC) $(OPENGL_OBJS) $(LDFLAGS) $(X11LDFLAGS) -o $@
endif
# release/baseq2/game.so
release/baseq2/game.so : $(GAME_OBJS)
@echo '===> LD $@'
ifeq ($(OSTYPE), Windows)
release/baseq2/game.dll : $(GAME_OBJS)
@echo "===> LD $@"
${Q}$(CC) $(GAME_OBJS) $(LDFLAGS) -o $@
else
release/baseq2/game.so : $(GAME_OBJS)
@echo "===> LD $@"
${Q}$(CC) $(GAME_OBJS) $(LDFLAGS) -o $@
endif
# ----------

229
README
View file

@ -1,8 +1,8 @@
* ****************************** *
* Yamagi Quake II *
* http://www.yamagi.org/quake2 *
* http://github.com/yquake2 *
* ****************************** *
* ****************************** *
* Yamagi Quake II *
* http://www.yamagi.org/quake2 *
* http://github.com/yquake2 *
* ****************************** *
===============================================================================
@ -10,21 +10,21 @@ This is the Yamagi Quake II Client, an enhanced Version of id Software's
Quake II. The main focus is single player, the gameplay and the graphics are
unchanged, but many bugs were fixed. Unlike most other Quake II ports Yamagi
Quake II is full 64 bit clean so it works perfectly on modern amd64 (x86_64)
processors and operating systems. This code should run on most unix-like
operating systems (only FreeBSD and Linux are officially supported and tested,
for other systems you'd at least have to edit the Makefile), just type "make" or
"gmake" to compile.
processors and operating systems. This code should run on Windows XP or higher
and on most unix-like operating systems (only FreeBSD and Linux are officially
supported and tested, for other systems you'd at least have to edit the
Makefile), just type "make" or "gmake" to compile.
This code is based upon Icculus Quake II, which itself is built upon id
Software's original code drop. Additional code and patches by many contributers
were used. It's released under the terms of the GPL version 2. See the LICENSE
were used. It's released under the terms of the GPL version 2. See the LICENSE
file for further information.
===============================================================================
Content of this file:
--------------------
1. Installation
1. Installation on FreeBSD and Linux
1.1 Supported Systems
1.2 Retail Version
1.3 Demo Version
@ -32,31 +32,40 @@ Content of this file:
1.5 Compiling
1.6 Default Configuration
2. OGG/Vorbis playback
2.1 Setup for the original soundtrack
2.2 Setup for other music and playlists
2.3 Manual control
2.4 Console variables
2. Installation on Microsoft Windows
2.1 Supported Systems
2.2 Retail Version
2.3 Demo Version
2.4 Addons
2.5 Binary Installation
2.6 Compiling
2.7 Default Configuration
3. Configuration
3.1 Video
3.2 Input
3.3 Sound
3.3.1 The classic sound system
3.3.2 The OpenAL sound system
3. OGG/Vorbis playback
3.1 Setup for the original soundtrack
3.2 Setup for other music and playlists
3.3 Manual control
3.4 Console variables
4. Bugreports
4. Configuration
4.1 Video
4.2 Input
4.3 Sound
4.3.1 The classic sound system
4.3.2 The OpenAL sound system
5. FAQ
5. Bugreports
6. FAQ
===============================================================================
1. Installation
==============
1. Installation on FreeBSD and Linux
====================================
Note: If you're using Debian Linux or a derived distribution like Ubuntu, you
probably want to use the packages that are linked in the Download section at
http://www.yamagi.org/quake2/debian.html
They'll even assist you in installing the game data.
http://www.yamagi.org/quake2/debian.html They'll even assist you in installing
the game data.
1.1 Supported Systems:
----------------------
@ -64,17 +73,16 @@ Officially, only Linux and FreeBSD on i386 (x86) and amd64 (x86_64) compatible
CPUs are supported. Other (Unix-like) Operating Systems and hardware
architectures are untested and may need small changes, at least in the Makefile.
Yamagi Quake II needs OpenGL 1.1 (better: 1.4) support in hardware and libGL;
OpenGL ES will not work yet. It's in progress. The only tested compilers are gcc
4.2 (or later) and clang 3.0 (or later).
Patches (or better Github pull request) for other platforms are welcome :-)
OpenGL ES will not work. The only tested compilers are gcc 4.2 (or later) and
clang 3.0 (or later). Patches (or better Github pull request) for other
platforms are welcome. :-)
1.2 Retail Version:
-------------------
If you own Quake II, first get the official point release to Quake II 3.20:
ftp://ftp.idsoftware.com/idstuff/quake2/q2-3.20-x86-full-ctf.exe
Use this and only this file! Unofficial "linux pointreleases" or something like
that will not work and may crash your game!
ftp://ftp.idsoftware.com/idstuff/quake2/q2-3.20-x86-full-ctf.exe Use this and
only this file! Unofficial "linux pointreleases" or something like that will
not work and may crash your game!
Create a new directory "quake2/" and extract (with unzip) the file you just
downloaded into it. Even if the file extension is ".exe" it's a self-extracting
@ -100,11 +108,11 @@ the directory "video/" to the "baseq2/" directory of your installation.
If you haven't got Quake II, try the demo version. Get it here:
ftp://ftp.idsoftware.com/idstuff/quake2/q2-314-demo-x86.exe
Unzip this file (again, it's a self-extracting zip file).
Create a new "quake2/" directory with a "baseq2/" sub-directory and put the
"pak0.pak" and the "players/" sub-directory, you can find them within the
unzipped files (in Install/Data/baseq2/), in your "baseq2/" directory. No
patching is needed for the demo, in fact it would break it.
Unzip this file (again, it's a self-extracting zip file). Create a new
"quake2/" directory with a "baseq2/" sub-directory and put the "pak0.pak"
and the "players/" sub-directory, you can find them within the unzipped
files (in Install/Data/baseq2/), in your "baseq2/" directory. No patching
is needed for the demo, in fact it would break it.
1.4 Addons
----------
@ -151,14 +159,119 @@ Now you are ready to start your brand new Quake II. Have fun.
===============================================================================
2. OGG/Vorbis playback
2. Installation on Microsoft Windows
====================================
Yamagi Quake II has full support for Microsoft Windows. All features are
supported, including the IPv6 network code and the OpenAL sound backend.
Installation can be done by using the binary release (this is highly
recommended) or by compiling the source with MinGW.
2.1 Supported Systems
---------------------
Yamagi Quake II should run on Windows XP or higher, older versions are not
supported. You'll need a graphics card with support for at least OpenGL 1.1
(OpenGL 1.4 is recommended). Both x86 and x86_64 Windows installations are
supported.
2.2 Retail Version
------------------
If you own Quake II, first get the official point release to Quake II 3.20:
ftp://ftp.idsoftware.com/idstuff/quake2/q2-3.20-x86-full-ctf.exe
Use this and only this file! Unofficial pointreleases or something like
that will not work and may crash your game!
Extract the file into a new directory (we recommend quake2\) and delete
the following files and directories:
- 3.20_Changes.txt
- quake2.exe
- ref_gl.dll
- ref_soft.dll
- baseq2\gamex86.dll
- baseq2\maps.lst
- ctf\ctf2.ico
- ctf\gamex86.dll
- ctf\readme.txt
- ctf\server.cfg
- xatrix\gamex86.dll
- rogue\gamex86.dll
Now put the Quake II CD-ROM into your cd drive and cancel the installtion.
Copy "pak0.pak" and the directory "video\" to the "baseq2\" directory of your
installation.
2.3 Demo Version
----------------
If you haven't got Quake II, try the demo version. Get it here:
ftp://ftp.idsoftware.com/idstuff/quake2/q2-314-demo-x86.exe
Extract this file into a new directory and delete everything but
"baseq2\pak0.pk2" and the "baseq2\video\" directory. No patching
is needed for the demo, in fact it would break it.
2.4 Addons
----------
Due to license issues - Yamagi Quake II is covered by the GPL and the
addons are under the id Software SDK license - the addons are
distributed separately. You can get them at http://www.yamagi.org/quake2,
both contain installation instructions. But nevertheless you'll need an
installation of the full Quake II game with our client for playing them.
The same applies to the "ctf" capture the flag addon.
2.5 Binary Installation
-----------------------
We highly recommend, that you use our binary release of Yamagi Quake 2.
Just extract at over the directory created in step 2.3 or 2.4. If you
want to copy the files by hand, just copy them over by preserving the
directory structure.
2.6 Compiling
-------------
Compiling Yamagi Quake II from source is unnecessary as long as you will not
use the github version or want to develop on Windows. If you relly want to
compile Yamagi Quake II by yourself follow these steps:
1. Grab a copy of Nuwens MinGW distribution from http://nuwen.net/mingw.html
Our code is tested with version 9.0, newer version may work but we can not
guarantee that. Extract the distribution to a directory of your choice.
2. Grab a copy of OpenAL Soft from http://kcat.strangesoft.net/openal.html
(the binary release for Windows). Our code is tested with version 1.14.
Extract it and put the include\AL directory into the include\ directory
of the MinGW distribution.
3. Open the command window of Nuwens MinGW distribution, navigate to your
copy of the Yamagi Quake II source and type "make". This'll build the
Windows binaries.
After compiling, copy the following files from "release\" to your Quake II
installation preserving the directory structure:
- q2ded.exe
- quake2.exe
- ref_gl.dll
- baseq2\game.dll
You'll need a "openal32.dll" and an "SDL.dll" next to "quake2.exe". You can use
and rename the OpenAL DLL that came with OpenAL Soft. We recommend to use a
"SDL.dll" from http://libsdl.org and not the one supplied with Nuwens MinGW
distribution.
2.7 Default Configuration
-------------------------
Quake II ships with an old and for today standards "insane" default
configuration. This is no problem since you can alter everything. To make your
life easier Yamagi Quake II contains an updated default configuration.
If you want to use it just copy "stuff\yq2.cfg" to your "baseq2/" folder.
Now you are ready to start your brand new Quake II. Have fun.
===============================================================================
3. OGG/Vorbis playback
======================
Since most modern CD-ROM and DVD drives don't have an analog audio output and
most sound codecs don't have the appropriate input header, it's not possible to
use CD audio as background music on such systems. Therefore OGG/Vorbis music
support has been added to Yamagi Quake II.
2.1 Setup for the original soundtrack:
3.1 Setup for the original soundtrack:
--------------------------------------
Put your Quake II CD-ROM into your drive, start your favorite CD extractor and
rip the audiotracks into OGG/Vorbis files. These files must be named after their
@ -171,7 +284,7 @@ Drop these files in "baseq2/music/", start Quake II, enter the "Options" menu
and set "OGG music" to enabled. "CD music" will be automaticly disabled.
Quake II will now play the OGG/Vorbis files instead of the Audio-CD.
2.2 Setup for other music and playlists:
3.2 Setup for other music and playlists:
----------------------------------------
You can put any OGG/Vorbis files into "baseq2/music/" or "your_mod/music/".
If shuffle is enabled, Quake II will shuffle through all files, otherwise it
@ -179,7 +292,7 @@ will loop through the track associated with the map.
A playlist is also supported. Just put the filenames into music/playlist
(a plain text file) and start the game.
2.3 Manual control:
3.3 Manual control:
-------------------
For manual control of ogg playback the following console commands are available:
@ -212,7 +325,7 @@ For manual control of ogg playback the following console commands are available:
- ogg_status
Display status ("playing a file", "paused", "stopped", etc).
2.4 Console variables:
3.4 Console variables:
----------------------
- ogg_enable {0 | 1}
Enables the Ogg Vorbis subsystem if set to "1". Defaults to "0".
@ -236,13 +349,13 @@ For manual control of ogg playback the following console commands are available:
===============================================================================
3. Configuration
4. Configuration
================
While configuring Quake II is straight forward some rough edges can arise.
Before reporting bugs or mailing us please read this section all the hints
covered in it!
3.1 Video
4.1 Video
---------
For most people the options in the "Video" menu are sufficent. But there
are some things that can and in some cases must be tuned via cvars. Here
@ -305,7 +418,7 @@ the most common questions are answered.
"vid_restart" aftwards.
3.2 Input
4.2 Input
---------
Quake II had a rather simple input system, even back in 1997. It just mapped
Windows 95 mouse directly on movements. That was a very acurate way to do it,
@ -335,7 +448,7 @@ There are some cvar to adjust:
impossible to add modern acceleration to Quake II since most of the needed data
isn't available to the input backend.
3.3 Sound
4.3 Sound
---------
Quake II featured one of the best sound systems of it's time (for example it had
support for realtime calculated stereo effects) but sadly it was totaly broken.
@ -348,7 +461,7 @@ scratch. This should solve most if not all problems. Yamagi Quake II 4.20
featured an optional OpenAL sound system, enabling better stereo calculations
and even surround support.
3.3.1 The classic sound system
4.3.1 The classic sound system
------------------------------
This is the original sound implementation, as used in the first release of Quake
II in 1997. It featured stereo calculations for most samples. It's disabled by
@ -378,7 +491,7 @@ default and can be reenables by setting "s_openal" to "0", followed by
card 0
}
3.3.2 The OpenAL sound system
4.3.2 The OpenAL sound system
-----------------------------
This is a sound system based upon the popular OpenAL audio library. It features
surround playback which gives a huge improvement in sound quality and gameplay
@ -402,7 +515,7 @@ important options (tested with OpenAL Soft 1.14) are:
===============================================================================
4. Bugreports
5. Bugreports
=============
Something is not working as expected? An elevator is broken? An enemy doesn't
move? Or the whole game is just crashing? Just open an issue at
@ -440,7 +553,7 @@ Valgrind reports many, many memory leaks!
===============================================================================
5. FAQ
6. FAQ
======
How do I open the console?
@ -519,13 +632,15 @@ Can I connect to an IPv6 server?
./q2ded +set ip "[2001:db8::1]"
Where can I find the configuartion file?
- It's located at ~/.yq2/game/config.cfg. Replace "game" by the mod name,
e.g. "baseq2/" for the main game.
- It's located at ~/.yq2/game/config.cfg (FreeBSD and Linux) or
C:\Users\Username\Documents\YamagiQ2\game\config.cfg (Windows).
Replace "game" by the mod name, e.g. "baseq2/" for the main game.
My mod crashes at startup.
- This is known problem, yet to be analyzed. A workaround is to create the
working directory by hand:
mkdir -p ~/.yq2/$moddir
mkdir -p ~/.yq2/$moddir (FreeBSD and Linux)
C:\Users\Username\Documents\YamagiQ2\$moddir (Windows)
Only parts of the maps are rendered!
- By default the maximum view distance is 2300 units. You can widen it up
@ -535,7 +650,7 @@ Why has Yamagi Quake II no support for joysticks?
- Because nobody has implemented it yet and egoshooters like Quake II
are not really meant to be played with joysticks, gamepads or anything
like that. If you really need joystick support you can use a joystick
to keyboard translator like joytran:
to keyboard translator like joytran (for FreeBSD and Linux):
http://chiselapp.com/user/beyert/repository/joytran/index
==============================================================================

79
TODO Normal file
View file

@ -0,0 +1,79 @@
Long term TODO list for Quake II on Windows
-------------------------------------------
1. Test various windows version in different
localizations. At least:
- Windows XP [done]
- Windows XP 64
- Windows 2003
- Windows Vista
- Windows 2008
- Windows 7 [done]
- Windows 8 Preview [done]
2. The "dsound" sound system issue:
By default SDL uses the "waveout" sound driver which
needs to many buffers to be usable with Quake II. There
is no easy way to work around this, we can neither call
the sound system more often nor generate more sound per
call. The short term solution is to force the DirectX 5
based "dsound" driver. But "dsound" is unavailable for
64 bit applications on 64 bit Windows and on Windows 8.
SDL 2.0 has the new DirectX 8 based "directsound" driver
but that would require a port of Yamagi Quake II to the
still unstable SDL 2.0. Another soultion would be a
custom SDL.dll with the new driver backported to SDL
1.2.15. Be aware, that this problem only affects the
SDL sound-backend and not the default OpenAL backend!
3. The keyboard layout issue:
SDL 1.2 has a bug which results in untranslated keycodes
on non qwerty layouts. The consequence is, that Quake II
uses always the english keyboard layout, regardless of it's
real layout and the layout setting in the windows control
pannel. The recommendet work around is to switch SDL into
unicode mode and read unicode characters instead of the
raw keycodes. But implementing this into Quake II would
be a real PITA due to the rather complex differences
between the internal input system and SDL. ioQuake3 uses
unicode input for the console and raw input for the key
bingings, has therefor a correct layout in the console
but an english layout on normal key bindings. Their
implementation is rather invasive into the console
subsystem and I don't think that it's worth the efford.
4. The unicode issue:
Quake II only allows ASCII characters, internally all
characters are represented as "char". But Windows uses
unicode quite often. This may lead to problems. The big
question is: "What happens, if the path to the home dir
contains unicode characters?" At what can we do to prevent
problems without rewriting the whole game to be unicode
aware? This may be a problem on Linux and FreeBSD too,
but at least on FreeBSD unicode characters in the user-
name are a bad idea and for things to work correctly
the homedir-name should be the same as the username...
5. The debug / stdout issue:
At the moment no stdout is readable on windows, the only
way is to scroll in the console. This is a problem, because
without the game output problems are hard to debug. Enabling
the console log by default might migitate the problem, but
the early startup is not convered by it. One solution would
be to redirect stdout into a file (like dhewm). Daniel
suggested to implement a console window like the orginal
Quake III Arena client had.
It would be nice, if the Windows crash handler would be
invoced at every crash and not only sometimes. In theory
the crash handler is able to create crash dumps and send
them to a remore location (only Micorsoft or anybody?).
While I'm not sure that gdb can read Windows crashdumps,
it may be worth to take a deeper look into this.
6. The CR-LF issue:
At the moment all files have LF line endings, which are
incompatible with most Windows software. This isn't a
problem for the code itself (at least with MinGW), but
for the documentation. A possible solution is to use git
to convert the file endings at checkout. This would leave
the repo at LF and enable CR-LF for Windows.

View file

@ -578,7 +578,7 @@ void CL_InitLocal (void)
void CL_WriteConfiguration (void)
{
FILE *f;
char path[MAX_QPATH];
char path[MAX_OSPATH];
if (cls.state == ca_uninitialized)
return;

View file

@ -27,89 +27,97 @@
#ifndef CL_SOUND_LOCAL_H
#define CL_SOUND_LOCAL_H
typedef struct {
int left;
int right;
typedef struct
{
int left;
int right;
} portable_samplepair_t;
typedef struct {
int length;
int loopstart;
int speed; /* not needed, because converted on load? */
int width;
typedef struct
{
int length;
int loopstart;
int speed; /* not needed, because converted on load? */
int width;
#if USE_OPENAL
int size;
int bufnum;
int size;
int bufnum;
#endif
int stereo;
byte data[1]; /* variable sized */
int stereo;
byte data[1]; /* variable sized */
} sfxcache_t;
typedef struct sfx_s {
char name[MAX_QPATH];
int registration_sequence;
sfxcache_t *cache;
char *truename;
typedef struct sfx_s
{
char name[MAX_QPATH];
int registration_sequence;
sfxcache_t *cache;
char *truename;
} sfx_t;
/* a playsound_t will be generated by each call to S_StartSound,
when the mixer reaches playsound->begin, the playsound will
be assigned to a channel */
typedef struct playsound_s {
struct playsound_s *prev, *next;
sfx_t *sfx;
float volume;
float attenuation;
int entnum;
int entchannel;
qboolean fixed_origin; /* use origin field instead of entnum's origin */
vec3_t origin;
unsigned begin; /* begin on this sample */
* when the mixer reaches playsound->begin, the playsound will
* be assigned to a channel */
typedef struct playsound_s
{
struct playsound_s *prev, *next;
sfx_t *sfx;
float volume;
float attenuation;
int entnum;
int entchannel;
qboolean fixed_origin; /* use origin field instead of entnum's origin */
vec3_t origin;
unsigned begin; /* begin on this sample */
} playsound_t;
typedef struct {
int channels;
int samples; /* mono samples in buffer */
int submission_chunk; /* don't mix less than this */
int samplepos; /* in mono samples */
int samplebits;
int speed;
byte *buffer;
typedef struct
{
int channels;
int samples; /* mono samples in buffer */
int submission_chunk; /* don't mix less than this */
int samplepos; /* in mono samples */
int samplebits;
int speed;
byte *buffer;
} dma_t;
typedef struct {
sfx_t *sfx; /* sfx number */
int leftvol; /* 0-255 volume */
int rightvol; /* 0-255 volume */
int end; /* end time in global paintsamples */
int pos; /* sample position in sfx */
int looping; /* where to loop, -1 = no looping */
int entnum; /* to allow overriding a specific sound */
int entchannel;
vec3_t origin; /* only use if fixed_origin is set */
vec_t dist_mult; /* distance multiplier (attenuation/clipK) */
int master_vol; /* 0-255 master volume */
qboolean fixed_origin; /* use origin instead of fetching entnum's origin */
qboolean autosound; /* from an entity->sound, cleared each frame */
typedef struct
{
sfx_t *sfx; /* sfx number */
int leftvol; /* 0-255 volume */
int rightvol; /* 0-255 volume */
int end; /* end time in global paintsamples */
int pos; /* sample position in sfx */
int looping; /* where to loop, -1 = no looping */
int entnum; /* to allow overriding a specific sound */
int entchannel;
vec3_t origin; /* only use if fixed_origin is set */
vec_t dist_mult; /* distance multiplier (attenuation/clipK) */
int master_vol; /* 0-255 master volume */
qboolean fixed_origin; /* use origin instead of fetching entnum's origin */
qboolean autosound; /* from an entity->sound, cleared each frame */
#if USE_OPENAL
int autoframe;
int srcnum;
int autoframe;
int srcnum;
#endif
} channel_t;
typedef struct {
int rate;
int width;
int channels;
int loopstart;
int samples;
int dataofs; /* chunk starts this many bytes from file start */
typedef struct
{
int rate;
int width;
int channels;
int loopstart;
int samples;
int dataofs; /* chunk starts this many bytes from file start */
} wavinfo_t;
typedef enum {
SS_NOT = 0, // soundsystem not started
SS_DMA, // soundsystem started, using DMA/SDL
SS_OAL // soundsystem started, using OpenAL
typedef enum
{
SS_NOT = 0, /* soundsystem not started */
SS_DMA, /* soundsystem started, using DMA/SDL */
SS_OAL /* soundsystem started, using OpenAL */
} sndstarted_t;
extern sndstarted_t sound_started;
@ -119,42 +127,42 @@ extern sndstarted_t sound_started;
qboolean SNDDMA_Init(void);
/* gets the current DMA position */
int SNDDMA_GetDMAPos(void);
int SNDDMA_GetDMAPos(void);
/* shutdown the DMA xfer. */
void SNDDMA_Shutdown(void);
void SNDDMA_BeginPainting (void);
void SNDDMA_Submit(void);
void SNDDMA_Shutdown(void);
void SNDDMA_BeginPainting(void);
void SNDDMA_Submit(void);
#define MAX_CHANNELS 32
extern channel_t channels[MAX_CHANNELS];
extern int s_numchannels;
#define MAX_CHANNELS 32
extern channel_t channels[MAX_CHANNELS];
extern int s_numchannels;
extern int paintedtime;
extern int s_rawend;
extern vec3_t listener_origin;
extern vec3_t listener_forward;
extern vec3_t listener_right;
extern vec3_t listener_up;
extern dma_t dma;
extern playsound_t s_pendingplays;
extern int paintedtime;
extern int s_rawend;
extern vec3_t listener_origin;
extern vec3_t listener_forward;
extern vec3_t listener_right;
extern vec3_t listener_up;
extern dma_t dma;
extern playsound_t s_pendingplays;
#define MAX_RAW_SAMPLES 8192
extern portable_samplepair_t s_rawsamples[MAX_RAW_SAMPLES];
#define MAX_RAW_SAMPLES 8192
extern portable_samplepair_t s_rawsamples[MAX_RAW_SAMPLES];
extern cvar_t *s_volume;
extern cvar_t *s_nosound;
extern cvar_t *s_loadas8bit;
extern cvar_t *s_khz;
extern cvar_t *s_show;
extern cvar_t *s_mixahead;
extern cvar_t *s_testsound;
extern cvar_t *s_ambient;
extern cvar_t *s_volume;
extern cvar_t *s_nosound;
extern cvar_t *s_loadas8bit;
extern cvar_t *s_khz;
extern cvar_t *s_show;
extern cvar_t *s_mixahead;
extern cvar_t *s_testsound;
extern cvar_t *s_ambient;
wavinfo_t GetWavinfo (char *name, byte *wav, int wavlength);
void S_InitScaletable (void);
sfxcache_t *S_LoadSound (sfx_t *s);
void S_IssuePlaysound (playsound_t *ps);
wavinfo_t GetWavinfo(char *name, byte *wav, int wavlength);
void S_InitScaletable(void);
sfxcache_t *S_LoadSound(sfx_t *s);
void S_IssuePlaysound(playsound_t *ps);
void S_PaintChannels(int endtime);
/* picks a channel based on priorities, empty slots, number of channels */
@ -163,28 +171,30 @@ channel_t *S_PickChannel(int entnum, int entchannel);
/* spatializes a channel */
void S_Spatialize(channel_t *ch);
void S_BuildSoundList( int *sounds );
void S_BuildSoundList(int *sounds);
#if USE_OPENAL
// this stuff was taken from Q2Pro
// only begin attenuating sound volumes when outside the FULLVOLUME range
#define SOUND_FULLVOLUME 80
#define SOUND_LOOPATTENUATE 0.003
/* Only begin attenuating sound volumes
when outside the FULLVOLUME range */
#define SOUND_FULLVOLUME 80
#define SOUND_LOOPATTENUATE 0.003
// number of buffers in flight (needed for ogg)
/* number of buffers in flight (needed for ogg) */
extern int active_buffers;
// for snd_al.c - copied from Q2Pro and adapted
void AL_SoundInfo( void );
qboolean AL_Init( void );
void AL_Shutdown( void );
sfxcache_t *AL_UploadSfx( sfx_t *s, wavinfo_t *s_info, byte *data );
void AL_DeleteSfx( sfx_t *s );
void AL_StopChannel( channel_t *ch );
void AL_PlayChannel( channel_t *ch );
void AL_StopAllChannels( void );
void AL_Update( void );
void AL_RawSamples( int samples, int rate, int width, int channels, byte *data, float volume );
#endif
/* for snd_al.c - copied from Q2Pro and adapted */
void AL_SoundInfo(void);
qboolean AL_Init(void);
void AL_Shutdown(void);
sfxcache_t *AL_UploadSfx(sfx_t *s, wavinfo_t *s_info, byte *data);
void AL_DeleteSfx(sfx_t *s);
void AL_StopChannel(channel_t *ch);
void AL_PlayChannel(channel_t *ch);
void AL_StopAllChannels(void);
void AL_Update(void);
void AL_RawSamples(int samples, int rate, int width,
int channels, byte *data, float volume);
#endif
#endif

View file

@ -30,24 +30,29 @@
struct sfx_s;
void S_Init (void);
void S_Shutdown (void);
void S_Init(void);
void S_Shutdown(void);
/* if origin is NULL, the sound will be dynamically sourced from the entity */
void S_StartSound (vec3_t origin, int entnum, int entchannel, struct sfx_s *sfx, float fvol, float attenuation, float timeofs);
/* if origin is NULL, the sound will be
dynamically sourced from the entity */
void S_StartSound(vec3_t origin, int entnum, int entchannel,
struct sfx_s *sfx, float fvol, float attenuation,
float timeofs);
void S_StartLocalSound (char *s);
void S_RawSamples (int samples, int rate, int width, int channels, byte *data, float volume);
void S_StartLocalSound(char *s);
void S_RawSamples(int samples, int rate, int width, int channels,
byte *data, float volume);
void S_StopAllSounds(void);
void S_Update (vec3_t origin, vec3_t v_forward, vec3_t v_right, vec3_t v_up);
void S_Activate (qboolean active);
void S_BeginRegistration (void);
struct sfx_s *S_RegisterSound (char *sample);
void S_EndRegistration (void);
struct sfx_s *S_FindName (char *name, qboolean create);
void S_Update(vec3_t origin, vec3_t v_forward, vec3_t v_right, vec3_t v_up);
void S_Activate(qboolean active);
void S_BeginRegistration(void);
struct sfx_s *S_RegisterSound(char *sample);
void S_EndRegistration(void);
struct sfx_s *S_FindName(char *name, qboolean create);
/* the sound code makes callbacks to the client for entitiy position
information, so entities can be dynamically re-spatialized */
void CL_GetEntitySoundOrigin (int ent, vec3_t org);
/* the sound code makes callbacks to the client for
entitiy position information, so entities can be
dynamically re-spatialized */
void CL_GetEntitySoundOrigin(int ent, vec3_t org);
#endif

View file

@ -25,49 +25,51 @@
#ifdef OGG
#ifndef CL_SOUND_VORBIS_H
#define CL_SOUND_VORBIS_H
#define CL_SOUND_VORBIS_H
/* The OGG codec can return the samples in a number
of different formats, we use the standard signed
short format. */
#define OGG_SAMPLEWIDTH 2
* of different formats, we use the standard signed
* short format. */
#define OGG_SAMPLEWIDTH 2
#define OGG_DIR "music"
#define OGG_DIR "music"
typedef enum {
typedef enum
{
PLAY,
PAUSE,
STOP
} ogg_status_t;
typedef enum {
typedef enum
{
ABS,
REL
} ogg_seek_t;
void OGG_Init (void);
void OGG_Shutdown(void);
void OGG_Reinit(void);
qboolean OGG_Check(char *name);
void OGG_Seek (ogg_seek_t type, double offset);
void OGG_LoadFileList(void);
void OGG_LoadPlaylist(char *name);
qboolean OGG_Open(ogg_seek_t type, int offset);
qboolean OGG_OpenName(char *filename);
int OGG_Read (void);
void OGG_Sequence(void);
void OGG_Stop (void);
void OGG_Stream(void);
void S_RawSamplesVol(int samples, int rate, int width, int channels, byte * data, float volume);
void OGG_Init(void);
void OGG_Shutdown(void);
void OGG_Reinit(void);
qboolean OGG_Check(char *name);
void OGG_Seek(ogg_seek_t type, double offset);
void OGG_LoadFileList(void);
void OGG_LoadPlaylist(char *name);
qboolean OGG_Open(ogg_seek_t type, int offset);
qboolean OGG_OpenName(char *filename);
int OGG_Read(void);
void OGG_Sequence(void);
void OGG_Stop(void);
void OGG_Stream(void);
void S_RawSamplesVol(int samples, int rate, int width,
int channels, byte *data, float volume);
/* Console commands. */
void OGG_ListCmd(void);
void OGG_ParseCmd(char *arg);
void OGG_PauseCmd(void);
void OGG_PlayCmd(void);
void OGG_ResumeCmd(void);
void OGG_SeekCmd(void);
void OGG_StatusCmd(void);
void OGG_ListCmd(void);
void OGG_ParseCmd(char *arg);
void OGG_PauseCmd(void);
void OGG_PlayCmd(void);
void OGG_ResumeCmd(void);
void OGG_SeekCmd(void);
void OGG_StatusCmd(void);
#endif
#endif

View file

@ -21,10 +21,9 @@
*
* =======================================================================
*
* Most of these functions are from the Q2Pro project, and some are from
* zeq2. We adapted them to work with Yamagi Quake II
*
* This is an OpenAL backend for the Quake II Soundsystem.
* This is an OpenAL backend for the Quake II Soundsystem. Most of these
* functions are from the Q2Pro project, and some are from zeq2. We
* adapted them to work with Yamagi Quake II.
*
* =======================================================================
*/
@ -32,15 +31,21 @@
#ifdef USE_OPENAL
#include "../header/client.h"
#include "../../unix/header/qal.h"
#include "header/local.h"
#include "header/vorbis.h"
// translates from AL coordinate system to quake
#define AL_UnpackVector(v) -v[1],v[2],-v[0]
#define AL_CopyVector(a,b) ((b)[0]=-(a)[1],(b)[1]=(a)[2],(b)[2]=-(a)[0])
#ifdef _WIN32
#include "../../windows/header/qal.h"
#else
#include "../../unix/header/qal.h"
#endif
// OpenAL implementation should support at least this number of sources
/* translates from AL coordinate system to quake */
#define AL_UnpackVector(v) - v[1], v[2], -v[0]
#define AL_CopyVector(a, b) ((b)[0] = -(a)[1], (b)[1] = (a)[2], (b)[2] = \
-(a)[0])
/* OpenAL implementation should support at least this number of sources */
#define MIN_CHANNELS 16
qboolean streamPlaying;
@ -49,27 +54,31 @@ int active_buffers;
static ALuint streamSource;
static ALuint underwaterFilter;
static ALuint s_srcnums[MAX_CHANNELS-1];
static ALuint s_srcnums[MAX_CHANNELS - 1];
static int s_framecount;
// Forward Declarations
static void S_AL_StreamUpdate( void );
static void S_AL_StreamDie( void );
// /Forward Declarations
/* Forward Declarations */
static void S_AL_StreamUpdate(void);
static void S_AL_StreamDie(void);
static void AL_InitStreamSource() {
qalSourcei (streamSource, AL_BUFFER, 0 );
qalSourcei (streamSource, AL_LOOPING, AL_FALSE );
qalSource3f(streamSource, AL_POSITION, 0.0, 0.0, 0.0);
qalSource3f(streamSource, AL_VELOCITY, 0.0, 0.0, 0.0);
qalSource3f(streamSource, AL_DIRECTION, 0.0, 0.0, 0.0);
qalSourcef (streamSource, AL_ROLLOFF_FACTOR, 0.0 );
qalSourcei (streamSource, AL_SOURCE_RELATIVE, AL_TRUE );
/* /Forward Declarations */
static void
AL_InitStreamSource()
{
qalSourcei(streamSource, AL_BUFFER, 0);
qalSourcei(streamSource, AL_LOOPING, AL_FALSE);
qalSource3f(streamSource, AL_POSITION, 0.0, 0.0, 0.0);
qalSource3f(streamSource, AL_VELOCITY, 0.0, 0.0, 0.0);
qalSource3f(streamSource, AL_DIRECTION, 0.0, 0.0, 0.0);
qalSourcef(streamSource, AL_ROLLOFF_FACTOR, 0.0);
qalSourcei(streamSource, AL_SOURCE_RELATIVE, AL_TRUE);
}
static void AL_InitUnderwaterFilter()
static void
AL_InitUnderwaterFilter()
{
// Generate a filter
/* Generate a filter */
qalGenFilters(1, &underwaterFilter);
if (qalGetError() != AL_NO_ERROR)
@ -78,7 +87,7 @@ static void AL_InitUnderwaterFilter()
return;
}
// Low pass filter for underwater effect
/* Low pass filter for underwater effect */
qalFilteri(underwaterFilter, AL_FILTER_TYPE, AL_FILTER_LOWPASS);
if (qalGetError() != AL_NO_ERROR)
@ -87,44 +96,55 @@ static void AL_InitUnderwaterFilter()
return;
}
// The effect
/* The effect */
qalFilterf(underwaterFilter, AL_LOWPASS_GAIN, 1.5);
qalFilterf(underwaterFilter, AL_LOWPASS_GAINHF, 0.25);
}
qboolean AL_Init( void ) {
qboolean
AL_Init(void)
{
int i;
if( !QAL_Init() ) {
Com_Printf( "ERROR: OpenAL failed to initialize.\n" );
if (!QAL_Init())
{
Com_Printf("ERROR: OpenAL failed to initialize.\n");
return false;
}
// check for linear distance extension
if( !qalIsExtensionPresent( "AL_EXT_LINEAR_DISTANCE" ) ) {
Com_Printf( "ERROR: Required AL_EXT_LINEAR_DISTANCE extension is missing.\n" );
/* check for linear distance extension */
if (!qalIsExtensionPresent("AL_EXT_LINEAR_DISTANCE"))
{
Com_Printf("ERROR: Required AL_EXT_LINEAR_DISTANCE extension is missing.\n");
goto fail;
}
// generate source names
/* generate source names */
qalGetError();
qalGenSources( 1, &streamSource );
if( qalGetError() != AL_NO_ERROR )
{
Com_Printf( "ERROR: Couldn't get a single Source.\n" );
goto fail;
qalGenSources(1, &streamSource);
} else {
// -1 because we already got one channel for streaming
for( i = 0; i < MAX_CHANNELS - 1; i++ ) {
qalGenSources( 1, &s_srcnums[i] );
if( qalGetError() != AL_NO_ERROR ) {
if (qalGetError() != AL_NO_ERROR)
{
Com_Printf("ERROR: Couldn't get a single Source.\n");
goto fail;
}
else
{
/* -1 because we already got one channel for streaming */
for (i = 0; i < MAX_CHANNELS - 1; i++)
{
qalGenSources(1, &s_srcnums[i]);
if (qalGetError() != AL_NO_ERROR)
{
break;
}
}
if( i < MIN_CHANNELS - 1 ) {
Com_Printf( "ERROR: Required at least %d sources, but got %d.\n", MIN_CHANNELS, i+1 );
if (i < MIN_CHANNELS - 1)
{
Com_Printf("ERROR: Required at least %d sources, but got %d.\n",
MIN_CHANNELS, i + 1);
goto fail;
}
}
@ -142,44 +162,53 @@ fail:
return false;
}
void AL_Shutdown( void ) {
Com_Printf( "Shutting down OpenAL.\n" );
void
AL_Shutdown(void)
{
Com_Printf("Shutting down OpenAL.\n");
S_AL_StreamDie();
qalDeleteSources(1, &streamSource);
qalDeleteFilters(1, &underwaterFilter);
if( s_numchannels ) {
// delete source names
qalDeleteSources( s_numchannels, s_srcnums );
memset( s_srcnums, 0, sizeof( s_srcnums ) );
if (s_numchannels)
{
/* delete source names */
qalDeleteSources(s_numchannels, s_srcnums);
memset(s_srcnums, 0, sizeof(s_srcnums));
s_numchannels = 0;
}
QAL_Shutdown();
}
sfxcache_t *AL_UploadSfx( sfx_t *s, wavinfo_t *s_info, byte *data ) {
sfxcache_t *
AL_UploadSfx(sfx_t *s, wavinfo_t *s_info, byte *data)
{
sfxcache_t *sc;
ALsizei size = s_info->samples * s_info->width;
ALenum format = s_info->width == 2 ? AL_FORMAT_MONO16 : AL_FORMAT_MONO8;
ALuint name;
if( !size ) {
if (!size)
{
return NULL;
}
qalGetError();
qalGenBuffers( 1, &name );
qalBufferData( name, format, data, size, s_info->rate );
qalGenBuffers(1, &name);
qalBufferData(name, format, data, size, s_info->rate);
active_buffers++;
if( qalGetError() != AL_NO_ERROR ) {
if (qalGetError() != AL_NO_ERROR)
{
return NULL;
}
// allocate placeholder sfxcache
/* allocate placeholder sfxcache */
sc = s->cache = Z_TagMalloc(sizeof(*sc), 0);
sc->length = s_info->samples * 1000 / s_info->rate; // in msec
sc->length = s_info->samples * 1000 / s_info->rate; /* in msec */
sc->loopstart = s_info->loopstart;
sc->width = s_info->width;
sc->size = size;
@ -188,147 +217,212 @@ sfxcache_t *AL_UploadSfx( sfx_t *s, wavinfo_t *s_info, byte *data ) {
return sc;
}
void AL_DeleteSfx( sfx_t *s ) {
void
AL_DeleteSfx(sfx_t *s)
{
sfxcache_t *sc;
ALuint name;
sc = s->cache;
if( !sc ) {
if (!sc)
{
return;
}
name = sc->bufnum;
qalDeleteBuffers( 1, &name );
qalDeleteBuffers(1, &name);
active_buffers--;
}
void AL_StopChannel( channel_t *ch ) {
void
AL_StopChannel(channel_t *ch)
{
if (s_show->value > 1)
Com_Printf("%s: %s\n", __func__, ch->sfx->name );
// stop it
qalSourceStop( ch->srcnum );
qalSourcei( ch->srcnum, AL_BUFFER, AL_NONE );
memset (ch, 0, sizeof(*ch));
}
static void AL_Spatialize( channel_t *ch ) {
vec3_t origin;
// anything coming from the view entity will always be full volume
// no attenuation = no spatialization
if( ch->entnum == -1 || ch->entnum == cl.playernum + 1 || !ch->dist_mult ) {
VectorCopy( listener_origin, origin );
} else if( ch->fixed_origin ) {
VectorCopy( ch->origin, origin );
} else {
CL_GetEntitySoundOrigin( ch->entnum, origin );
{
Com_Printf("%s: %s\n", __func__, ch->sfx->name);
}
qalSource3f( ch->srcnum, AL_POSITION, AL_UnpackVector( origin ) );
/* stop it */
qalSourceStop(ch->srcnum);
qalSourcei(ch->srcnum, AL_BUFFER, AL_NONE);
memset(ch, 0, sizeof(*ch));
}
void AL_PlayChannel( channel_t *ch ) {
static void
AL_Spatialize(channel_t *ch)
{
vec3_t origin;
/* anything coming from the view entity
will always be full volume. no
attenuation = no spatialization */
if ((ch->entnum == -1) || (ch->entnum == cl.playernum + 1) ||
!ch->dist_mult)
{
VectorCopy(listener_origin, origin);
}
else if (ch->fixed_origin)
{
VectorCopy(ch->origin, origin);
}
else
{
CL_GetEntitySoundOrigin(ch->entnum, origin);
}
qalSource3f(ch->srcnum, AL_POSITION, AL_UnpackVector(origin));
}
void
AL_PlayChannel(channel_t *ch)
{
sfxcache_t *sc = ch->sfx->cache;
if (s_show->value > 1)
Com_Printf("%s: %s\n", __func__, ch->sfx->name );
{
Com_Printf("%s: %s\n", __func__, ch->sfx->name);
}
ch->srcnum = s_srcnums[ch - channels];
qalGetError();
qalSourcei( ch->srcnum, AL_BUFFER, sc->bufnum );
qalSourcei( ch->srcnum, AL_LOOPING, ch->autosound ? AL_TRUE : AL_FALSE );
qalSourcef( ch->srcnum, AL_GAIN, ch->master_vol );
qalSourcef( ch->srcnum, AL_REFERENCE_DISTANCE, SOUND_FULLVOLUME );
qalSourcef( ch->srcnum, AL_MAX_DISTANCE, 8192 );
qalSourcef( ch->srcnum, AL_ROLLOFF_FACTOR, ch->dist_mult * ( 8192 - SOUND_FULLVOLUME ) );
qalSourcei(ch->srcnum, AL_BUFFER, sc->bufnum);
qalSourcei(ch->srcnum, AL_LOOPING, ch->autosound ? AL_TRUE : AL_FALSE);
qalSourcef(ch->srcnum, AL_GAIN, ch->master_vol);
qalSourcef(ch->srcnum, AL_REFERENCE_DISTANCE, SOUND_FULLVOLUME);
qalSourcef(ch->srcnum, AL_MAX_DISTANCE, 8192);
qalSourcef(ch->srcnum, AL_ROLLOFF_FACTOR, ch->dist_mult *
(8192 - SOUND_FULLVOLUME));
AL_Spatialize( ch );
AL_Spatialize(ch);
// play it
qalSourcePlay( ch->srcnum );
if( qalGetError() != AL_NO_ERROR ) {
AL_StopChannel( ch );
/* play it */
qalSourcePlay(ch->srcnum);
if (qalGetError() != AL_NO_ERROR)
{
AL_StopChannel(ch);
}
}
void AL_StopAllChannels( void ) {
int i;
channel_t *ch;
void
AL_StopAllChannels(void)
{
int i;
channel_t *ch;
ch = channels;
for( i = 0; i < s_numchannels; i++, ch++ ) {
for (i = 0; i < s_numchannels; i++, ch++)
{
if (!ch->sfx)
{
continue;
AL_StopChannel( ch );
}
AL_StopChannel(ch);
}
s_rawend = 0;
S_AL_StreamDie();
}
static channel_t *AL_FindLoopingSound( int entnum, sfx_t *sfx ) {
int i;
channel_t *ch;
static channel_t *
AL_FindLoopingSound(int entnum, sfx_t *sfx)
{
int i;
channel_t *ch;
ch = channels;
for( i = 0; i < s_numchannels; i++, ch++ ) {
if( !ch->sfx )
for (i = 0; i < s_numchannels; i++, ch++)
{
if (!ch->sfx)
{
continue;
if( !ch->autosound )
}
if (!ch->autosound)
{
continue;
if( ch->entnum != entnum )
}
if (ch->entnum != entnum)
{
continue;
if( ch->sfx != sfx )
}
if (ch->sfx != sfx)
{
continue;
}
return ch;
}
return NULL;
}
static void AL_AddLoopSounds( void ) {
int i;
int sounds[MAX_EDICTS];
channel_t *ch;
sfx_t *sfx;
sfxcache_t *sc;
int num;
entity_state_t *ent;
static void
AL_AddLoopSounds(void)
{
int i;
int sounds[MAX_EDICTS];
channel_t *ch;
sfx_t *sfx;
sfxcache_t *sc;
int num;
entity_state_t *ent;
if( cls.state != ca_active || cl_paused->value || !s_ambient->value ) {
if ((cls.state != ca_active) || cl_paused->value || !s_ambient->value)
{
return;
}
S_BuildSoundList( sounds );
S_BuildSoundList(sounds);
for( i = 0; i < cl.frame.num_entities; i++ ) {
for (i = 0; i < cl.frame.num_entities; i++)
{
if (!sounds[i])
{
continue;
}
sfx = cl.sound_precache[sounds[i]];
if (!sfx)
continue; // bad sound effect
{
continue; /* bad sound effect */
}
sc = sfx->cache;
if (!sc)
{
continue;
}
num = ( cl.frame.parse_entities + i ) & ( MAX_PARSE_ENTITIES - 1 );
ent = &cl_parse_entities [ num ];
num = (cl.frame.parse_entities + i) & (MAX_PARSE_ENTITIES - 1);
ent = &cl_parse_entities[num];
ch = AL_FindLoopingSound( ent->number, sfx );
if( ch ) {
ch = AL_FindLoopingSound(ent->number, sfx);
if (ch)
{
ch->autoframe = s_framecount;
ch->end = paintedtime + sc->length;
continue;
}
// allocate a channel
/* allocate a channel */
ch = S_PickChannel(0, 0);
if (!ch)
continue;
ch->autosound = true; // remove next frame
if (!ch)
{
continue;
}
ch->autosound = true; /* remove next frame */
ch->autoframe = s_framecount;
ch->sfx = sfx;
ch->entnum = ent->number;
@ -336,96 +430,123 @@ static void AL_AddLoopSounds( void ) {
ch->dist_mult = SOUND_LOOPATTENUATE;
ch->end = paintedtime + sc->length;
AL_PlayChannel( ch );
AL_PlayChannel(ch);
}
}
static void AL_IssuePlaysounds( void ) {
static void
AL_IssuePlaysounds(void)
{
playsound_t *ps;
// start any playsounds
while (1) {
/* start any playsounds */
while (1)
{
ps = s_pendingplays.next;
if (ps == &s_pendingplays)
break; // no more pending sounds
{
break; /* no more pending sounds */
}
if (ps->begin > paintedtime)
{
break;
S_IssuePlaysound (ps);
}
S_IssuePlaysound(ps);
}
}
void AL_Update( void ) {
int i;
channel_t *ch;
vec_t orientation[6];
void
AL_Update(void)
{
int i;
channel_t *ch;
vec_t orientation[6];
paintedtime = cl.time;
// set listener parameters
qalListener3f( AL_POSITION, AL_UnpackVector( listener_origin ) );
AL_CopyVector( listener_forward, orientation );
AL_CopyVector( listener_up, orientation + 3 );
qalListenerfv( AL_ORIENTATION, orientation );
qalListenerf( AL_GAIN, s_volume->value );
qalDistanceModel( AL_LINEAR_DISTANCE_CLAMPED );
/* set listener parameters */
qalListener3f(AL_POSITION, AL_UnpackVector(listener_origin));
AL_CopyVector(listener_forward, orientation);
AL_CopyVector(listener_up, orientation + 3);
qalListenerfv(AL_ORIENTATION, orientation);
qalListenerf(AL_GAIN, s_volume->value);
qalDistanceModel(AL_LINEAR_DISTANCE_CLAMPED);
// update spatialization for dynamic sounds
/* update spatialization for dynamic sounds */
ch = channels;
for( i = 0; i < s_numchannels; i++, ch++ ) {
if( !ch->sfx )
continue;
if( ch->autosound ) {
// autosounds are regenerated fresh each frame
if( ch->autoframe != s_framecount ) {
AL_StopChannel( ch );
for (i = 0; i < s_numchannels; i++, ch++)
{
if (!ch->sfx)
{
continue;
}
if (ch->autosound)
{
/* autosounds are regenerated fresh each frame */
if (ch->autoframe != s_framecount)
{
AL_StopChannel(ch);
continue;
}
} else {
}
else
{
ALenum state;
qalGetError();
qalGetSourcei( ch->srcnum, AL_SOURCE_STATE, &state );
if( qalGetError() != AL_NO_ERROR || state == AL_STOPPED ) {
AL_StopChannel( ch );
qalGetSourcei(ch->srcnum, AL_SOURCE_STATE, &state);
if ((qalGetError() != AL_NO_ERROR) || (state == AL_STOPPED))
{
AL_StopChannel(ch);
continue;
}
}
if (s_show->value) {
Com_Printf ("%3i %s\n", ch->master_vol, ch->sfx->name);
if (s_show->value)
{
Com_Printf("%3i %s\n", ch->master_vol, ch->sfx->name);
}
AL_Spatialize(ch); // respatialize channel
AL_Spatialize(ch); /* respatialize channel */
}
s_framecount++;
// add loopsounds
AL_AddLoopSounds ();
/* add loopsounds */
AL_AddLoopSounds();
// add music
/* add music */
OGG_Stream();
S_AL_StreamUpdate();
AL_IssuePlaysounds();
}
void AL_Underwater()
void
AL_Underwater()
{
int i;
if(sound_started != SS_OAL) {
if (sound_started != SS_OAL)
{
return;
}
// Apply to all sources
/* Apply to all sources */
for (i = 0; i < s_numchannels; i++)
{
qalSourcei(s_srcnums[i], AL_DIRECT_FILTER, underwaterFilter);
}
}
void AL_Overwater()
void
AL_Overwater()
{
int i;
@ -434,23 +555,25 @@ void AL_Overwater()
return;
}
// Apply to all sources
/* Apply to all sources */
for (i = 0; i < s_numchannels; i++)
{
qalSourcei(s_srcnums[i], AL_DIRECT_FILTER, 0);
}
}
static void S_AL_StreamDie( void )
static void
S_AL_StreamDie(void)
{
int numBuffers;
int numBuffers;
streamPlaying = false;
qalSourceStop(streamSource);
// Un-queue any buffers, and delete them
qalGetSourcei( streamSource, AL_BUFFERS_QUEUED, &numBuffers );
while( numBuffers-- )
/* Un-queue any buffers, and delete them */
qalGetSourcei(streamSource, AL_BUFFERS_QUEUED, &numBuffers);
while (numBuffers--)
{
ALuint buffer;
qalSourceUnqueueBuffers(streamSource, 1, &buffer);
@ -459,14 +582,16 @@ static void S_AL_StreamDie( void )
}
}
static void S_AL_StreamUpdate( void )
static void
S_AL_StreamUpdate(void)
{
int numBuffers;
ALint state;
int numBuffers;
ALint state;
// Un-queue any buffers, and delete them
qalGetSourcei( streamSource, AL_BUFFERS_PROCESSED, &numBuffers );
while( numBuffers-- )
/* Un-queue any buffers, and delete them */
qalGetSourcei(streamSource, AL_BUFFERS_PROCESSED, &numBuffers);
while (numBuffers--)
{
ALuint buffer;
qalSourceUnqueueBuffers(streamSource, 1, &buffer);
@ -474,70 +599,84 @@ static void S_AL_StreamUpdate( void )
active_buffers--;
}
// Start the streamSource playing if necessary
qalGetSourcei( streamSource, AL_BUFFERS_QUEUED, &numBuffers );
/* Start the streamSource playing if necessary */
qalGetSourcei(streamSource, AL_BUFFERS_QUEUED, &numBuffers);
qalGetSourcei(streamSource, AL_SOURCE_STATE, &state);
if(state == AL_STOPPED)
if (state == AL_STOPPED)
{
streamPlaying = false;
}
if( !streamPlaying && numBuffers )
if (!streamPlaying && numBuffers)
{
qalSourcePlay( streamSource );
qalSourcePlay(streamSource);
streamPlaying = true;
}
}
static ALuint S_AL_Format(int width, int channels)
static ALuint
S_AL_Format(int width, int channels)
{
ALuint format = AL_FORMAT_MONO16;
// Work out format
if(width == 1)
/* Work out format */
if (width == 1)
{
if(channels == 1)
if (channels == 1)
{
format = AL_FORMAT_MONO8;
else if(channels == 2)
}
else if (channels == 2)
{
format = AL_FORMAT_STEREO8;
}
}
else if(width == 2)
else if (width == 2)
{
if(channels == 1)
if (channels == 1)
{
format = AL_FORMAT_MONO16;
else if(channels == 2)
}
else if (channels == 2)
{
format = AL_FORMAT_STEREO16;
}
}
return format;
}
void AL_RawSamples( int samples, int rate, int width, int channels, byte *data, float volume )
void
AL_RawSamples(int samples, int rate, int width, int channels,
byte *data, float volume)
{
ALuint buffer;
ALuint format;
format = S_AL_Format( width, channels );
format = S_AL_Format(width, channels);
// Create a buffer, and stuff the data into it
/* Create a buffer, and stuff the data into it */
qalGenBuffers(1, &buffer);
qalBufferData(buffer, format, (ALvoid *)data, (samples * width * channels), rate);
qalBufferData(buffer, format, (ALvoid *)data,
(samples * width * channels), rate);
active_buffers++;
// set volume
qalSourcef( streamSource, AL_GAIN, volume );
/* set volume */
qalSourcef(streamSource, AL_GAIN, volume);
// Shove the data onto the streamSource
/* Shove the data onto the streamSource */
qalSourceQueueBuffers(streamSource, 1, &buffer);
// emulate behavior of S_RawSamples for s_rawend
/* emulate behavior of S_RawSamples for s_rawend */
s_rawend += samples;
}
void AL_UnqueueRawSamples()
void
AL_UnqueueRawSamples()
{
S_AL_StreamDie();
}
#endif // USE_OPENAL
#endif /* USE_OPENAL */

File diff suppressed because it is too large Load diff

View file

@ -19,8 +19,9 @@
*
* =======================================================================
*
* The sound caching. This file contains support functions for loading
* the sound samples into the memory.
* The sound caching. This file contains support functions for
* processing the soundsamples, load them into the memory and
* provide them to the SDL or OpenAL sound backend.
*
* =======================================================================
*/
@ -29,7 +30,7 @@
#include "header/local.h"
void
ResampleSfx ( sfx_t *sfx, int inrate, int inwidth, byte *data )
ResampleSfx(sfx_t *sfx, int inrate, int inwidth, byte *data)
{
int outcount;
int srcsample;
@ -37,37 +38,38 @@ ResampleSfx ( sfx_t *sfx, int inrate, int inwidth, byte *data )
int i;
int sample;
unsigned int samplefrac, fracstep;
sfxcache_t *sc;
sfxcache_t *sc;
sc = sfx->cache;
if ( !sc )
if (!sc)
{
return;
}
stepscale = (float) inrate / dma.speed; /* this is usually 0.5, 1, or 2 */
stepscale = (float)inrate / dma.speed; /* this is usually 0.5, 1, or 2 */
outcount = (int) ( sc->length / stepscale );
outcount = (int)(sc->length / stepscale);
if ( outcount == 0 )
if (outcount == 0)
{
Com_Printf( "ResampleSfx: Invalid sound file '%s' (zero length)\n", sfx->name );
Z_Free( sfx->cache );
Com_Printf("ResampleSfx: Invalid sound file '%s' (zero length)\n",
sfx->name);
Z_Free(sfx->cache);
sfx->cache = NULL;
return;
}
sc->length = outcount;
if ( sc->loopstart != -1 )
if (sc->loopstart != -1)
{
sc->loopstart = (int) ( sc->loopstart / stepscale );
sc->loopstart = (int)(sc->loopstart / stepscale);
}
sc->speed = dma.speed;
if ( s_loadas8bit->value )
if (s_loadas8bit->value)
{
sc->width = 1;
}
@ -81,62 +83,62 @@ ResampleSfx ( sfx_t *sfx, int inrate, int inwidth, byte *data )
/* resample / decimate to the current source rate */
samplefrac = 0;
fracstep = (int) ( stepscale * 256 );
fracstep = (int)(stepscale * 256);
for ( i = 0; i < outcount; i++ )
for (i = 0; i < outcount; i++)
{
srcsample = samplefrac >> 8;
samplefrac += fracstep;
if ( inwidth == 2 )
if (inwidth == 2)
{
sample = LittleShort( ( (short *) data ) [ srcsample ] );
sample = LittleShort(((short *)data)[srcsample]);
}
else
{
sample = (int) ( (unsigned char) ( data [ srcsample ] ) - 128 ) << 8;
sample = (int)((unsigned char)(data[srcsample]) - 128) << 8;
}
if ( sc->width == 2 )
if (sc->width == 2)
{
( (short *) sc->data ) [ i ] = sample;
((short *)sc->data)[i] = sample;
}
else
{
( (signed char *) sc->data ) [ i ] = sample >> 8;
((signed char *)sc->data)[i] = sample >> 8;
}
}
}
sfxcache_t *
S_LoadSound ( sfx_t *s )
S_LoadSound(sfx_t *s)
{
char namebuffer [ MAX_QPATH ];
byte *data;
char namebuffer[MAX_QPATH];
byte *data;
wavinfo_t info;
int len;
float stepscale;
sfxcache_t *sc;
sfxcache_t *sc;
int size;
char *name;
char *name;
if ( s->name [ 0 ] == '*' )
if (s->name[0] == '*')
{
return ( NULL );
return NULL;
}
/* see if still in memory */
sc = s->cache;
if ( sc )
if (sc)
{
return ( sc );
return sc;
}
/* load it in */
if ( s->truename )
if (s->truename)
{
name = s->truename;
}
@ -146,48 +148,52 @@ S_LoadSound ( sfx_t *s )
name = s->name;
}
if ( name [ 0 ] == '#' )
if (name[0] == '#')
{
strcpy( namebuffer, &name [ 1 ] );
} else {
Com_sprintf( namebuffer, sizeof ( namebuffer ), "sound/%s", name );
strcpy(namebuffer, &name[1]);
}
else
{
Com_sprintf(namebuffer, sizeof(namebuffer), "sound/%s", name);
}
size = FS_LoadFile( namebuffer, (void **) &data );
size = FS_LoadFile(namebuffer, (void **)&data);
if ( !data )
if (!data)
{
s->cache = NULL;
Com_DPrintf( "Couldn't load %s\n", namebuffer );
return ( NULL );
Com_DPrintf("Couldn't load %s\n", namebuffer);
return NULL;
}
info = GetWavinfo( s->name, data, size );
info = GetWavinfo(s->name, data, size);
if ( info.channels != 1 )
if (info.channels != 1)
{
Com_Printf( "%s is a stereo sample\n", s->name );
FS_FreeFile( data );
return ( NULL );
Com_Printf("%s is a stereo sample\n", s->name);
FS_FreeFile(data);
return NULL;
}
if (sound_started != SS_OAL) {
stepscale = (float) info.rate / dma.speed;
len = (int) ( info.samples / stepscale );
if ( ( info.samples == 0 ) || ( len == 0 ) )
if (sound_started != SS_OAL)
{
stepscale = (float)info.rate / dma.speed;
len = (int)(info.samples / stepscale);
if ((info.samples == 0) || (len == 0))
{
Com_Printf( "WARNING: Zero length sound encountered: %s\n", s->name );
FS_FreeFile( data );
return ( NULL );
Com_Printf("WARNING: Zero length sound encountered: %s\n", s->name);
FS_FreeFile(data);
return NULL;
}
len = len * info.width * info.channels;
sc = s->cache = Z_Malloc( len + sizeof ( sfxcache_t ) );
sc = s->cache = Z_Malloc(len + sizeof(sfxcache_t));
if ( !sc )
if (!sc)
{
FS_FreeFile( data );
return ( NULL );
FS_FreeFile(data);
return NULL;
}
sc->length = info.samples;
@ -199,12 +205,17 @@ S_LoadSound ( sfx_t *s )
#if USE_OPENAL
if (sound_started == SS_OAL)
{
sc = AL_UploadSfx(s, &info, data + info.dataofs);
}
else
#endif
ResampleSfx( s, sc->speed, sc->width, data + info.dataofs );
{
ResampleSfx(s, sc->speed, sc->width, data + info.dataofs);
}
FS_FreeFile( data );
FS_FreeFile(data);
return ( sc );
return sc;
}

View file

@ -31,148 +31,212 @@
#define PAINTBUFFER_SIZE 2048
portable_samplepair_t paintbuffer [ PAINTBUFFER_SIZE ];
int snd_scaletable [ 32 ] [ 256 ];
int *snd_p, snd_linear_count, snd_vol;
short *snd_out;
portable_samplepair_t paintbuffer[PAINTBUFFER_SIZE];
int snd_scaletable[32][256];
int *snd_p, snd_linear_count, snd_vol;
short *snd_out;
void
S_TransferPaintBuffer ( int endtime )
S_TransferPaintBuffer(int endtime)
{
int i;
int lpos;
int ls_paintedtime;
int out_idx;
int count;
int out_mask;
int *p;
int *p;
int step;
int val;
unsigned long *pbuf;
pbuf = (unsigned long *) dma.buffer;
pbuf = (unsigned long *)dma.buffer;
if ( s_testsound->value )
if (s_testsound->value)
{
int i;
int count;
/* write a fixed sine wave */
count = ( endtime - paintedtime );
count = (endtime - paintedtime);
for ( i = 0; i < count; i++ )
for (i = 0; i < count; i++)
{
paintbuffer [ i ].left = paintbuffer [ i ].right = (int) ( (float) sin( ( paintedtime + i ) * 0.1f ) * 20000 * 256 );
paintbuffer[i].left = paintbuffer[i].right =
(int)((float)sin((paintedtime + i) * 0.1f) * 20000 * 256);
}
}
p = (int *) paintbuffer;
count = ( endtime - paintedtime ) * dma.channels;
out_mask = dma.samples - 1;
out_idx = paintedtime * dma.channels & out_mask;
step = 3 - dma.channels;
if ( dma.samplebits == 16 )
if ((dma.samplebits == 16) && (dma.channels == 2))
{
short *out = (short *) pbuf;
snd_p = (int *)paintbuffer;
ls_paintedtime = paintedtime;
while ( count-- )
while (ls_paintedtime < endtime)
{
val = *p >> 8;
p += step;
lpos = ls_paintedtime & ((dma.samples >> 1) - 1);
if ( val > 0x7fff )
snd_out = (short *)pbuf + (lpos << 1);
snd_linear_count = (dma.samples >> 1) - lpos;
if (ls_paintedtime + snd_linear_count > endtime)
{
val = 0x7fff;
snd_linear_count = endtime - ls_paintedtime;
}
else if ( val < (short) 0x8000 )
snd_linear_count <<= 1;
for (i = 0; i < snd_linear_count; i += 2)
{
val = (short) 0x8000;
val = snd_p[i] >> 8;
if (val > 0x7fff)
{
snd_out[i] = 0x7fff;
}
else if (val < -32768)
{
snd_out[i] = -32768;
}
else
{
snd_out[i] = val;
}
val = snd_p[i + 1] >> 8;
if (val > 0x7fff)
{
snd_out[i + 1] = 0x7fff;
}
else if (val < -32768)
{
snd_out[i + 1] = -32768;
}
else
{
snd_out[i + 1] = val;
}
}
out [ out_idx ] = val;
out_idx = ( out_idx + 1 ) & out_mask;
snd_p += snd_linear_count;
ls_paintedtime += (snd_linear_count >> 1);
}
}
else if ( dma.samplebits == 8 )
else
{
unsigned char *out = (unsigned char *) pbuf;
p = (int *)paintbuffer;
count = (endtime - paintedtime) * dma.channels;
out_mask = dma.samples - 1;
out_idx = paintedtime * dma.channels & out_mask;
step = 3 - dma.channels;
while ( count-- )
if (dma.samplebits == 16)
{
val = *p >> 8;
p += step;
short *out = (short *)pbuf;
if ( val > 0x7fff )
while (count--)
{
val = 0x7fff;
}
val = *p >> 8;
p += step;
else if ( val < (short) 0x8000 )
if (val > 0x7fff)
{
val = 0x7fff;
}
else if (val < -32768)
{
val = -32768;
}
out[out_idx] = val;
out_idx = (out_idx + 1) & out_mask;
}
}
else if (dma.samplebits == 8)
{
unsigned char *out = (unsigned char *)pbuf;
while (count--)
{
val = (short) 0x8000;
}
val = *p >> 8;
p += step;
out [ out_idx ] = ( val >> 8 ) + 128;
out_idx = ( out_idx + 1 ) & out_mask;
if (val > 0x7fff)
{
val = 0x7fff;
}
else if (val < -32768)
{
val = -32768;
}
out[out_idx] = (val >> 8) + 128;
out_idx = (out_idx + 1) & out_mask;
}
}
}
}
void
S_PaintChannelFrom8 ( channel_t *ch, sfxcache_t *sc, int count, int offset )
S_PaintChannelFrom8(channel_t *ch, sfxcache_t *sc, int count, int offset)
{
int data;
int *lscale, *rscale;
int *lscale, *rscale;
unsigned char *sfx;
int i;
portable_samplepair_t *samp;
portable_samplepair_t *samp;
if ( ch->leftvol > 255 )
if (ch->leftvol > 255)
{
ch->leftvol = 255;
}
if ( ch->rightvol > 255 )
if (ch->rightvol > 255)
{
ch->rightvol = 255;
}
lscale = snd_scaletable [ ch->leftvol >> 3 ];
rscale = snd_scaletable [ ch->rightvol >> 3 ];
lscale = snd_scaletable[ch->leftvol >> 3];
rscale = snd_scaletable[ch->rightvol >> 3];
sfx = sc->data + ch->pos;
samp = &paintbuffer [ offset ];
samp = &paintbuffer[offset];
for ( i = 0; i < count; i++, samp++ )
for (i = 0; i < count; i++, samp++)
{
data = sfx [ i ];
samp->left += lscale [ data ];
samp->right += rscale [ data ];
data = sfx[i];
samp->left += lscale[data];
samp->right += rscale[data];
}
ch->pos += count;
}
void
S_PaintChannelFrom16 ( channel_t *ch, sfxcache_t *sc, int count, int offset )
S_PaintChannelFrom16(channel_t *ch, sfxcache_t *sc, int count, int offset)
{
int data;
int left, right;
int leftvol, rightvol;
signed short *sfx;
int i;
portable_samplepair_t *samp;
portable_samplepair_t *samp;
leftvol = ch->leftvol * snd_vol;
rightvol = ch->rightvol * snd_vol;
sfx = (signed short *) sc->data + ch->pos;
sfx = (signed short *)sc->data + ch->pos;
samp = &paintbuffer [ offset ];
samp = &paintbuffer[offset];
for ( i = 0; i < count; i++, samp++ )
for (i = 0; i < count; i++, samp++)
{
data = sfx [ i ];
left = ( data * leftvol ) >> 8;
right = ( data * rightvol ) >> 8;
data = sfx[i];
left = (data * leftvol) >> 8;
right = (data * rightvol) >> 8;
samp->left += left;
samp->right += right;
}
@ -181,23 +245,23 @@ S_PaintChannelFrom16 ( channel_t *ch, sfxcache_t *sc, int count, int offset )
}
void
S_PaintChannels ( int endtime )
S_PaintChannels(int endtime)
{
int i;
int end;
channel_t *ch;
sfxcache_t *sc;
sfxcache_t *sc;
int ltime, count;
playsound_t *ps;
snd_vol = (int) ( s_volume->value * 256 );
snd_vol = (int)(s_volume->value * 256);
while ( paintedtime < endtime )
while (paintedtime < endtime)
{
/* if paintbuffer is smaller than DMA buffer */
end = endtime;
if ( endtime - paintedtime > PAINTBUFFER_SIZE )
if (endtime - paintedtime > PAINTBUFFER_SIZE)
{
end = paintedtime + PAINTBUFFER_SIZE;
}
@ -207,23 +271,23 @@ S_PaintChannels ( int endtime )
{
ps = s_pendingplays.next;
if ( ps == NULL )
if (ps == NULL)
{
break;
}
if ( ps == &s_pendingplays )
if (ps == &s_pendingplays)
{
break; /* no more pending sounds */
break; /* no more pending sounds */
}
if ( ps->begin <= paintedtime )
if (ps->begin <= paintedtime)
{
S_IssuePlaysound( ps );
S_IssuePlaysound(ps);
continue;
}
if ( ps->begin < end )
if (ps->begin < end)
{
end = ps->begin; /* stop here */
}
@ -232,9 +296,10 @@ S_PaintChannels ( int endtime )
}
/* clear the paint buffer */
if ( s_rawend < paintedtime )
if (s_rawend < paintedtime)
{
memset( paintbuffer, 0, ( end - paintedtime ) * sizeof ( portable_samplepair_t ) );
memset(paintbuffer, 0,
(end - paintedtime) * sizeof(portable_samplepair_t));
}
else
{
@ -242,31 +307,31 @@ S_PaintChannels ( int endtime )
int s;
int stop;
stop = ( end < s_rawend ) ? end : s_rawend;
stop = (end < s_rawend) ? end : s_rawend;
for ( i = paintedtime; i < stop; i++ )
for (i = paintedtime; i < stop; i++)
{
s = i & ( MAX_RAW_SAMPLES - 1 );
paintbuffer [ i - paintedtime ] = s_rawsamples [ s ];
s = i & (MAX_RAW_SAMPLES - 1);
paintbuffer[i - paintedtime] = s_rawsamples[s];
}
for ( ; i < end; i++ )
for ( ; i < end; i++)
{
// TODO: this could be done with memset
paintbuffer [ i - paintedtime ].left = paintbuffer [ i - paintedtime ].right = 0;
memset(&paintbuffer[i - paintedtime], 0,
sizeof(paintbuffer[i - paintedtime]));
}
}
/* paint in the channels. */
ch = channels;
for ( i = 0; i < s_numchannels; i++, ch++ )
for (i = 0; i < s_numchannels; i++, ch++)
{
ltime = paintedtime;
while ( ltime < end )
while (ltime < end)
{
if ( !ch->sfx || ( !ch->leftvol && !ch->rightvol ) )
if (!ch->sfx || (!ch->leftvol && !ch->rightvol))
{
break;
}
@ -275,43 +340,43 @@ S_PaintChannels ( int endtime )
count = end - ltime;
/* might be stopped by running out of data */
if ( ch->end - ltime < count )
if (ch->end - ltime < count)
{
count = ch->end - ltime;
}
sc = S_LoadSound( ch->sfx );
sc = S_LoadSound(ch->sfx);
if ( !sc )
if (!sc)
{
break;
}
if ( ( count > 0 ) && ch->sfx )
if ((count > 0) && ch->sfx)
{
if ( sc->width == 1 )
if (sc->width == 1)
{
S_PaintChannelFrom8( ch, sc, count, ltime - paintedtime );
S_PaintChannelFrom8(ch, sc, count, ltime - paintedtime);
}
else
{
S_PaintChannelFrom16( ch, sc, count, ltime - paintedtime );
S_PaintChannelFrom16(ch, sc, count, ltime - paintedtime);
}
ltime += count;
}
/* if at end of loop, restart */
if ( ltime >= ch->end )
if (ltime >= ch->end)
{
if ( ch->autosound )
if (ch->autosound)
{
/* autolooping sounds always go back to start */
ch->pos = 0;
ch->end = ltime + sc->length;
}
else if ( sc->loopstart >= 0 )
else if (sc->loopstart >= 0)
{
ch->pos = sc->loopstart;
ch->end = ltime + sc->length - ch->pos;
@ -326,36 +391,37 @@ S_PaintChannels ( int endtime )
}
/* transfer out according to DMA format */
S_TransferPaintBuffer( end );
S_TransferPaintBuffer(end);
paintedtime = end;
}
}
/* This is called from snd_dma.c */
void
S_InitScaletable ( void )
S_InitScaletable(void)
{
int i, j;
int scale;
if ( s_volume->value > 2.0f )
if (s_volume->value > 2.0f)
{
Cvar_Set( "s_volume", "2" );
Cvar_Set("s_volume", "2");
}
else if ( s_volume->value < 0 )
else if (s_volume->value < 0)
{
Cvar_Set( "s_volume", "0" );
Cvar_Set("s_volume", "0");
}
s_volume->modified = false;
for ( i = 0; i < 32; i++ )
for (i = 0; i < 32; i++)
{
scale = (int) ( i * 8 * 256 * s_volume->value );
scale = (int)(i * 8 * 256 * s_volume->value);
for ( j = 0; j < 256; j++ )
for (j = 0; j < 256; j++)
{
snd_scaletable [ i ] [ j ] = ( ( j < 128 ) ? j : j - 0xff ) * scale;
snd_scaletable[i][j] = ((j < 128) ? j : j - 0xff) * scale;
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -19,7 +19,7 @@
*
* =======================================================================
*
* This file implements a subset of the WAVE audio file format
* This file implements a subset of the WAVE audio file format.
*
* =======================================================================
*/
@ -27,48 +27,45 @@
#include "../header/client.h"
#include "header/local.h"
// FIXME: this code is really fucked up, those global variables make me sick.
// someone should clean this up one day..
byte *data_p;
byte *iff_end;
byte *last_chunk;
byte *iff_data;
int iff_chunk_len;
byte *data_p;
byte *iff_end;
byte *last_chunk;
byte *iff_data;
int iff_chunk_len;
short
GetLittleShort ( void )
GetLittleShort(void)
{
short val = 0;
val = *data_p;
val = val + ( *( data_p + 1 ) << 8 );
val = val + (*(data_p + 1) << 8);
data_p += 2;
return ( val );
return val;
}
int
GetLittleLong ( void )
GetLittleLong(void)
{
int val = 0;
val = *data_p;
val = val + ( *( data_p + 1 ) << 8 );
val = val + ( *( data_p + 2 ) << 16 );
val = val + ( *( data_p + 3 ) << 24 );
val = val + (*(data_p + 1) << 8);
val = val + (*(data_p + 2) << 16);
val = val + (*(data_p + 3) << 24);
data_p += 4;
return ( val );
return val;
}
void
FindNextChunk ( char *name )
FindNextChunk(char *name)
{
while ( 1 )
while (1)
{
data_p = last_chunk;
data_p += 4;
if ( data_p >= iff_end )
if (data_p >= iff_end)
{
data_p = NULL;
return;
@ -76,16 +73,16 @@ FindNextChunk ( char *name )
iff_chunk_len = GetLittleLong();
if ( iff_chunk_len < 0 )
if (iff_chunk_len < 0)
{
data_p = NULL;
return;
}
data_p -= 8;
last_chunk = data_p + 8 + ( ( iff_chunk_len + 1 ) & ~1 );
last_chunk = data_p + 8 + ((iff_chunk_len + 1) & ~1);
if ( !strncmp( (const char *) data_p, name, 4 ) )
if (!strncmp((const char *)data_p, name, 4))
{
return;
}
@ -93,57 +90,57 @@ FindNextChunk ( char *name )
}
void
FindChunk ( char *name )
FindChunk(char *name)
{
last_chunk = iff_data;
FindNextChunk( name );
FindNextChunk(name);
}
wavinfo_t
GetWavinfo ( char *name, byte *wav, int wavlength )
GetWavinfo(char *name, byte *wav, int wavlength)
{
wavinfo_t info;
int i;
int format;
int samples;
memset( &info, 0, sizeof ( info ) );
memset(&info, 0, sizeof(info));
if ( !wav )
if (!wav)
{
return ( info );
return info;
}
iff_data = wav;
iff_end = wav + wavlength;
/* find "RIFF" chunk */
FindChunk( "RIFF" );
FindChunk("RIFF");
if ( !( data_p && !strncmp( (const char *) data_p + 8, "WAVE", 4 ) ) )
if (!(data_p && !strncmp((const char *)data_p + 8, "WAVE", 4)))
{
Com_Printf( "Missing RIFF/WAVE chunks\n" );
return ( info );
Com_Printf("Missing RIFF/WAVE chunks\n");
return info;
}
/* get "fmt " chunk */
iff_data = data_p + 12;
FindChunk( "fmt " );
FindChunk("fmt ");
if ( !data_p )
if (!data_p)
{
Com_Printf( "Missing fmt chunk\n" );
return ( info );
Com_Printf("Missing fmt chunk\n");
return info;
}
data_p += 8;
format = GetLittleShort();
if ( format != 1 )
if (format != 1)
{
Com_Printf( "Microsoft PCM format only\n" );
return ( info );
Com_Printf("Microsoft PCM format only\n");
return info;
}
info.channels = GetLittleShort();
@ -152,21 +149,24 @@ GetWavinfo ( char *name, byte *wav, int wavlength )
info.width = GetLittleShort() / 8;
/* get cue chunk */
FindChunk( "cue " );
FindChunk("cue ");
if ( data_p )
if (data_p)
{
data_p += 32;
info.loopstart = GetLittleLong();
/* if the next chunk is a LIST chunk, look for a cue length marker */
FindNextChunk( "LIST" );
/* if the next chunk is a LIST chunk,
look for a cue length marker */
FindNextChunk("LIST");
if ( data_p )
if (data_p)
{
if ( ( ( data_p - wav ) + 32 <= wavlength ) && !strncmp( (const char *) data_p + 28, "mark", 4 ) )
if (((data_p - wav) + 32 <= wavlength) &&
!strncmp((const char *)data_p + 28, "mark", 4))
{
/* this is not a proper parse, but it works with cooledit... */
/* this is not a proper parse,
but it works with cooledit... */
data_p += 24;
i = GetLittleLong(); /* samples in loop */
info.samples = info.loopstart + i;
@ -179,22 +179,22 @@ GetWavinfo ( char *name, byte *wav, int wavlength )
}
/* find data chunk */
FindChunk( "data" );
FindChunk("data");
if ( !data_p )
if (!data_p)
{
Com_Printf( "Missing data chunk\n" );
return ( info );
Com_Printf("Missing data chunk\n");
return info;
}
data_p += 4;
samples = GetLittleLong() / info.width;
if ( info.samples )
if (info.samples)
{
if ( samples < info.samples )
if (samples < info.samples)
{
Com_Error( ERR_DROP, "Sound %s has a bad loop length", name );
Com_Error(ERR_DROP, "Sound %s has a bad loop length", name);
}
}
else
@ -202,7 +202,8 @@ GetWavinfo ( char *name, byte *wav, int wavlength )
info.samples = samples;
}
info.dataofs = (int) ( data_p - wav );
info.dataofs = (int)(data_p - wav);
return ( info );
return info;
}

View file

@ -26,7 +26,7 @@
*/
#include "header/common.h"
#include "../unix/header/glob.h"
#include "../common/header/glob.h"
#ifdef ZIP
#include "unzip/unzip.h"
@ -232,7 +232,7 @@ FS_CreatePath(char *path)
old = cur;
cur = strchr(old + 1, '/');
}
}
}
void
@ -257,14 +257,6 @@ FS_Gamedir(void)
return (fs_gamedir);
}
void
FS_DeletePath(char *path)
{
FS_DPrintf("FS_DeletePath(%s)\n", path);
Sys_Rmdir(path);
}
/*
* Returns a FILE * for a fileHandle_t.
*/
@ -429,7 +421,7 @@ FS_FOpenFileRead(fsHandle_t * handle)
{
/* PAK */
file_from_pak = 1;
handle->file = fopen(pack->name, "r");
handle->file = fopen(pack->name, "rb");
if (handle->file)
{
@ -469,12 +461,12 @@ FS_FOpenFileRead(fsHandle_t * handle)
/* Search in a directory tree. */
Com_sprintf(path, sizeof(path), "%s/%s", search->path, handle->name);
handle->file = fopen(path, "r");
handle->file = fopen(path, "rb");
if (!handle->file)
{
strlwr(path);
handle->file = fopen(path, "r");
handle->file = fopen(path, "rb");
}
if (!handle->file)
@ -1038,7 +1030,7 @@ FS_LoadPAK(const char *packPath)
dpackheader_t header; /* PAK file header. */
dpackfile_t info[MAX_FILES_IN_PACK]; /* PAK info. */
handle = fopen(packPath, "r");
handle = fopen(packPath, "rb");
if (handle == NULL)
return (NULL);
@ -1261,23 +1253,27 @@ FS_AddGameDirectory(const char *dir)
void
FS_AddHomeAsGameDirectory(char *dir)
{
char *home;
char gdir[MAX_OSPATH];
char *homedir=getenv("HOME");
size_t len;
if(homedir)
home = Sys_GetHomeDir();
if (home == NULL)
{
int len = snprintf(gdir,sizeof(gdir),"%s/.yq2/%s/", homedir, dir);
FS_CreatePath(gdir);
if ((len > 0) && (len < sizeof(gdir)) && (gdir[len-1] == '/'))
gdir[len-1] = 0;
strncpy(fs_gamedir,gdir,sizeof(fs_gamedir)-1);
fs_gamedir[sizeof(fs_gamedir)-1] = 0;
FS_AddGameDirectory (gdir);
return;
}
len = snprintf(gdir, sizeof(gdir), "%s%s/", home, dir);
FS_CreatePath(gdir);
if ((len > 0) && (len < sizeof(gdir)) && (gdir[len-1] == '/'))
gdir[len-1] = 0;
strncpy(fs_gamedir,gdir,sizeof(fs_gamedir)-1);
fs_gamedir[sizeof(fs_gamedir)-1] = 0;
FS_AddGameDirectory (gdir);
}
#ifdef SYSTEMWIDE

View file

@ -39,6 +39,8 @@
#define BUILDSTRING "Linux"
#elif defined __FreeBSD__
#define BUILDSTRING "FreeBSD"
#elif defined _WIN32
#define BUILDSTRING "Windows"
#else
#define BUILDSTRING "Unknown"
#endif
@ -53,6 +55,12 @@
#define CPUSTRING "Unknown"
#endif
#ifdef _WIN32
#define CFGDIR "YamagiQ2"
#else
#define CFGDIR ".yq2"
#endif
/* ================================================================== */
typedef struct sizebuf_s
@ -481,6 +489,7 @@ typedef struct
unsigned short port;
} netadr_t;
void NET_Init (void);
void NET_Shutdown (void);
void NET_Config (qboolean multiplayer);
@ -648,7 +657,6 @@ qboolean FS_FileExists(char *path);
void FS_CopyFile(const char *srcPath, const char *dstPath);
void FS_RenameFile(const char *oldPath, const char *newPath);
void FS_DeleteFile(const char *path);
void FS_DeletePath(char *path);
int FS_GetFileList(const char *path, const char *extension, char *buffer, int size, fsSearchType_t searchType);
char **FS_ListPak(char *find, int *num); /* Knighmare- pak list function */
char **FS_ListFiles(char *findname, int *numfiles, unsigned musthave, unsigned canthave);
@ -730,6 +738,7 @@ void SCR_DebugGraph (float value, int color);
/* NON-PORTABLE SYSTEM SERVICES */
void Sys_Init (void);
void Sys_UnloadGame (void);
void *Sys_GetGameAPI (void *parms);
@ -738,8 +747,7 @@ void Sys_ConsoleOutput (char *string);
void Sys_SendKeyEvents (void);
void Sys_Error (char *error, ...);
void Sys_Quit (void);
char *Sys_GetClipboardData( void );
void Sys_CopyProtect (void);
char *Sys_GetHomeDir(void);
/* CLIENT / SERVER SYSTEMS */

View file

@ -53,7 +53,12 @@ typedef enum {false, true} qboolean;
#define MAX_TOKEN_CHARS 128 /* max length of an individual token */
#define MAX_QPATH 64 /* max length of a quake game pathname */
#ifdef _WIN32
#define MAX_OSPATH 256 /* max length of a filesystem pathname */
#else
#define MAX_OSPATH 128 /* max length of a filesystem pathname */
#endif
/* */
/* per-level limits */
@ -249,7 +254,6 @@ extern int curtime; /* time returned by last Sys_Milliseconds */
int Sys_Milliseconds(void);
void Sys_Mkdir(char *path);
void Sys_Rmdir(char *path);
char *strlwr(char *s);
/* large block stack allocation routines */

View file

@ -236,6 +236,8 @@ void Qcommon_Init (int argc, char **argv)
if (dedicated->value)
Cmd_AddCommand ("quit", Com_Quit);
Sys_Init();
NET_Init();
Netchan_Init ();
SV_Init ();
#ifndef DEDICATED_ONLY

View file

@ -88,6 +88,8 @@
#define OS "FreeBSD"
#elif defined(__linux__)
#define OS "Linux"
#elif defined(_WIN32)
#define OS "Windows"
#else
#define OS "Unknown"
#endif

View file

@ -39,6 +39,20 @@
#define GL_COLOR_INDEX8_EXT GL_COLOR_INDEX
#endif
#ifndef GL_EXT_texture_filter_anisotropic
#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF
#endif
#ifndef GL_ARB_multitexture
#define GL_TEXTURE0_ARB 0x84C0
#define GL_TEXTURE1_ARB 0x84C1
#endif
#ifndef GL_VERSION_1_3
#define GL_TEXTURE1 0x84C1
#endif
#define TEXNUM_LIGHTMAPS 1024
#define TEXNUM_SCRAPS 1152
#define TEXNUM_IMAGES 1153

View file

@ -27,6 +27,10 @@
#ifndef REF_QGL_H
#define REF_QGL_H
#ifdef _WIN32
#include <windows.h>
#endif
#include <GL/gl.h>
#ifndef APIENTRY
@ -406,10 +410,45 @@ extern void ( APIENTRY *qglSelectTextureSGIS )( GLenum );
extern void ( APIENTRY *qglActiveTextureARB )( GLenum );
extern void ( APIENTRY *qglClientActiveTextureARB )( GLenum );
#ifdef _WIN32
extern int ( WINAPI * qwglChoosePixelFormat )(HDC, CONST PIXELFORMATDESCRIPTOR *);
extern int ( WINAPI * qwglDescribePixelFormat) (HDC, int, UINT, LPPIXELFORMATDESCRIPTOR);
extern int ( WINAPI * qwglGetPixelFormat)(HDC);
extern BOOL ( WINAPI * qwglSetPixelFormat)(HDC, int, CONST PIXELFORMATDESCRIPTOR *);
extern BOOL ( WINAPI * qwglSwapBuffers)(HDC);
extern BOOL ( WINAPI * qwglCopyContext)(HGLRC, HGLRC, UINT);
extern HGLRC ( WINAPI * qwglCreateContext)(HDC);
extern HGLRC ( WINAPI * qwglCreateLayerContext)(HDC, int);
extern BOOL ( WINAPI * qwglDeleteContext)(HGLRC);
extern HGLRC ( WINAPI * qwglGetCurrentContext)(VOID);
extern HDC ( WINAPI * qwglGetCurrentDC)(VOID);
extern PROC ( WINAPI * qwglGetProcAddress)(LPCSTR);
extern BOOL ( WINAPI * qwglMakeCurrent)(HDC, HGLRC);
extern BOOL ( WINAPI * qwglShareLists)(HGLRC, HGLRC);
extern BOOL ( WINAPI * qwglUseFontBitmaps)(HDC, DWORD, DWORD, DWORD);
extern BOOL ( WINAPI * qwglUseFontOutlines)(HDC, DWORD, DWORD, DWORD, FLOAT, FLOAT, int, LPGLYPHMETRICSFLOAT);
extern BOOL ( WINAPI * qwglDescribeLayerPlane)(HDC, int, int, UINT, LPLAYERPLANEDESCRIPTOR);
extern int ( WINAPI * qwglSetLayerPaletteEntries)(HDC, int, int, int, CONST COLORREF *);
extern int ( WINAPI * qwglGetLayerPaletteEntries)(HDC, int, int, int, COLORREF *);
extern BOOL ( WINAPI * qwglRealizeLayerPalette)(HDC, int, BOOL);
extern BOOL ( WINAPI * qwglSwapLayerBuffers)(HDC, UINT);
extern BOOL ( WINAPI * qwglSwapIntervalEXT)( int interval );
extern BOOL ( WINAPI * qwglGetDeviceGammaRampEXT ) ( unsigned char *pRed, unsigned char *pGreen, unsigned char *pBlue );
extern BOOL ( WINAPI * qwglSetDeviceGammaRampEXT ) ( const unsigned char *pRed, const unsigned char *pGreen, const unsigned char *pBlue );
#else
/* local function in dll */
extern void *qwglGetProcAddress ( char *symbol );
void Fake_glColorTableEXT ( GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table );
#endif
extern int QGL_TEXTURE0, QGL_TEXTURE1;

View file

@ -94,7 +94,9 @@ gltmode_t gl_solid_modes[] = {
{ "GL_RGB5", GL_RGB5 },
{ "GL_RGB4", GL_RGB4 },
{ "GL_R3_G3_B2", GL_R3_G3_B2 },
#ifdef GL_RGB2_EXT
{ "GL_RGB2", GL_RGB2_EXT },
#endif
};
#define NUM_GL_SOLID_MODES ( sizeof ( gl_solid_modes ) / sizeof ( gltmode_t ) )
@ -1026,10 +1028,13 @@ R_FindImage ( char *name, imagetype_t type )
int i, len;
byte *pic, *palette;
int width, height;
int realwidth = 0, realheight = 0;
char *ptr;
char namewe[256];
#ifdef RETEXTURE
int realwidth = 0, realheight = 0;
#endif
if ( !name )
{
return ( NULL );
@ -1171,6 +1176,7 @@ R_FindImage ( char *name, imagetype_t type )
}
}
}
#ifdef RETEXTURE
else if ( !strcmp( name + len - 4, ".tga" ) )
{
LoadTGA( name, &pic, &width, &height );
@ -1181,6 +1187,7 @@ R_FindImage ( char *name, imagetype_t type )
LoadJPG( name, &pic, &width, &height );
image = R_LoadPic( name, pic, width, realwidth, height, realheight, type, 32 );
}
#endif
else
{
return ( NULL );

View file

@ -985,7 +985,13 @@ R_Register ( void )
gl_polyblend = ri.Cvar_Get( "gl_polyblend", "1", 0 );
gl_flashblend = ri.Cvar_Get( "gl_flashblend", "0", 0 );
gl_playermip = ri.Cvar_Get( "gl_playermip", "0", 0 );
#ifdef _WIN32
gl_driver = ri.Cvar_Get( "gl_driver", "opengl32.dll", CVAR_ARCHIVE );
#else
gl_driver = ri.Cvar_Get( "gl_driver", "libGL.so.1", CVAR_ARCHIVE );
#endif
gl_texturemode = ri.Cvar_Get( "gl_texturemode", "GL_LINEAR_MIPMAP_NEAREST", CVAR_ARCHIVE );
gl_texturealphamode = ri.Cvar_Get( "gl_texturealphamode", "default", CVAR_ARCHIVE );
gl_texturesolidmode = ri.Cvar_Get( "gl_texturesolidmode", "default", CVAR_ARCHIVE );

View file

@ -28,7 +28,13 @@
#ifdef CDA
#include <stdio.h>
#ifdef _WIN32
#include "SDL/SDL.h"
#else
#include "SDL.h"
#endif
#include "../client/header/client.h"
static qboolean cdValid = false;

View file

@ -24,11 +24,17 @@
*
* =======================================================================
*/
#include <SDL.h>
#include "../refresh/header/local.h"
#include "../client/header/keyboard.h"
#ifdef _WIN32
#include <SDL/SDL.h>
#include "../windows/header/winquake.h"
#else
#include <SDL.h>
#include "../unix/header/unix.h"
#endif
#define MOUSE_MAX 3000
#define MOUSE_MIN 40

View file

@ -25,20 +25,27 @@
* =======================================================================
*/
#include <SDL.h>
#include "../refresh/header/local.h"
#include <GL/gl.h>
#include "../refresh/header/local.h"
#ifdef _WIN32
#include <SDL/SDL.h>
#include "../windows/header/glwindow.h"
#else
#include <SDL.h>
#include "../unix/header/glwindow.h"
#endif
/* The window icon */
#include "icon/q2icon.xbm"
/* X.org stuff */
#ifdef X11GAMMA
#include <X11/Xos.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/extensions/xf86vmode.h>
#endif
SDL_Surface *surface;
glwstate_t glw_state;

View file

@ -30,15 +30,21 @@
* =======================================================================
*/
#ifdef _WIN32
#include <SDL/SDL.h>
#else
#include <SDL.h>
#endif
#include "../client/header/client.h"
#include "../client/sound/header/local.h"
/* Global stuff */
int snd_inited = 0;
int snd_inited = 0;
static int dmapos = 0;
static int dmasize = 0;
static dma_t *dmabackend;
cvar_t *s_sdldriver;
/* The callback */
static void
@ -96,6 +102,7 @@ qboolean
SNDDMA_Init(void)
{
char drivername[128];
char reqdriver[128];
SDL_AudioSpec desired;
SDL_AudioSpec obtained;
int tmp, val;
@ -111,6 +118,17 @@ SNDDMA_Init(void)
int sndfreq = (Cvar_Get("s_khz", "44", CVAR_ARCHIVE))->value;
int sndchans = (Cvar_Get("sndchannels", "2", CVAR_ARCHIVE))->value;
#ifdef _WIN32
s_sdldriver = (Cvar_Get("s_sdldriver", "dsound", CVAR_ARCHIVE));
#elif __linux__
s_sdldriver = (Cvar_Get("s_sdldriver", "alsa", CVAR_ARCHIVE));
#else
s_sdldriver = (Cvar_Get("s_sdldriver", "dsp", CVAR_ARCHIVE));
#endif
snprintf(reqdriver, sizeof(drivername), "%s=%s", "SDL_AUDIODRIVER", s_sdldriver->string);
putenv(reqdriver);
Com_Printf("Starting SDL audio callback.\n");
if (!SDL_WasInit(SDL_INIT_AUDIO))

View file

@ -180,6 +180,11 @@ SockadrToNetadr ( struct sockaddr_storage *s, netadr_t *a )
}
}
void
NET_Init ( )
{
}
qboolean
NET_CompareAdr ( netadr_t a, netadr_t b )
{

View file

@ -45,8 +45,8 @@
#include <dlfcn.h>
#include <dirent.h>
#include "header/glob.h"
#include "../common/header/common.h"
#include "../common/header/glob.h"
#include "header/unix.h"
unsigned sys_frame_time;
@ -94,6 +94,11 @@ CompareAttributes ( char *path, char *name, unsigned musthave, unsigned canthave
return ( true );
}
void
Sys_Init ( void )
{
}
int
Sys_Milliseconds ( void )
{
@ -120,12 +125,6 @@ Sys_Mkdir ( char *path )
mkdir( path, 0755 );
}
void
Sys_Rmdir ( char *path )
{
rmdir( path );
}
char *
Sys_GetCurrentDirectory ( void )
{
@ -502,3 +501,22 @@ Sys_SendKeyEvents ( void )
/* grab frame time */
sys_frame_time = Sys_Milliseconds();
}
char *
Sys_GetHomeDir(void)
{
static char gdir[MAX_OSPATH];
char *home;
home = getenv("HOME");
if (!home)
{
return NULL;
}
snprintf(gdir, sizeof(gdir), "%s/%s/", home, CFGDIR);
return gdir;
}

460
src/windows/conproc.c Normal file
View file

@ -0,0 +1,460 @@
/*
* Copyright (C) 1997-2001 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.
*
* =======================================================================
*
* The "qhost" subsystem, hosting the console window.
*
* =======================================================================
*/
#include <ctype.h>
#include <process.h>
#include <stdio.h>
#include <windows.h>
#include "header/conproc.h"
#define CCOM_WRITE_TEXT 0x2
#define CCOM_GET_TEXT 0x3
#define CCOM_GET_SCR_LINES 0x4
#define CCOM_SET_SCR_LINES 0x5
HANDLE heventDone;
HANDLE hfileBuffer;
HANDLE heventChildSend;
HANDLE heventParentSend;
HANDLE hStdout;
HANDLE hStdin;
LPVOID GetMappedBuffer(HANDLE hfileBuffer);
BOOL GetScreenBufferLines(int *piLines);
BOOL SetScreenBufferLines(int iLines);
BOOL ReadText(LPTSTR pszText, int iBeginLine, int iEndLine);
BOOL WriteText(LPCTSTR szText);
BOOL SetConsoleCXCY(HANDLE hStdout, int cx, int cy);
int CharToCode(char c);
unsigned int _stdcall RequestProc(void *arg);
void ReleaseMappedBuffer(LPVOID pBuffer);
int ccom_argc;
char **ccom_argv;
/*
* Returns the position (1 to argc-1) in the
* program's argument list where the given
* parameter apears, or 0 if not present
*/
int
CCheckParm(char *parm)
{
int i;
for (i = 1; i < ccom_argc; i++)
{
if (!ccom_argv[i])
{
continue;
}
if (!strcmp(parm, ccom_argv[i]))
{
return i;
}
}
return 0;
}
void
InitConProc(int argc, char **argv)
{
HANDLE hFile = NULL;
HANDLE heventParent = NULL;
HANDLE heventChild = NULL;
int t;
unsigned int threadAddr;
ccom_argc = argc;
ccom_argv = argv;
/* give QHOST a chance to hook into the console */
if ((t = CCheckParm("-HFILE")) > 0)
{
if (t < argc)
{
hFile = (HANDLE)(int)strtol(ccom_argv[t + 1], (char **)NULL, 10);
}
}
if ((t = CCheckParm("-HPARENT")) > 0)
{
if (t < argc)
{
heventParent = (HANDLE)(int)strtol(ccom_argv[t + 1], (char **)NULL, 10);
}
}
if ((t = CCheckParm("-HCHILD")) > 0)
{
if (t < argc)
{
heventChild = (HANDLE)(int)strtol(ccom_argv[t + 1], (char **)NULL, 10);
}
}
/* ignore if we don't have all the events. */
if (!hFile || !heventParent || !heventChild)
{
printf("Qhost not present.\n");
return;
}
printf("Initializing for qhost.\n");
hfileBuffer = hFile;
heventParentSend = heventParent;
heventChildSend = heventChild;
/* so we'll know when to go away. */
heventDone = CreateEvent(NULL, FALSE, FALSE, NULL);
if (!heventDone)
{
printf("Couldn't create heventDone\n");
return;
}
if (!_beginthreadex(NULL, 0, RequestProc, NULL, 0, &threadAddr))
{
CloseHandle(heventDone);
printf("Couldn't create QHOST thread\n");
return;
}
/* save off the input/output handles. */
hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
hStdin = GetStdHandle(STD_INPUT_HANDLE);
/* force 80 character width,
at least 25 character height */
SetConsoleCXCY(hStdout, 80, 25);
}
void
DeinitConProc(void)
{
if (heventDone)
{
SetEvent(heventDone);
}
}
unsigned _stdcall
RequestProc(void *arg)
{
int *pBuffer;
DWORD dwRet;
HANDLE heventWait[2];
int iBeginLine, iEndLine;
heventWait[0] = heventParentSend;
heventWait[1] = heventDone;
while (1)
{
dwRet = WaitForMultipleObjects(2, heventWait, FALSE, INFINITE);
/* heventDone fired, so we're exiting. */
if (dwRet == WAIT_OBJECT_0 + 1)
{
break;
}
pBuffer = (int *)GetMappedBuffer(hfileBuffer);
/* hfileBuffer is invalid. Just leave. */
if (!pBuffer)
{
printf("Invalid hfileBuffer\n");
break;
}
switch (pBuffer[0])
{
case CCOM_WRITE_TEXT:
pBuffer[0] = WriteText((LPCTSTR)(pBuffer + 1));
break;
case CCOM_GET_TEXT:
iBeginLine = pBuffer[1];
iEndLine = pBuffer[2];
pBuffer[0] = ReadText((LPTSTR)(pBuffer + 1), iBeginLine,
iEndLine);
break;
case CCOM_GET_SCR_LINES:
pBuffer[0] = GetScreenBufferLines(&pBuffer[1]);
break;
case CCOM_SET_SCR_LINES:
pBuffer[0] = SetScreenBufferLines(pBuffer[1]);
break;
}
ReleaseMappedBuffer(pBuffer);
SetEvent(heventChildSend);
}
_endthreadex(0);
return 0;
}
LPVOID
GetMappedBuffer(HANDLE hfileBuffer)
{
LPVOID pBuffer;
pBuffer = MapViewOfFile(hfileBuffer,
FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
return pBuffer;
}
void
ReleaseMappedBuffer(LPVOID pBuffer)
{
UnmapViewOfFile(pBuffer);
}
BOOL
GetScreenBufferLines(int *piLines)
{
CONSOLE_SCREEN_BUFFER_INFO info;
BOOL bRet;
bRet = GetConsoleScreenBufferInfo(hStdout, &info);
if (bRet)
{
*piLines = info.dwSize.Y;
}
return bRet;
}
BOOL
SetScreenBufferLines(int iLines)
{
return SetConsoleCXCY(hStdout, 80, iLines);
}
BOOL
ReadText(LPTSTR pszText, int iBeginLine, int iEndLine)
{
COORD coord;
DWORD dwRead;
BOOL bRet;
coord.X = 0;
coord.Y = iBeginLine;
bRet = ReadConsoleOutputCharacter(hStdout, pszText,
80 * (iEndLine - iBeginLine + 1), coord,
&dwRead);
/* Make sure it's null terminated. */
if (bRet)
{
pszText[dwRead] = '\0';
}
return bRet;
}
BOOL
WriteText(LPCTSTR szText)
{
DWORD dwWritten;
INPUT_RECORD rec;
char upper, *sz;
sz = (LPTSTR)szText;
while (*sz)
{
/* 13 is the code for a carriage
return (\n) instead of 10. */
if (*sz == 10)
{
*sz = 13;
}
upper = toupper(*sz);
rec.EventType = KEY_EVENT;
rec.Event.KeyEvent.bKeyDown = TRUE;
rec.Event.KeyEvent.wRepeatCount = 1;
rec.Event.KeyEvent.wVirtualKeyCode = upper;
rec.Event.KeyEvent.wVirtualScanCode = CharToCode(*sz);
rec.Event.KeyEvent.uChar.AsciiChar = *sz;
rec.Event.KeyEvent.uChar.UnicodeChar = *sz;
rec.Event.KeyEvent.dwControlKeyState = isupper(*sz) ? 0x80 : 0x0;
WriteConsoleInput(hStdin, &rec, 1, &dwWritten);
rec.Event.KeyEvent.bKeyDown = FALSE;
WriteConsoleInput(hStdin, &rec, 1, &dwWritten);
sz++;
}
return TRUE;
}
int
CharToCode(char c)
{
char upper;
upper = toupper(c);
switch (c)
{
case 13:
return 28;
default:
break;
}
if (isalpha(c))
{
return 30 + upper - 65;
}
if (isdigit(c))
{
return 1 + upper - 47;
}
return c;
}
BOOL
SetConsoleCXCY(HANDLE hStdout, int cx, int cy)
{
CONSOLE_SCREEN_BUFFER_INFO info;
COORD coordMax;
coordMax = GetLargestConsoleWindowSize(hStdout);
if (cy > coordMax.Y)
{
cy = coordMax.Y;
}
if (cx > coordMax.X)
{
cx = coordMax.X;
}
if (!GetConsoleScreenBufferInfo(hStdout, &info))
{
return FALSE;
}
/* height */
info.srWindow.Left = 0;
info.srWindow.Right = info.dwSize.X - 1;
info.srWindow.Top = 0;
info.srWindow.Bottom = cy - 1;
if (cy < info.dwSize.Y)
{
if (!SetConsoleWindowInfo(hStdout, TRUE, &info.srWindow))
{
return FALSE;
}
info.dwSize.Y = cy;
if (!SetConsoleScreenBufferSize(hStdout, info.dwSize))
{
return FALSE;
}
}
else if (cy > info.dwSize.Y)
{
info.dwSize.Y = cy;
if (!SetConsoleScreenBufferSize(hStdout, info.dwSize))
{
return FALSE;
}
if (!SetConsoleWindowInfo(hStdout, TRUE, &info.srWindow))
{
return FALSE;
}
}
if (!GetConsoleScreenBufferInfo(hStdout, &info))
{
return FALSE;
}
/* width */
info.srWindow.Left = 0;
info.srWindow.Right = cx - 1;
info.srWindow.Top = 0;
info.srWindow.Bottom = info.dwSize.Y - 1;
if (cx < info.dwSize.X)
{
if (!SetConsoleWindowInfo(hStdout, TRUE, &info.srWindow))
{
return FALSE;
}
info.dwSize.X = cx;
if (!SetConsoleScreenBufferSize(hStdout, info.dwSize))
{
return FALSE;
}
}
else if (cx > info.dwSize.X)
{
info.dwSize.X = cx;
if (!SetConsoleScreenBufferSize(hStdout, info.dwSize))
{
return FALSE;
}
if (!SetConsoleWindowInfo(hStdout, TRUE, &info.srWindow))
{
return FALSE;
}
}
return TRUE;
}

View file

@ -0,0 +1,34 @@
/*
* Copyright (C) 1997-2001 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.
*
* =======================================================================
*
* Header file to the "qhost" subsystem.
*
* =======================================================================
*/
#ifndef WIN_CONPROC_H
#define WIN_CONPROC_H
void InitConProc(int argc, char **argv);
void DeinitConProc(void);
#endif

View file

@ -0,0 +1,52 @@
/*
* Copyright (C) 1997-2001 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.
*
* =======================================================================
*
* This file holds the main struct for the OpenGL context
*
* =======================================================================
*/
#ifndef WIN_GLW_WIN_H__
#define WIN_GLW_WIN_H__
#include <windows.h>
typedef struct
{
HINSTANCE hInstance;
void *wndproc;
HDC hDC; /* handle to device context */
HWND hWnd; /* handle to window */
HGLRC hGLRC; /* handle to GL rendering context */
HINSTANCE hinstOpenGL; /* HINSTANCE for the OpenGL library */
qboolean minidriver;
qboolean allowdisplaydepthchange;
qboolean mcd_accelerated;
FILE *log_fp;
} glwstate_t;
extern glwstate_t glw_state;
#endif

136
src/windows/header/qal.h Normal file
View file

@ -0,0 +1,136 @@
/*
* Copyright (C) 2012 Yamagi Burmeister
* Copyright (C) 2010 skuller.net
*
* 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.
*
* =======================================================================
*
* Header file to the low level "qal" API implementation. This source file
* was taken from Q2Pro and modified by the YQ2 authors.
*
* =======================================================================
*/
#ifdef USE_OPENAL
#ifndef WIN_QAL_API_H_
#define WIN_QAL_API_H_
#include <AL/al.h>
#include <AL/efx.h>
/* Function pointers used to tie
the qal API to the OpenAL API */
extern LPALENABLE qalEnable;
extern LPALDISABLE qalDisable;
extern LPALISENABLED qalIsEnabled;
extern LPALGETSTRING qalGetString;
extern LPALGETBOOLEANV qalGetBooleanv;
extern LPALGETINTEGERV qalGetIntegerv;
extern LPALGETFLOATV qalGetFloatv;
extern LPALGETDOUBLEV qalGetDoublev;
extern LPALGETBOOLEAN qalGetBoolean;
extern LPALGETINTEGER qalGetInteger;
extern LPALGETFLOAT qalGetFloat;
extern LPALGETDOUBLE qalGetDouble;
extern LPALGETERROR qalGetError;
extern LPALISEXTENSIONPRESENT qalIsExtensionPresent;
extern LPALGETPROCADDRESS qalGetProcAddress;
extern LPALGETENUMVALUE qalGetEnumValue;
extern LPALLISTENERF qalListenerf;
extern LPALLISTENER3F qalListener3f;
extern LPALLISTENERFV qalListenerfv;
extern LPALLISTENERI qalListeneri;
extern LPALLISTENER3I qalListener3i;
extern LPALLISTENERIV qalListeneriv;
extern LPALGETLISTENERF qalGetListenerf;
extern LPALGETLISTENER3F qalGetListener3f;
extern LPALGETLISTENERFV qalGetListenerfv;
extern LPALGETLISTENERI qalGetListeneri;
extern LPALGETLISTENER3I qalGetListener3i;
extern LPALGETLISTENERIV qalGetListeneriv;
extern LPALGENSOURCES qalGenSources;
extern LPALDELETESOURCES qalDeleteSources;
extern LPALISSOURCE qalIsSource;
extern LPALSOURCEF qalSourcef;
extern LPALSOURCE3F qalSource3f;
extern LPALSOURCEFV qalSourcefv;
extern LPALSOURCEI qalSourcei;
extern LPALSOURCE3I qalSource3i;
extern LPALSOURCEIV qalSourceiv;
extern LPALGETSOURCEF qalGetSourcef;
extern LPALGETSOURCE3F qalGetSource3f;
extern LPALGETSOURCEFV qalGetSourcefv;
extern LPALGETSOURCEI qalGetSourcei;
extern LPALGETSOURCE3I qalGetSource3i;
extern LPALGETSOURCEIV qalGetSourceiv;
extern LPALSOURCEPLAYV qalSourcePlayv;
extern LPALSOURCESTOPV qalSourceStopv;
extern LPALSOURCEREWINDV qalSourceRewindv;
extern LPALSOURCEPAUSEV qalSourcePausev;
extern LPALSOURCEPLAY qalSourcePlay;
extern LPALSOURCESTOP qalSourceStop;
extern LPALSOURCEREWIND qalSourceRewind;
extern LPALSOURCEPAUSE qalSourcePause;
extern LPALSOURCEQUEUEBUFFERS qalSourceQueueBuffers;
extern LPALSOURCEUNQUEUEBUFFERS qalSourceUnqueueBuffers;
extern LPALGENBUFFERS qalGenBuffers;
extern LPALDELETEBUFFERS qalDeleteBuffers;
extern LPALISBUFFER qalIsBuffer;
extern LPALBUFFERDATA qalBufferData;
extern LPALBUFFERF qalBufferf;
extern LPALBUFFER3F qalBuffer3f;
extern LPALBUFFERFV qalBufferfv;
extern LPALBUFFERI qalBufferi;
extern LPALBUFFER3I qalBuffer3i;
extern LPALBUFFERIV qalBufferiv;
extern LPALGETBUFFERF qalGetBufferf;
extern LPALGETBUFFER3F qalGetBuffer3f;
extern LPALGETBUFFERFV qalGetBufferfv;
extern LPALGETBUFFERI qalGetBufferi;
extern LPALGETBUFFER3I qalGetBuffer3i;
extern LPALGETBUFFERIV qalGetBufferiv;
extern LPALDOPPLERFACTOR qalDopplerFactor;
extern LPALDOPPLERVELOCITY qalDopplerVelocity;
extern LPALSPEEDOFSOUND qalSpeedOfSound;
extern LPALDISTANCEMODEL qalDistanceModel;
extern LPALGENFILTERS qalGenFilters;
extern LPALFILTERI qalFilteri;
extern LPALFILTERF qalFilterf;
extern LPALDELETEFILTERS qalDeleteFilters;
/*
* Gives information over the OpenAL
* implementation and it's state
*/
void QAL_SoundInfo(void);
/*
* Loads the OpenAL shared lib, creates
* a context and device handle.
*/
qboolean QAL_Init(void);
/*
* Shuts OpenAL down, frees all context and
* device handles and unloads the shared lib.
*/
void QAL_Shutdown(void);
#endif /* WIN_QAL_API_H_ */
#endif /* USE_OPENAL */

View file

@ -0,0 +1,15 @@
#ifndef WIN_RESOURCE_H
#define WIN_RESOURCE_H
#define IDI_ICON1 101
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 103
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
#endif

View file

@ -0,0 +1,69 @@
/*
* Copyright (C) 1997-2001 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.
*
* =======================================================================
*
* Header file for Windows specific stuff.
*
* =======================================================================
*/
#ifndef WIN_WINQUAKE_H
#define WIN_WINQUAKE_H
#include <windows.h>
#define WINDOW_STYLE (WS_OVERLAPPED | WS_BORDER | WS_CAPTION | WS_VISIBLE)
#ifndef _PC_24
#define _PC_24 0x00020000
#endif
#ifndef _MCW_PC
#define _MCW_PC 0x00030000
#endif
/* This is a hack to work around a missing MinGW prototype */
#ifndef _controlfp
unsigned int _controlfp(unsigned int new, unsigned int mask);
#endif
extern HINSTANCE global_hInstance;
extern HWND cl_hwnd;
extern qboolean ActiveApp, Minimized;
extern int window_center_x, window_center_y;
extern RECT window_rect;
typedef void (*Key_Event_fp_t)(int key, qboolean down);
extern void (*IN_Update_fp)(void);
typedef struct in_state
{
/* Pointers to functions back in client, set by vid_so */
void ( *IN_CenterView_fp )( void );
Key_Event_fp_t Key_Event_fp;
vec_t *viewangles;
int *in_strafe_state;
int *in_speed_state;
} in_state_t;
#endif

99
src/windows/mem.c Normal file
View file

@ -0,0 +1,99 @@
/*
* Copyright (C) 1997-2001 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.
*
* =======================================================================
*
* Memory handling functions.
*
* =======================================================================
*/
#include "../common/header/common.h"
#include "header/winquake.h"
byte *membase;
int hunkcount;
int hunkmaxsize;
int cursize;
void *
Hunk_Begin(int maxsize)
{
/* reserve a huge chunk of memory,
but don't commit any yet */
cursize = 0;
hunkmaxsize = maxsize;
membase = VirtualAlloc(NULL, maxsize, MEM_RESERVE, PAGE_NOACCESS);
if (!membase)
{
Sys_Error("VirtualAlloc reserve failed");
}
return (void *)membase;
}
void *
Hunk_Alloc(int size)
{
void *buf;
/* round to cacheline */
size = (size + 31) & ~31;
/* commit pages as needed */
buf = VirtualAlloc(membase, cursize + size, MEM_COMMIT, PAGE_READWRITE);
if (!buf)
{
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&buf, 0, NULL);
Sys_Error("VirtualAlloc commit failed.\n%s", buf);
}
cursize += size;
if (cursize > hunkmaxsize)
{
Sys_Error("Hunk_Alloc overflow");
}
return (void *)(membase + cursize - size);
}
int
Hunk_End(void)
{
hunkcount++;
return cursize;
}
void
Hunk_Free(void *base)
{
if (base)
{
VirtualFree(base, 0, MEM_RELEASE);
}
hunkcount--;
}

1392
src/windows/network.c Normal file

File diff suppressed because it is too large Load diff

503
src/windows/qal.c Normal file
View file

@ -0,0 +1,503 @@
/*
* Copyright (C) 2012 Yamagi Burmeister
* Copyright (C) 2010 skuller.net
*
* 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.
*
* =======================================================================
*
* Low level, platform depended "qal" API implementation. This files
* provides functions to load, initialize, shutdown und unload the
* OpenAL library and connects the "qal" funtion pointers to the
* OpenAL functions. This source file was taken from Q2Pro and
* modified by the YQ2 authors.
*
* =======================================================================
*/
#ifdef USE_OPENAL
#include <AL/al.h>
#include <AL/alc.h>
#include <AL/alext.h>
#include <windows.h>
#include "../common/header/common.h"
#include "header/qal.h"
#define GPA(a) (void *)GetProcAddress(handle, a)
static ALCcontext *context;
static ALCdevice *device;
static cvar_t *al_device;
static cvar_t *al_driver;
static void *handle;
/* Function pointers for OpenAL management */
static LPALCCREATECONTEXT qalcCreateContext;
static LPALCMAKECONTEXTCURRENT qalcMakeContextCurrent;
static LPALCPROCESSCONTEXT qalcProcessContext;
static LPALCSUSPENDCONTEXT qalcSuspendContext;
static LPALCDESTROYCONTEXT qalcDestroyContext;
static LPALCGETCURRENTCONTEXT qalcGetCurrentContext;
static LPALCGETCONTEXTSDEVICE qalcGetContextsDevice;
static LPALCOPENDEVICE qalcOpenDevice;
static LPALCCLOSEDEVICE qalcCloseDevice;
static LPALCGETERROR qalcGetError;
static LPALCISEXTENSIONPRESENT qalcIsExtensionPresent;
static LPALCGETPROCADDRESS qalcGetProcAddress;
static LPALCGETENUMVALUE qalcGetEnumValue;
static LPALCGETSTRING qalcGetString;
static LPALCGETINTEGERV qalcGetIntegerv;
static LPALCCAPTUREOPENDEVICE qalcCaptureOpenDevice;
static LPALCCAPTURECLOSEDEVICE qalcCaptureCloseDevice;
static LPALCCAPTURESTART qalcCaptureStart;
static LPALCCAPTURESTOP qalcCaptureStop;
static LPALCCAPTURESAMPLES qalcCaptureSamples ;
/* Declaration of function pointers used
to connect OpenAL to our internal API */
LPALENABLE qalEnable;
LPALDISABLE qalDisable;
LPALISENABLED qalIsEnabled;
LPALGETSTRING qalGetString;
LPALGETBOOLEANV qalGetBooleanv;
LPALGETINTEGERV qalGetIntegerv;
LPALGETFLOATV qalGetFloatv;
LPALGETDOUBLEV qalGetDoublev;
LPALGETBOOLEAN qalGetBoolean;
LPALGETINTEGER qalGetInteger;
LPALGETFLOAT qalGetFloat;
LPALGETDOUBLE qalGetDouble;
LPALGETERROR qalGetError;
LPALISEXTENSIONPRESENT qalIsExtensionPresent;
LPALGETPROCADDRESS qalGetProcAddress;
LPALGETENUMVALUE qalGetEnumValue;
LPALLISTENERF qalListenerf;
LPALLISTENER3F qalListener3f;
LPALLISTENERFV qalListenerfv;
LPALLISTENERI qalListeneri;
LPALLISTENER3I qalListener3i;
LPALLISTENERIV qalListeneriv;
LPALGETLISTENERF qalGetListenerf;
LPALGETLISTENER3F qalGetListener3f;
LPALGETLISTENERFV qalGetListenerfv;
LPALGETLISTENERI qalGetListeneri;
LPALGETLISTENER3I qalGetListener3i;
LPALGETLISTENERIV qalGetListeneriv;
LPALGENSOURCES qalGenSources;
LPALDELETESOURCES qalDeleteSources;
LPALISSOURCE qalIsSource;
LPALSOURCEF qalSourcef;
LPALSOURCE3F qalSource3f;
LPALSOURCEFV qalSourcefv;
LPALSOURCEI qalSourcei;
LPALSOURCE3I qalSource3i;
LPALSOURCEIV qalSourceiv;
LPALGETSOURCEF qalGetSourcef;
LPALGETSOURCE3F qalGetSource3f;
LPALGETSOURCEFV qalGetSourcefv;
LPALGETSOURCEI qalGetSourcei;
LPALGETSOURCE3I qalGetSource3i;
LPALGETSOURCEIV qalGetSourceiv;
LPALSOURCEPLAYV qalSourcePlayv;
LPALSOURCESTOPV qalSourceStopv;
LPALSOURCEREWINDV qalSourceRewindv;
LPALSOURCEPAUSEV qalSourcePausev;
LPALSOURCEPLAY qalSourcePlay;
LPALSOURCESTOP qalSourceStop;
LPALSOURCEREWIND qalSourceRewind;
LPALSOURCEPAUSE qalSourcePause;
LPALSOURCEQUEUEBUFFERS qalSourceQueueBuffers;
LPALSOURCEUNQUEUEBUFFERS qalSourceUnqueueBuffers;
LPALGENBUFFERS qalGenBuffers;
LPALDELETEBUFFERS qalDeleteBuffers;
LPALISBUFFER qalIsBuffer;
LPALBUFFERDATA qalBufferData;
LPALBUFFERF qalBufferf;
LPALBUFFER3F qalBuffer3f;
LPALBUFFERFV qalBufferfv;
LPALBUFFERI qalBufferi;
LPALBUFFER3I qalBuffer3i;
LPALBUFFERIV qalBufferiv;
LPALGETBUFFERF qalGetBufferf;
LPALGETBUFFER3F qalGetBuffer3f;
LPALGETBUFFERFV qalGetBufferfv;
LPALGETBUFFERI qalGetBufferi;
LPALGETBUFFER3I qalGetBuffer3i;
LPALGETBUFFERIV qalGetBufferiv;
LPALDOPPLERFACTOR qalDopplerFactor;
LPALDOPPLERVELOCITY qalDopplerVelocity;
LPALSPEEDOFSOUND qalSpeedOfSound;
LPALDISTANCEMODEL qalDistanceModel;
LPALGENFILTERS qalGenFilters;
LPALFILTERI qalFilteri;
LPALFILTERF qalFilterf;
LPALDELETEFILTERS qalDeleteFilters;
/*
* Gives information over the OpenAL
* implementation and it's state
*/
void QAL_SoundInfo()
{
Com_Printf("OpenAL settings:\n");
Com_Printf("AL_VENDOR: %s\n", qalGetString(AL_VENDOR));
Com_Printf("AL_RENDERER: %s\n", qalGetString(AL_RENDERER));
Com_Printf("AL_VERSION: %s\n", qalGetString(AL_VERSION));
Com_Printf("AL_EXTENSIONS: %s\n", qalGetString(AL_EXTENSIONS));
if (qalcIsExtensionPresent(NULL, "ALC_ENUMERATE_ALL_EXT"))
{
const char *devs = qalcGetString(NULL, ALC_ALL_DEVICES_SPECIFIER);
Com_Printf("\nAvailable OpenAL devices:\n");
if (devs == NULL)
{
Com_Printf("- No devices found. Depending on your\n");
Com_Printf(" platform this may be expected and\n");
Com_Printf(" doesn't indicate a problem!\n");
}
else
{
while (devs && *devs)
{
Com_Printf("- %s\n", devs);
devs += strlen(devs) + 1;
}
}
}
if (qalcIsExtensionPresent(NULL, "ALC_ENUMERATE_ALL_EXT"))
{
const char *devs = qalcGetString(device, ALC_DEVICE_SPECIFIER);
Com_Printf("\nCurrent OpenAL device:\n");
if (devs == NULL)
{
Com_Printf("- No OpenAL device in use\n");
}
else
{
Com_Printf("- %s\n", devs);
}
}
}
/*
* Shuts OpenAL down, frees all context and
* device handles and unloads the shared lib.
*/
void
QAL_Shutdown()
{
if (context)
{
qalcMakeContextCurrent( NULL );
qalcDestroyContext( context );
context = NULL;
}
if (device)
{
qalcCloseDevice( device );
device = NULL;
}
/* Disconnect function pointers used
for OpenAL management calls */
qalcCreateContext = NULL;
qalcMakeContextCurrent = NULL;
qalcProcessContext = NULL;
qalcSuspendContext = NULL;
qalcDestroyContext = NULL;
qalcGetCurrentContext = NULL;
qalcGetContextsDevice = NULL;
qalcOpenDevice = NULL;
qalcCloseDevice = NULL;
qalcGetError = NULL;
qalcIsExtensionPresent = NULL;
qalcGetProcAddress = NULL;
qalcGetEnumValue = NULL;
qalcGetString = NULL;
qalcGetIntegerv = NULL;
qalcCaptureOpenDevice = NULL;
qalcCaptureCloseDevice = NULL;
qalcCaptureStart = NULL;
qalcCaptureStop = NULL;
qalcCaptureSamples = NULL;
/* Disconnect OpenAL
* function pointers */
qalEnable = NULL;
qalDisable = NULL;
qalIsEnabled = NULL;
qalGetString = NULL;
qalGetBooleanv = NULL;
qalGetIntegerv = NULL;
qalGetFloatv = NULL;
qalGetDoublev = NULL;
qalGetBoolean = NULL;
qalGetInteger = NULL;
qalGetFloat = NULL;
qalGetDouble = NULL;
qalGetError = NULL;
qalIsExtensionPresent = NULL;
qalGetProcAddress = NULL;
qalGetEnumValue = NULL;
qalListenerf = NULL;
qalListener3f = NULL;
qalListenerfv = NULL;
qalListeneri = NULL;
qalListener3i = NULL;
qalListeneriv = NULL;
qalGetListenerf = NULL;
qalGetListener3f = NULL;
qalGetListenerfv = NULL;
qalGetListeneri = NULL;
qalGetListener3i = NULL;
qalGetListeneriv = NULL;
qalGenSources = NULL;
qalDeleteSources = NULL;
qalIsSource = NULL;
qalSourcef = NULL;
qalSource3f = NULL;
qalSourcefv = NULL;
qalSourcei = NULL;
qalSource3i = NULL;
qalSourceiv = NULL;
qalGetSourcef = NULL;
qalGetSource3f = NULL;
qalGetSourcefv = NULL;
qalGetSourcei = NULL;
qalGetSource3i = NULL;
qalGetSourceiv = NULL;
qalSourcePlayv = NULL;
qalSourceStopv = NULL;
qalSourceRewindv = NULL;
qalSourcePausev = NULL;
qalSourcePlay = NULL;
qalSourceStop = NULL;
qalSourceRewind = NULL;
qalSourcePause = NULL;
qalSourceQueueBuffers = NULL;
qalSourceUnqueueBuffers = NULL;
qalGenBuffers = NULL;
qalDeleteBuffers = NULL;
qalIsBuffer = NULL;
qalBufferData = NULL;
qalBufferf = NULL;
qalBuffer3f = NULL;
qalBufferfv = NULL;
qalBufferi = NULL;
qalBuffer3i = NULL;
qalBufferiv = NULL;
qalGetBufferf = NULL;
qalGetBuffer3f = NULL;
qalGetBufferfv = NULL;
qalGetBufferi = NULL;
qalGetBuffer3i = NULL;
qalGetBufferiv = NULL;
qalDopplerFactor = NULL;
qalDopplerVelocity = NULL;
qalSpeedOfSound = NULL;
qalDistanceModel = NULL;
qalGenFilters = NULL;
qalFilteri = NULL;
qalFilterf = NULL;
qalDeleteFilters = NULL;
/* Unload the shared lib */
FreeLibrary(handle);
handle = NULL;
}
/*
* Loads the OpenAL shared lib, creates
* a context and device handle.
*/
qboolean
QAL_Init()
{
/* DEFAULT_OPENAL_DRIVER is defined at compile time via the compiler */
al_driver = Cvar_Get( "al_driver", DEFAULT_OPENAL_DRIVER, CVAR_ARCHIVE );
al_device = Cvar_Get( "al_device", "", CVAR_ARCHIVE );
Com_Printf("LoadLibrary(%s)\n", al_driver->string);
/* Load the library */
handle = LoadLibrary( al_driver->string );
if (!handle)
{
Com_Printf("Loading %s failed! Disabling OpenAL.\n", al_driver->string);
return false;
}
/* Connect function pointers to management functions */
qalcCreateContext = GPA("alcCreateContext");
qalcMakeContextCurrent = GPA("alcMakeContextCurrent");
qalcProcessContext = GPA("alcProcessContext");
qalcSuspendContext = GPA("alcSuspendContext");
qalcDestroyContext = GPA("alcDestroyContext");
qalcGetCurrentContext = GPA("alcGetCurrentContext");
qalcGetContextsDevice = GPA("alcGetContextsDevice");
qalcOpenDevice = GPA("alcOpenDevice");
qalcCloseDevice = GPA("alcCloseDevice");
qalcGetError = GPA("alcGetError");
qalcIsExtensionPresent = GPA("alcIsExtensionPresent");
qalcGetProcAddress = GPA("alcGetProcAddress");
qalcGetEnumValue = GPA("alcGetEnumValue");
qalcGetString = GPA("alcGetString");
qalcGetIntegerv = GPA("alcGetIntegerv");
qalcCaptureOpenDevice = GPA("alcCaptureOpenDevice");
qalcCaptureCloseDevice = GPA("alcCaptureCloseDevice");
qalcCaptureStart = GPA("alcCaptureStart");
qalcCaptureStop = GPA("alcCaptureStop");
qalcCaptureSamples = GPA("alcCaptureSamples");
/* Connect function pointers to
to OpenAL API functions */
qalEnable = GPA("alEnable");
qalDisable = GPA("alDisable");
qalIsEnabled = GPA("alIsEnabled");
qalGetString = GPA("alGetString");
qalGetBooleanv = GPA("alGetBooleanv");
qalGetIntegerv = GPA("alGetIntegerv");
qalGetFloatv = GPA("alGetFloatv");
qalGetDoublev = GPA("alGetDoublev");
qalGetBoolean = GPA("alGetBoolean");
qalGetInteger = GPA("alGetInteger");
qalGetFloat = GPA("alGetFloat");
qalGetDouble = GPA("alGetDouble");
qalGetError = GPA("alGetError");
qalIsExtensionPresent = GPA("alIsExtensionPresent");
qalGetProcAddress = GPA("alGetProcAddress");
qalGetEnumValue = GPA("alGetEnumValue");
qalListenerf = GPA("alListenerf");
qalListener3f = GPA("alListener3f");
qalListenerfv = GPA("alListenerfv");
qalListeneri = GPA("alListeneri");
qalListener3i = GPA("alListener3i");
qalListeneriv = GPA("alListeneriv");
qalGetListenerf = GPA("alGetListenerf");
qalGetListener3f = GPA("alGetListener3f");
qalGetListenerfv = GPA("alGetListenerfv");
qalGetListeneri = GPA("alGetListeneri");
qalGetListener3i = GPA("alGetListener3i");
qalGetListeneriv = GPA("alGetListeneriv");
qalGenSources = GPA("alGenSources");
qalDeleteSources = GPA("alDeleteSources");
qalIsSource = GPA("alIsSource");
qalSourcef = GPA("alSourcef");
qalSource3f = GPA("alSource3f");
qalSourcefv = GPA("alSourcefv");
qalSourcei = GPA("alSourcei");
qalSource3i = GPA("alSource3i");
qalSourceiv = GPA("alSourceiv");
qalGetSourcef = GPA("alGetSourcef");
qalGetSource3f = GPA("alGetSource3f");
qalGetSourcefv = GPA("alGetSourcefv");
qalGetSourcei = GPA("alGetSourcei");
qalGetSource3i = GPA("alGetSource3i");
qalGetSourceiv = GPA("alGetSourceiv");
qalSourcePlayv = GPA("alSourcePlayv");
qalSourceStopv = GPA("alSourceStopv");
qalSourceRewindv = GPA("alSourceRewindv");
qalSourcePausev = GPA("alSourcePausev");
qalSourcePlay = GPA("alSourcePlay");
qalSourceStop = GPA("alSourceStop");
qalSourceRewind = GPA("alSourceRewind");
qalSourcePause = GPA("alSourcePause");
qalSourceQueueBuffers = GPA("alSourceQueueBuffers");
qalSourceUnqueueBuffers = GPA("alSourceUnqueueBuffers");
qalGenBuffers = GPA("alGenBuffers");
qalDeleteBuffers = GPA("alDeleteBuffers");
qalIsBuffer = GPA("alIsBuffer");
qalBufferData = GPA("alBufferData");
qalBufferf = GPA("alBufferf");
qalBuffer3f = GPA("alBuffer3f");
qalBufferfv = GPA("alBufferfv");
qalBufferi = GPA("alBufferi");
qalBuffer3i = GPA("alBuffer3i");
qalBufferiv = GPA("alBufferiv");
qalGetBufferf = GPA("alGetBufferf");
qalGetBuffer3f = GPA("alGetBuffer3f");
qalGetBufferfv = GPA("alGetBufferfv");
qalGetBufferi = GPA("alGetBufferi");
qalGetBuffer3i = GPA("alGetBuffer3i");
qalGetBufferiv = GPA("alGetBufferiv");
qalDopplerFactor = GPA("alDopplerFactor");
qalDopplerVelocity = GPA("alDopplerVelocity");
qalSpeedOfSound = GPA("alSpeedOfSound");
qalDistanceModel = GPA("alDistanceModel");
qalGenFilters = GPA("alGenFilters");
qalFilteri = GPA("alFilteri");
qalFilterf = GPA("alFilterf");
qalDeleteFilters = GPA("alDeleteFilters");
/* Open the OpenAL device */
Com_Printf("...opening OpenAL device:");
device = qalcOpenDevice(al_device->string[0] ? al_device->string : NULL);
if(!device)
{
Com_DPrintf("failed\n");
QAL_Shutdown();
return false;
}
Com_Printf("ok\n");
/* Create the OpenAL context */
Com_Printf("...creating OpenAL context: ");
context = qalcCreateContext(device, NULL);
if(!context)
{
Com_DPrintf("failed\n");
QAL_Shutdown();
return false;
}
Com_Printf("ok\n");
/* Set the created context as current context */
Com_Printf("...making context current: ");
if (!qalcMakeContextCurrent(context))
{
Com_DPrintf("failed\n");
QAL_Shutdown();
return false;
}
Com_Printf("ok\n");
/* Print OpenAL informations */
Com_Printf("\n");
QAL_SoundInfo();
Com_Printf("\n");
return true;
}
#endif /* USE_OPENAL */

4769
src/windows/qgl.c Normal file

File diff suppressed because it is too large Load diff

739
src/windows/system.c Normal file
View file

@ -0,0 +1,739 @@
/*
* Copyright (C) 1997-2001 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.
*
* =======================================================================
*
* This file is the starting point of the program and implements
* several support functions and the main loop.
*
* =======================================================================
*/
#include <errno.h>
#include <float.h>
#include <fcntl.h>
#include <stdio.h>
#include <direct.h>
#include <io.h>
#include <conio.h>
#include <shlobj.h>
#include "../common/header/common.h"
#include "header/conproc.h"
#include "header/resource.h"
#include "header/winquake.h"
#define MAX_NUM_ARGVS 128
int curtime;
int starttime;
qboolean ActiveApp;
qboolean Minimized;
static HANDLE hinput, houtput;
static HANDLE qwclsemaphore;
HINSTANCE global_hInstance;
static HINSTANCE game_library;
unsigned int sys_msg_time;
unsigned int sys_frame_time;
static char console_text[256];
static int console_textlen;
char findbase[MAX_OSPATH];
char findpath[MAX_OSPATH];
int findhandle;
int argc;
char *argv[MAX_NUM_ARGVS];
/* ================================================================ */
void
Sys_Error(char *error, ...)
{
va_list argptr;
char text[1024];
#ifndef DEDICATED_ONLY
CL_Shutdown();
#endif
Qcommon_Shutdown();
va_start(argptr, error);
vsprintf(text, error, argptr);
va_end(argptr);
MessageBox(NULL, text, "Error", 0 /* MB_OK */);
if (qwclsemaphore)
{
CloseHandle(qwclsemaphore);
}
/* shut down QHOST hooks if necessary */
DeinitConProc();
exit(1);
}
void
Sys_Quit(void)
{
timeEndPeriod(1);
#ifndef DEDICATED_ONLY
CL_Shutdown();
#endif
Qcommon_Shutdown();
CloseHandle(qwclsemaphore);
if (dedicated && dedicated->value)
{
FreeConsole();
}
/* shut down QHOST hooks if necessary */
DeinitConProc();
exit(0);
}
void
WinError(void)
{
LPVOID lpMsgBuf;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&lpMsgBuf, 0, NULL);
/* Display the string. */
MessageBox(NULL, lpMsgBuf, "GetLastError", MB_OK | MB_ICONINFORMATION);
/* Free the buffer. */
LocalFree(lpMsgBuf);
}
/* ================================================================ */
char *
Sys_ScanForCD(void)
{
static char cddir[MAX_OSPATH];
static qboolean done;
char drive[4];
FILE *f;
char test[MAX_QPATH];
if (done) /* don't re-check */
{
return cddir;
}
/* no abort/retry/fail errors */
SetErrorMode(SEM_FAILCRITICALERRORS);
drive[0] = 'c';
drive[1] = ':';
drive[2] = '\\';
drive[3] = 0;
done = true;
/* scan the drives */
for (drive[0] = 'c'; drive[0] <= 'z'; drive[0]++)
{
/* where activision put the stuff... */
sprintf(cddir, "%sinstall\\data", drive);
sprintf(test, "%sinstall\\data\\quake2.exe", drive);
f = fopen(test, "r");
if (f)
{
fclose(f);
if (GetDriveType(drive) == DRIVE_CDROM)
{
return cddir;
}
}
}
cddir[0] = 0;
return NULL;
}
/* ================================================================ */
void
Sys_Init(void)
{
OSVERSIONINFO vinfo;
timeBeginPeriod(1);
vinfo.dwOSVersionInfoSize = sizeof(vinfo);
if (!GetVersionEx(&vinfo))
{
Sys_Error("Couldn't get OS info");
}
/* While Quake II should run on older versions,
limit Yamagi Quake II to Windows XP and
above. Testing older version would be a
PITA. */
if (!((vinfo.dwMajorVersion > 5) ||
((vinfo.dwMajorVersion == 5) &&
(vinfo.dwMinorVersion >= 1))))
{
Sys_Error("Yamagi Quake II needs Windows XP or higher!\n");
}
if (dedicated->value)
{
AllocConsole();
hinput = GetStdHandle(STD_INPUT_HANDLE);
houtput = GetStdHandle(STD_OUTPUT_HANDLE);
/* let QHOST hook in */
InitConProc(argc, argv);
}
}
char *
Sys_ConsoleInput(void)
{
INPUT_RECORD recs[1024];
int ch;
DWORD dummy, numread, numevents;
if (!dedicated || !dedicated->value)
{
return NULL;
}
for ( ; ; )
{
if (!GetNumberOfConsoleInputEvents(hinput, &numevents))
{
Sys_Error("Error getting # of console events");
}
if (numevents <= 0)
{
break;
}
if (!ReadConsoleInput(hinput, recs, 1, &numread))
{
Sys_Error("Error reading console input");
}
if (numread != 1)
{
Sys_Error("Couldn't read console input");
}
if (recs[0].EventType == KEY_EVENT)
{
if (!recs[0].Event.KeyEvent.bKeyDown)
{
ch = recs[0].Event.KeyEvent.uChar.AsciiChar;
switch (ch)
{
case '\r':
WriteFile(houtput, "\r\n", 2, &dummy, NULL);
if (console_textlen)
{
console_text[console_textlen] = 0;
console_textlen = 0;
return console_text;
}
break;
case '\b':
if (console_textlen)
{
console_textlen--;
WriteFile(houtput, "\b \b", 3, &dummy, NULL);
}
break;
default:
if (ch >= ' ')
{
if (console_textlen < sizeof(console_text) - 2)
{
WriteFile(houtput, &ch, 1, &dummy, NULL);
console_text[console_textlen] = ch;
console_textlen++;
}
}
break;
}
}
}
}
return NULL;
}
void
Sys_ConsoleOutput(char *string)
{
char text[256];
DWORD dummy;
if (!dedicated || !dedicated->value)
{
return;
}
if (console_textlen)
{
text[0] = '\r';
memset(&text[1], ' ', console_textlen);
text[console_textlen + 1] = '\r';
text[console_textlen + 2] = 0;
WriteFile(houtput, text, console_textlen + 2, &dummy, NULL);
}
WriteFile(houtput, string, strlen(string), &dummy, NULL);
if (console_textlen)
{
WriteFile(houtput, console_text, console_textlen, &dummy, NULL);
}
}
void
Sys_SendKeyEvents(void)
{
#ifndef DEDICATED_ONLY
if ( IN_Update_fp )
{
IN_Update_fp();
}
#endif
/* grab frame time */
sys_frame_time = timeGetTime();
}
/* ================================================================ */
void
Sys_UnloadGame(void)
{
if (!FreeLibrary(game_library))
{
Com_Error(ERR_FATAL, "FreeLibrary failed for game library");
}
game_library = NULL;
}
void *
Sys_GetGameAPI(void *parms)
{
void *(*GetGameAPI)(void *);
const char *gamename = "game.dll";
char name[MAX_OSPATH];
char *path = NULL;
if (game_library)
{
Com_Error(ERR_FATAL, "Sys_GetGameAPI without Sys_UnloadingGame");
}
/* now run through the search paths */
path = NULL;
while (1)
{
path = FS_NextPath(path);
if (!path)
{
return NULL; /* couldn't find one anywhere */
}
Com_sprintf(name, sizeof(name), "%s/%s", path, gamename);
game_library = LoadLibrary(name);
if (game_library)
{
Com_DPrintf("LoadLibrary (%s)\n", name);
break;
}
}
GetGameAPI = (void *)GetProcAddress(game_library, "GetGameAPI");
if (!GetGameAPI)
{
Sys_UnloadGame();
return NULL;
}
return GetGameAPI(parms);
}
/* ======================================================================= */
void
ParseCommandLine(LPSTR lpCmdLine)
{
argc = 1;
argv[0] = "exe";
while (*lpCmdLine && (argc < MAX_NUM_ARGVS))
{
while (*lpCmdLine && ((*lpCmdLine <= 32) || (*lpCmdLine > 126)))
{
lpCmdLine++;
}
if (*lpCmdLine)
{
argv[argc] = lpCmdLine;
argc++;
while (*lpCmdLine && ((*lpCmdLine > 32) && (*lpCmdLine <= 126)))
{
lpCmdLine++;
}
if (*lpCmdLine)
{
*lpCmdLine = 0;
lpCmdLine++;
}
}
}
}
/* ======================================================================= */
int
Sys_Milliseconds(void)
{
static int base;
static qboolean initialized = false;
if (!initialized)
{ /* let base retain 16 bits of effectively random data */
base = timeGetTime() & 0xffff0000;
initialized = true;
}
curtime = timeGetTime() - base;
return curtime;
}
/* ======================================================================= */
static qboolean
CompareAttributes(unsigned found, unsigned musthave, unsigned canthave)
{
if ((found & _A_RDONLY) && (canthave & SFF_RDONLY))
{
return false;
}
if ((found & _A_HIDDEN) && (canthave & SFF_HIDDEN))
{
return false;
}
if ((found & _A_SYSTEM) && (canthave & SFF_SYSTEM))
{
return false;
}
if ((found & _A_SUBDIR) && (canthave & SFF_SUBDIR))
{
return false;
}
if ((found & _A_ARCH) && (canthave & SFF_ARCH))
{
return false;
}
if ((musthave & SFF_RDONLY) && !(found & _A_RDONLY))
{
return false;
}
if ((musthave & SFF_HIDDEN) && !(found & _A_HIDDEN))
{
return false;
}
if ((musthave & SFF_SYSTEM) && !(found & _A_SYSTEM))
{
return false;
}
if ((musthave & SFF_SUBDIR) && !(found & _A_SUBDIR))
{
return false;
}
if ((musthave & SFF_ARCH) && !(found & _A_ARCH))
{
return false;
}
return true;
}
char *
Sys_FindFirst(char *path, unsigned musthave, unsigned canthave)
{
struct _finddata_t findinfo;
if (findhandle)
{
Sys_Error("Sys_BeginFind without close");
}
findhandle = 0;
COM_FilePath(path, findbase);
findhandle = _findfirst(path, &findinfo);
if (findhandle == -1)
{
return NULL;
}
if (!CompareAttributes(findinfo.attrib, musthave, canthave))
{
return NULL;
}
Com_sprintf(findpath, sizeof(findpath), "%s/%s", findbase, findinfo.name);
return findpath;
}
char *
Sys_FindNext(unsigned musthave, unsigned canthave)
{
struct _finddata_t findinfo;
if (findhandle == -1)
{
return NULL;
}
if (_findnext(findhandle, &findinfo) == -1)
{
return NULL;
}
if (!CompareAttributes(findinfo.attrib, musthave, canthave))
{
return NULL;
}
Com_sprintf(findpath, sizeof(findpath), "%s/%s", findbase, findinfo.name);
return findpath;
}
void
Sys_FindClose(void)
{
if (findhandle != -1)
{
_findclose(findhandle);
}
findhandle = 0;
}
void
Sys_Mkdir(char *path)
{
_mkdir(path);
}
char *
Sys_GetCurrentDirectory(void)
{
static char dir[MAX_OSPATH];
if (!_getcwd(dir, sizeof(dir)))
{
Sys_Error("Couldn't get current working directory");
}
return dir;
}
char *
Sys_GetHomeDir(void)
{
char *old;
char *cur;
static char gdir[MAX_OSPATH];
TCHAR profile[MAX_OSPATH];
SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, 0, profile);
/* Replace backslashes by slashes */
cur = old = profile;
if (strstr(cur, "\\") != NULL)
{
while (cur != NULL)
{
if ((cur - old) > 1)
{
*cur = '/';
}
old = cur;
cur = strchr(old + 1, '\\');
}
}
snprintf(gdir, sizeof(gdir), "%s/%s/", profile, CFGDIR);
return gdir;
}
/* ======================================================================= */
/*
* Windows main function. Containts the
* initialization code and the main loop
*/
int WINAPI
WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
int time, oldtime, newtime;
char *cddir;
/* Previous instances do not exist in Win32 */
if (hPrevInstance)
{
return 0;
}
/* Make the current instance global */
global_hInstance = hInstance;
/* Seed PRNG */
randk_seed();
/* Parse the command line arguments */
ParseCommandLine(lpCmdLine);
/* Search the CD (for partial installations) */
cddir = Sys_ScanForCD();
if (cddir && (argc < MAX_NUM_ARGVS - 3))
{
int i;
/* don't override a cddir on the command line */
for (i = 0; i < argc; i++)
{
if (!strcmp(argv[i], "cddir"))
{
break;
}
}
if (i == argc)
{
argv[argc++] = "+set";
argv[argc++] = "cddir";
argv[argc++] = cddir;
}
}
/* Call the initialization code */
Qcommon_Init(argc, argv);
/* Save our time */
oldtime = Sys_Milliseconds();
/* The legendary main loop */
while (1)
{
/* If at a full screen console, don't update unless needed */
if (Minimized || (dedicated && dedicated->value))
{
Sleep(1);
}
while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
{
if (!GetMessage(&msg, NULL, 0, 0))
{
Com_Quit();
}
sys_msg_time = msg.time;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
do
{
newtime = Sys_Milliseconds();
time = newtime - oldtime;
}
while (time < 1);
_controlfp(_PC_24, _MCW_PC);
Qcommon_Frame(time);
oldtime = newtime;
}
/* never gets here */
return TRUE;
}

459
src/windows/vid.c Normal file
View file

@ -0,0 +1,459 @@
/*
* Copyright (C) 1997-2001 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.
*
* =======================================================================
*
* This is the "heart" of the id Tech 2 refresh engine. This file
* implements the main window in which Quake II is running. The window
* itself is created by the SDL backend, but here the refresh module is
* loaded, initialized and it's interaction with the operating system
* implemented. This code is also the interconnect between the input
* system (the mouse) and the keyboard system, both are here tied
* together with the refresher. The direct interaction between the
* refresher and those subsystems are the main cause for the very
* acurate and precise input controls of the id Tech 2.
*
* =======================================================================
*/
#include <assert.h>
#include <float.h>
#include "../common/header/common.h"
#include "header/winquake.h"
#include "../client/header/client.h"
/* Structure containing functions
* exported from refresh DLL */
refexport_t re;
/* Console variables that we need to access from this module */
cvar_t *vid_gamma;
cvar_t *vid_ref; /* Name of Refresh DLL loaded */
cvar_t *vid_xpos; /* X coordinate of window position */
cvar_t *vid_ypos; /* Y coordinate of window position */
cvar_t *vid_fullscreen;
/* Global variables used internally by this module */
viddef_t viddef; /* global video state; used by other modules */
HINSTANCE reflib_library; /* Handle to refresh DLL */
qboolean reflib_active = 0;
HWND cl_hwnd; /* Main window handle for life of program */
extern unsigned sys_msg_time;
in_state_t in_state;
typedef struct vidmode_s
{
const char *description;
int width, height;
int mode;
} vidmode_t;
void (*IN_Update_fp)(void);
void (*IN_KeyboardInit_fp)(Key_Event_fp_t fp);
void (*IN_Close_fp)(void);
void (*IN_BackendInit_fp)(in_state_t *in_state_p);
void (*IN_BackendShutdown_fp)(void);
void (*IN_BackendMouseButtons_fp)(void);
void (*IN_BackendMove_fp)(usercmd_t *cmd);
#define VID_NUM_MODES (sizeof(vid_modes) / sizeof(vid_modes[0]))
#define MAXPRINTMSG 4096
/* ========================================================================== */
void
Do_Key_Event(int key, qboolean down)
{
Key_Event(key, down, Sys_Milliseconds());
}
/* ========================================================================== */
void
VID_Printf(int print_level, char *fmt, ...)
{
va_list argptr;
char msg[MAXPRINTMSG];
va_start(argptr, fmt);
vsprintf(msg, fmt, argptr);
va_end(argptr);
if (print_level == PRINT_ALL)
{
Com_Printf("%s", msg);
}
else if (print_level == PRINT_DEVELOPER)
{
Com_DPrintf("%s", msg);
}
else if (print_level == PRINT_ALERT)
{
MessageBox(0, msg, "PRINT_ALERT", MB_ICONWARNING);
OutputDebugString(msg);
}
}
void
VID_Error(int err_level, char *fmt, ...)
{
va_list argptr;
char msg[MAXPRINTMSG];
va_start(argptr, fmt);
vsprintf(msg, fmt, argptr);
va_end(argptr);
Com_Error(err_level, "%s", msg);
}
/* ========================================================================== */
/*
* Console command to re-start the video mode and refresh DLL. We do this
* simply by setting the modified flag for the vid_ref variable, which will
* cause the entire video mode and refresh DLL to be reset on the next frame.
*/
void
VID_Restart_f(void)
{
vid_ref->modified = true;
}
void
VID_Front_f(void)
{
SetWindowLong(cl_hwnd, GWL_EXSTYLE, WS_EX_TOPMOST);
SetForegroundWindow(cl_hwnd);
}
/* This must be the same as in menu.c! */
vidmode_t vid_modes[] = {
{"Mode 0: 320x240", 320, 240, 0},
{"Mode 1: 400x300", 400, 300, 1},
{"Mode 2: 512x384", 512, 384, 2},
{"Mode 3: 640x400", 640, 400, 3},
{"Mode 4: 640x480", 640, 480, 4},
{"Mode 5: 800x500", 800, 500, 5},
{"Mode 6: 800x600", 800, 600, 6},
{"Mode 7: 960x720", 960, 720, 7},
{"Mode 8: 1024x480", 1024, 480, 8},
{"Mode 9: 1024x640", 1024, 640, 9},
{"Mode 10: 1024x768", 1024, 768, 10},
{"Mode 11: 1152x768", 1152, 768, 11},
{"Mode 12: 1152x864", 1152, 864, 12},
{"Mode 13: 1280x800", 1280, 800, 13},
{"Mode 14: 1280x854", 1280, 854, 14},
{"Mode 15: 1280x960", 1280, 860, 15},
{"Mode 16: 1280x1024", 1280, 1024, 16},
{"Mode 17: 1440x900", 1440, 900, 17},
{"Mode 18: 1600x1200", 1600, 1200, 18},
{"Mode 19: 1680x1050", 1680, 1050, 19},
{"Mode 20: 1920x1080", 1920, 1080, 20},
{"Mode 21: 1920x1200", 1920, 1200, 21},
{"Mode 22: 2048x1536", 2048, 1536, 22},
};
qboolean
VID_GetModeInfo(int *width, int *height, int mode)
{
if ((mode < 0) || (mode >= VID_NUM_MODES))
{
return false;
}
*width = vid_modes[mode].width;
*height = vid_modes[mode].height;
return true;
}
void
VID_UpdateWindowPosAndSize(int x, int y)
{
RECT r;
int style;
int w, h;
r.left = 0;
r.top = 0;
r.right = viddef.width;
r.bottom = viddef.height;
style = GetWindowLong(cl_hwnd, GWL_STYLE);
AdjustWindowRect(&r, style, FALSE);
w = r.right - r.left;
h = r.bottom - r.top;
MoveWindow(cl_hwnd, vid_xpos->value, vid_ypos->value, w, h, TRUE);
}
void
VID_NewWindow(int width, int height)
{
viddef.width = width;
viddef.height = height;
cl.force_refdef = true; /* can't use a paused refdef */
}
void
VID_FreeReflib(void)
{
if (reflib_library)
{
if (IN_Close_fp)
{
IN_Close_fp();
}
if (IN_BackendShutdown_fp)
{
IN_BackendShutdown_fp();
}
}
if (!FreeLibrary(reflib_library))
{
Com_Error(ERR_FATAL, "Reflib FreeLibrary failed");
}
IN_KeyboardInit_fp = NULL;
IN_Update_fp = NULL;
IN_Close_fp = NULL;
IN_BackendInit_fp = NULL;
IN_BackendShutdown_fp = NULL;
IN_BackendMouseButtons_fp = NULL;
IN_BackendMove_fp = NULL;
memset(&re, 0, sizeof(re));
reflib_library = NULL;
reflib_active = false;
}
qboolean
VID_LoadRefresh(char *name)
{
refimport_t ri;
R_GetRefAPI_t GetRefAPI;
if (reflib_active)
{
if (IN_Close_fp)
{
IN_Close_fp();
}
if (IN_BackendShutdown_fp)
{
IN_BackendShutdown_fp();
}
IN_Close_fp = NULL;
IN_BackendShutdown_fp = NULL;
re.Shutdown();
VID_FreeReflib();
}
Com_Printf("------- Loading %s -------\n", name);
if ((reflib_library = LoadLibrary(name)) == 0)
{
Com_Printf("LoadLibrary(\"%s\") failed\n", name);
return false;
}
ri.Cmd_AddCommand = Cmd_AddCommand;
ri.Cmd_RemoveCommand = Cmd_RemoveCommand;
ri.Cmd_Argc = Cmd_Argc;
ri.Cmd_Argv = Cmd_Argv;
ri.Cmd_ExecuteText = Cbuf_ExecuteText;
ri.Con_Printf = VID_Printf;
ri.Sys_Error = VID_Error;
ri.Sys_Mkdir = Sys_Mkdir;
ri.FS_LoadFile = FS_LoadFile;
ri.FS_FreeFile = FS_FreeFile;
ri.FS_Gamedir = FS_Gamedir;
ri.Cvar_Get = Cvar_Get;
ri.Cvar_Set = Cvar_Set;
ri.Cvar_SetValue = Cvar_SetValue;
ri.Vid_GetModeInfo = VID_GetModeInfo;
ri.Vid_MenuInit = VID_MenuInit;
ri.Vid_NewWindow = VID_NewWindow;
if ((GetRefAPI = (void *)GetProcAddress(reflib_library, "R_GetRefAPI")) == 0)
{
Com_Error(ERR_FATAL, "GetProcAddress failed on %s", name);
}
re = GetRefAPI(ri);
if (re.api_version != API_VERSION)
{
VID_FreeReflib();
Com_Error(ERR_FATAL, "%s has incompatible api_version", name);
}
/* Init IN (Mouse) */
in_state.IN_CenterView_fp = IN_CenterView;
in_state.Key_Event_fp = Do_Key_Event;
in_state.viewangles = cl.viewangles;
in_state.in_strafe_state = &in_strafe.state;
in_state.in_speed_state = &in_speed.state;
if (((IN_BackendInit_fp = (void *)GetProcAddress(reflib_library, "IN_BackendInit")) == NULL) ||
((IN_BackendShutdown_fp = (void *)GetProcAddress(reflib_library, "IN_BackendShutdown")) == NULL) ||
((IN_BackendMouseButtons_fp = (void *)GetProcAddress(reflib_library, "IN_BackendMouseButtons")) == NULL) ||
((IN_BackendMove_fp = (void *)GetProcAddress(reflib_library, "IN_BackendMove")) == NULL))
{
Com_Error(ERR_FATAL, "No input backend init functions in REF.\n");
}
if (IN_BackendInit_fp)
{
IN_BackendInit_fp( &in_state );
}
if (re.Init(global_hInstance, 0) == -1)
{
re.Shutdown();
Com_Error(ERR_FATAL, "re.Init() failed");
VID_FreeReflib();
return false;
}
/* Init IN (Keyboard) */
if (((IN_KeyboardInit_fp = (void *)GetProcAddress(reflib_library, "IN_KeyboardInit")) == NULL) ||
((IN_Update_fp = (void *)GetProcAddress(reflib_library, "IN_Update")) == NULL) ||
((IN_Close_fp = (void *)GetProcAddress(reflib_library, "IN_Close")) == NULL))
{
Com_Error(ERR_FATAL, "No keyboard input functions in REF.\n");
}
IN_KeyboardInit_fp(Do_Key_Event);
Key_ClearStates();
Com_Printf("------------------------------------\n");
reflib_active = true;
return true;
}
/*
* This function gets called once just before drawing each frame, and it's sole purpose in life
* is to check to see if any of the video mode parameters have changed, and if they have to
* update the rendering DLL and/or video mode to match.
*/
void
VID_CheckChanges(void)
{
char name[100];
if (vid_ref->modified)
{
cl.force_refdef = true; /* can't use a paused refdef */
S_StopAllSounds();
}
while (vid_ref->modified)
{
/* refresh has changed */
vid_ref->modified = false;
vid_fullscreen->modified = true;
cl.refresh_prepped = false;
cls.disable_screen = true;
Com_sprintf(name, sizeof(name), "ref_%s.dll", vid_ref->string);
if (!VID_LoadRefresh(name))
{
Cvar_Set("vid_ref", "gl");
}
cls.disable_screen = false;
}
}
void
VID_Init(void)
{
/* Create the video variables so we know how to start the graphics drivers */
vid_ref = Cvar_Get("vid_ref", "gl", CVAR_ARCHIVE);
vid_xpos = Cvar_Get("vid_xpos", "3", CVAR_ARCHIVE);
vid_ypos = Cvar_Get("vid_ypos", "22", CVAR_ARCHIVE);
vid_fullscreen = Cvar_Get("vid_fullscreen", "0", CVAR_ARCHIVE);
vid_gamma = Cvar_Get("vid_gamma", "1", CVAR_ARCHIVE);
/* Add some console commands that we want to handle */
Cmd_AddCommand("vid_restart", VID_Restart_f);
Cmd_AddCommand("vid_front", VID_Front_f);
/* Start the graphics mode and load refresh DLL */
VID_CheckChanges();
}
void
VID_Shutdown(void)
{
if (reflib_active)
{
re.Shutdown();
VID_FreeReflib();
}
}
qboolean
VID_CheckRefExists(const char *ref)
{
return true;
}
/* ========================================================================== */
void
IN_Move(usercmd_t *cmd)
{
if (IN_BackendMove_fp)
{
IN_BackendMove_fp(cmd);
}
}
void
IN_Shutdown(void)
{
if (IN_BackendShutdown_fp)
{
IN_BackendShutdown_fp();
}
}
void
IN_Commands(void)
{
if (IN_BackendMouseButtons_fp)
{
IN_BackendMouseButtons_fp();
}
}

BIN
stuff/icon/Quake2.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

View file

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

1
stuff/icon/icon.rc Normal file
View file

@ -0,0 +1 @@
id ICON "stuff/icon/Quake2.ico"

BIN
stuff/misc/mkdir.exe Normal file

Binary file not shown.

912
stuff/misc/uncrustify.cfg Normal file
View file

@ -0,0 +1,912 @@
#
# General options
#
# The type of line endings
newlines = lf # auto/lf/crlf/cr
# The original size of tabs in the input
input_tab_size = 4 # number
# The size of tabs in the output (only used if align_with_tabs=true)
output_tab_size = 4 # number
# The ascii value of the string escape char, usually 92 (\) or 94 (^). (Pawn)
string_escape_char = 92 # number
# Alternate string escape char for Pawn. Only works right before the quote char.
string_escape_char2 = 0 # number
#
# Indenting
#
# The number of columns to indent per level.
# Usually 2, 3, 4, or 8.
indent_columns = 4 # number
# How to use tabs when indenting code
# 0=spaces only
# 1=indent with tabs, align with spaces
# 2=indent and align with tabs
indent_with_tabs = 2 # number
# Whether to indent strings broken by '\' so that they line up
indent_align_string = true # false/true
# The number of spaces to indent multi-line XML strings.
# Requires indent_align_string=True
indent_xml_string = 0 # number
# Spaces to indent '{' from level
indent_brace = 0 # number
# Whether braces are indented to the body level
indent_braces = false # false/true
# Disabled indenting function braces if indent_braces is true
indent_braces_no_func = false # false/true
# Indent based on the size of the brace parent, ie 'if' => 3 spaces, 'for' => 4 spaces, etc.
indent_brace_parent = false # false/true
# Whether the 'namespace' body is indented
indent_namespace = true # false/true
# Whether the 'class' body is indented
indent_class = true # false/true
# Whether to indent the stuff after a leading class colon
indent_class_colon = false # false/true
# True: indent continued function call parameters one indent level
# False: align parameters under the open paren
indent_func_call_param = true # false/true
# Same as indent_func_call_param, but for function defs
indent_func_def_param = true # false/true
# Same as indent_func_call_param, but for function protos
indent_func_proto_param = true # false/true
# Same as indent_func_call_param, but for class declarations
indent_func_class_param = true # false/true
# Same as indent_func_call_param, but for class variable constructors
indent_func_ctor_var_param = true # false/true
# Double the indent for indent_func_xxx_param options
indent_func_param_double = true # false/true
# The number of spaces to indent a continued '->' or '.'
# Usually set to 0, 1, or indent_columns.
indent_member = 4 # number
# Spaces to indent single line ('//') comments on lines before code
indent_sing_line_comments = 0 # number
# Spaces to indent 'case' from 'switch'
# Usually 0 or indent_columns.
indent_switch_case = 4 # number
# Spaces to shift the 'case' line, without affecting any other lines
# Usually 0.
indent_case_shift = 0 # number
# Spaces to indent '{' from 'case'.
# By default, the brace will appear under the 'c' in case.
# Usually set to 0 or indent_columns.
indent_case_brace = 0 # number
# Whether to indent comments found in first column
indent_col1_comment = false # false/true
# How to indent goto labels
# >0 : absolute column where 1 is the leftmost column
# <=0 : subtract from brace indent
indent_label = -4 # number
# Same as indent_label, but for access specifiers that are followed by a colon
indent_access_spec = -4 # number
# If an open paren is followed by a newline, indent the next line so that it lines up after the open paren (not recommended)
indent_paren_nl = false # false/true
# Controls the indent of a close paren after a newline.
# 0: Indent to body level
# 1: Align under the open paren
# 2: Indent to the brace level
indent_paren_close = 0 # number
# Controls the indent of a comma when inside a paren.If TRUE, aligns under the open paren
indent_comma_paren = false # false/true
# Controls the indent of a BOOL operator when inside a paren.If TRUE, aligns under the open paren
indent_bool_paren = false # false/true
# If an open square is followed by a newline, indent the next line so that it lines up after the open square (not recommended)
indent_square_nl = false # false/true
# Don't change the relative indent of ESQL/C 'EXEC SQL' bodies
indent_preserve_sql = false # false/true
#
# Spacing options
#
# Add or remove space around arithmetic operator '+', '-', '/', '*', etc
sp_arith = force # ignore/add/remove/force
# Add or remove space around assignment operator '=', '+=', etc
sp_assign = force # ignore/add/remove/force
# Add or remove space around boolean operators '&&' and '||'
sp_bool = force # ignore/add/remove/force
# Add or remove space around compare operator '<', '>', '==', etc
sp_compare = force # ignore/add/remove/force
# Add or remove space inside '(' and ')'
sp_inside_paren = remove # ignore/add/remove/force
# Add or remove space between nested parens
sp_paren_paren = remove # ignore/add/remove/force
# Whether to balance spaces inside nested parens
sp_balance_nested_parens = false # false/true
# Add or remove space between ')' and '{'
sp_paren_brace = force # ignore/add/remove/force
# Add or remove space before pointer star '*'
sp_before_ptr_star = force # ignore/add/remove/force
# Add or remove space between pointer stars '*'
sp_between_ptr_star = remove # ignore/add/remove/force
# Add or remove space after pointer star '*', if followed by a word.
sp_after_ptr_star = remove # ignore/add/remove/force
# Add or remove space before reference sign '&'
sp_before_byref = force # ignore/add/remove/force
# Add or remove space after reference sign '&', if followed by a word.
sp_after_byref = remove # ignore/add/remove/force
# Add or remove space before '<>'
sp_before_angle = remove # ignore/add/remove/force
# Add or remove space after '<>'
sp_after_angle = remove # ignore/add/remove/force
# Add or remove space between '<>' and '(' as found in 'new List<byte>();'
sp_angle_paren = force # ignore/add/remove/force
# Add or remove space between '<>' and a word as in 'List<byte> m;'
sp_angle_word = force # ignore/add/remove/force
# Add or remove space before '(' of 'if', 'for', 'switch', and 'while'
sp_before_sparen = force # ignore/add/remove/force
# Add or remove space inside if-condition '(' and ')'
sp_inside_sparen = remove # ignore/add/remove/force
# Add or remove space after ')' of 'if', 'for', 'switch', and 'while'
sp_after_sparen = remove # ignore/add/remove/force
# Add or remove space between ')' and '{' of 'if', 'for', 'switch', and 'while'
sp_sparen_brace = force # ignore/add/remove/force
# Add or remove space before empty statement ';' on 'if', 'for' and 'while'
sp_special_semi = force # ignore/add/remove/force
# Add or remove space before ';'
sp_before_semi = remove # ignore/add/remove/force
# Add or remove space before ';' in non-empty 'for' statements
sp_before_semi_for = remove # ignore/add/remove/force
# Add or remove space before a semicolon of an empty part of a for statment.
sp_before_semi_for_empty = add # ignore/add/remove/force
# Add or remove space after the final semicolon of an empty part of a for statment: for ( ; ; <here> ).
sp_after_semi_for_empty = add # ignore/add/remove/force
# Add or remove space before '[' (except '[]')
sp_before_square = remove # ignore/add/remove/force
# Add or remove space before '[]'
sp_before_squares = remove # ignore/add/remove/force
# Add or remove space inside '[' and ']'
sp_inside_square = remove # ignore/add/remove/force
# Add or remove space after ','
sp_after_comma = force # ignore/add/remove/force
# Add or remove space before ','
sp_before_comma = remove # ignore/add/remove/force
# Add or remove space between 'operator' and operator sign
sp_after_operator = force # ignore/add/remove/force
# Add or remove space after cast
sp_after_cast = remove # ignore/add/remove/force
# Add or remove spaces inside cast parens
sp_inside_paren_cast = remove # ignore/add/remove/force
# Add or remove space between 'sizeof' and '('
sp_sizeof_paren = remove # ignore/add/remove/force
# Add or remove space after the tag keyword (Pawn)
sp_after_tag = remove # ignore/add/remove/force
# Add or remove space inside enum '{' and '}'
sp_inside_braces_enum = remove # ignore/add/remove/force
# Add or remove space inside struct/union '{' and '}'
sp_inside_braces_struct = remove # ignore/add/remove/force
# Add or remove space inside '{' and '}'
sp_inside_braces = remove # ignore/add/remove/force
# Add or remove space inside '<' and '>'
sp_inside_angle = remove # ignore/add/remove/force
# Add or remove space between return type and function name
# A minimum of 1 is forced except for pointer return types.
sp_type_func = remove # ignore/add/remove/force
# Add or remove space between function name and '(' on function declaration
sp_func_proto_paren = remove # ignore/add/remove/force
# Add or remove space between function name and '(' on function definition
sp_func_def_paren = remove # ignore/add/remove/force
# Add or remove space inside empty function '()'
sp_inside_fparens = remove # ignore/add/remove/force
# Add or remove space inside function '(' and ')'
sp_inside_fparen = remove # ignore/add/remove/force
# Add or remove space between ']' and '(' when part of a function call.
sp_square_fparen = remove # ignore/add/remove/force
# Add or remove space between ')' and '{' of function
sp_fparen_brace = remove # ignore/add/remove/force
# Add or remove space between function name and '(' on function calls
sp_func_call_paren = remove # ignore/add/remove/force
# Add or remove space between a constructor/destructor and the open paren
sp_func_class_paren = remove # ignore/add/remove/force
# Add or remove space between 'return' and '('
sp_return_paren = remove # ignore/add/remove/force
# Add or remove space between '__attribute__' and '('
sp_attribute_paren = remove # ignore/add/remove/force
# Add or remove space between macro and value
sp_macro = remove # ignore/add/remove/force
# Add or remove space between macro function ')' and value
sp_macro_func = force # ignore/add/remove/force
# Add or remove space between 'else' and '{' if on the same line
sp_else_brace = force # ignore/add/remove/force
# Add or remove space between '}' and 'else' if on the same line
sp_brace_else = force # ignore/add/remove/force
# Add or remove space between 'catch' and '{' if on the same line
sp_catch_brace = force # ignore/add/remove/force
# Add or remove space between '}' and 'catch' if on the same line
sp_brace_catch = force # ignore/add/remove/force
# Add or remove space between 'finally' and '{' if on the same line
sp_finally_brace = force # ignore/add/remove/force
# Add or remove space between '}' and 'finally' if on the same line
sp_brace_finally = force # ignore/add/remove/force
# Add or remove space between 'try' and '{' if on the same line
sp_try_brace = force # ignore/add/remove/force
# Add or remove space between get/set and '{' if on the same line
sp_getset_brace = force # ignore/add/remove/force
# Add or remove space before the '::' operator
sp_before_dc = remove # ignore/add/remove/force
# Add or remove space after the '::' operator
sp_after_dc = remove # ignore/add/remove/force
# Add or remove around the D named array initializer ':' operator
sp_d_array_colon = remove # ignore/add/remove/force
# Add or remove space after the '!' (not) operator.
sp_not = remove # ignore/add/remove/force
# Add or remove space after the '~' (invert) operator.
sp_inv = remove # ignore/add/remove/force
# Add or remove space after the '&' (address-of) operator.
# This does not affect the spacing after a '&' that is part of a type.
sp_addr = remove # ignore/add/remove/force
# Add or remove space around the '.' or '->' operators
sp_member = remove # ignore/add/remove/force
# Add or remove space after the '*' (dereference) operator.
# This does not affect the spacing after a '*' that is part of a type.
sp_deref = remove # ignore/add/remove/force
# Add or remove space after '+' or '-', as in 'x = -5' or 'y = +7'
sp_sign = remove # ignore/add/remove/force
# Add or remove space before or after '++' and '--', as in '(--x)' or 'y++;'
sp_incdec = remove # ignore/add/remove/force
# Add or remove space after the scope '+' or '-', as in '-(void) foo;' or '+(int) bar;'
sp_after_oc_scope = remove # ignore/add/remove/force
# Add or remove space after the colon in message specs
# '-(int) f: (int) x;' vs '+(int) f : (int) x;'
sp_before_oc_colon = force # ignore/add/remove/force
# Add or remove space after the (type) in message specs
# '-(int) f: (int) x;' vs '+(int)f : (int)x;'
sp_after_oc_type = remove # ignore/add/remove/force
#
# Code alignment (not left column spaces/tabs)
#
# Whether to keep non-indenting tabs
align_keep_tabs = false # false/true
# Whether to use tabs for alinging
align_with_tabs = true # false/true
# Whether to bump out to the next tab when aligning
align_on_tabstop = false # false/true
# Whether to left-align numbers
align_number_left = false # false/true
# Align variable definitions in prototypes and functions
align_func_params = false # false/true
# The span for aligning variable definitions (0=don't align)
align_var_def_span = 0 # number
# How to align the star in variable definitions.
# 0=Part of the type
# 1=Part of the variable
# 2=Dangling
align_var_def_star_style = 0 # number
# How to align the '&' in variable definitions.
# 0=Part of the type
# 1=Part of the variable
# 2=Dangling
align_var_def_amp_style = 0 # number
# The threshold for aligning variable definitions (0=no limit)
align_var_def_thresh = 100 # number
# Whether to align the colon in struct bit fields
align_var_def_colon = true # false/true
# Whether to align inline struct/enum/union variable definitions
align_var_def_inline = true # false/true
# The span for aligning on '=' in assignments (0=don't align)
align_assign_span = 0 # number
# The threshold for aligning on '=' in assignments (0=no limit)
align_assign_thresh = 0 # number
# The span for aligning on '=' in enums (0=don't align)
align_enum_equ_span = 0 # number
# The threshold for aligning on '=' in enums (0=no limit)
align_enum_equ_thresh = 0 # number
# The span for aligning struct/union (0=don't align)
align_var_struct_span = 0 # number
# The threshold for aligning struct/union member definitions (0=no limit)
align_var_struct_thresh = 0 # number
# The span for aligning struct initializer values (0=don't align)
align_struct_init_span = 0 # number
# The minimum space between the type and the synonym of a typedef
align_typedef_gap = 0 # number
# The span for aligning single-line typedefs (0=don't align)
align_typedef_span = 0 # number
# How to align typedef'd functions with other typedefs
# 0: Don't mix them at all
# 1: align the open paren with the types
# 2: align the function type name with the other type names
align_typedef_func = 0 # number
# Controls the positioning of the '*' in typedefs. Just try it.
# 0: Align on typdef type, ignore '*'
# 1: The '*' is part of type name: typedef int *pint;
# 2: The '*' is part of the type, but dangling: typedef int *pint;
align_typedef_star_style = 0 # number
# Controls the positioning of the '&' in typedefs. Just try it.
# 0: Align on typdef type, ignore '&'
# 1: The '&' is part of type name: typedef int &pint;
# 2: The '&' is part of the type, but dangling: typedef int &pint;
align_typedef_amp_style = 0 # number
# The span for aligning comments that end lines (0=don't align)
align_right_cmt_span = 0 # number
# If aligning comments, mix with comments after '}' and #endif with less than 3 spaces before the comment
align_right_cmt_mix = false # false/true
# The span for aligning function prototypes (0=don't align)
align_func_proto_span = 0 # number
# The span for aligning function prototypes (0=don't align)
align_oc_msg_spec_span = 0 # number
# Whether to align macros wrapped with a backslash and a newline.
# This will not work right if the macro contains a multi-line comment.
align_nl_cont = false # false/true
# The minimum space between label and value of a preprocessor define
align_pp_define_gap = 0 # number
# The span for aligning on '#define' bodies (0=don't align)
align_pp_define_span = 0 # number
#
# Newline adding and removing options
#
# Whether to collapse empty blocks between '{' and '}'
nl_collapse_empty_body = false # false/true
# Don't split one-line braced assignments - 'foo_t f = { 1, 2 };'
nl_assign_leave_one_liners = true # false/true
# Don't split one-line braced statements inside a class xx { } body
nl_class_leave_one_liners = false # false/true
# Don't split one-line enums: 'enum foo { BAR = 15 };'
nl_enum_leave_one_liners = true # false/true
# Don't split one-line get or set functions
nl_getset_leave_one_liners = true # false/true
# Don't split one-line function definitions - 'int foo() { return 0; }'
nl_func_leave_one_liners = true # false/true
# Don't split one-line if/else statements - 'if(a) b++;'
nl_if_leave_one_liners = false # false/true
# Add or remove newlines at the start of the file
nl_start_of_file = remove # ignore/add/remove/force
# The number of newlines at the start of the file (only used if nl_start_of_file is 'add' or 'force'
nl_start_of_file_min = 0 # number
# Add or remove newline at the end of the file
nl_end_of_file = add # ignore/add/remove/force
# The number of newlines at the end of the file (only used if nl_end_of_file is 'add' or 'force')
nl_end_of_file_min = 1 # number
# Add or remove newline between '=' and '{'
nl_assign_brace = remove # ignore/add/remove/force
# Add or remove newline between '=' and '[' (D only)
nl_assign_square = ignore # ignore/add/remove/force
# Add or remove newline after '= [' (D only). Will also affect the newline before the ']'
nl_after_square_assign = ignore # ignore/add/remove/force
# The number of newlines after a block of variable definitions
nl_func_var_def_blk = 1 # number
# Add or remove newline between a function call's ')' and '{', as in:
# list_for_each(item, &list) { }
nl_fcall_brace = add # ignore/add/remove/force
# Add or remove newline between 'enum' and '{'
nl_enum_brace = add # ignore/add/remove/force
# Add or remove newline between 'struct and '{'
nl_struct_brace = add # ignore/add/remove/force
# Add or remove newline between 'union' and '{'
nl_union_brace = add # ignore/add/remove/force
# Add or remove newline between 'if' and '{'
nl_if_brace = add # ignore/add/remove/force
# Add or remove newline between '}' and 'else'
nl_brace_else = add # ignore/add/remove/force
# Add or remove newline between 'else if' and '{'
# If set to ignore, nl_if_brace is used instead
nl_elseif_brace = add # ignore/add/remove/force
# Add or remove newline between 'else' and '{'
nl_else_brace = add # ignore/add/remove/force
# Add or remove newline between '}' and 'finally'
nl_brace_finally = add # ignore/add/remove/force
# Add or remove newline between 'finally' and '{'
nl_finally_brace = add # ignore/add/remove/force
# Add or remove newline between 'try' and '{'
nl_try_brace = add # ignore/add/remove/force
# Add or remove newline between get/set and '{'
nl_getset_brace = add # ignore/add/remove/force
# Add or remove newline between 'for' and '{'
nl_for_brace = add # ignore/add/remove/force
# Add or remove newline between 'catch' and '{'
nl_catch_brace = add # ignore/add/remove/force
# Add or remove newline between '}' and 'catch'
nl_brace_catch = add # ignore/add/remove/force
# Add or remove newline between 'while' and '{'
nl_while_brace = add # ignore/add/remove/force
# Add or remove newline between 'do' and '{'
nl_do_brace = add # ignore/add/remove/force
# Add or remove newline between '}' and 'while' of 'do' statement
nl_brace_while = add # ignore/add/remove/force
# Add or remove newline between 'switch' and '{'
nl_switch_brace = add # ignore/add/remove/force
# Add or remove newline when condition spans two or more lines
nl_multi_line_cond = true # false/true
# Force a newline in a define after the macro name for multi-line defines.
nl_multi_line_define = true # false/true
# Whether to put a newline before 'case' statement
nl_before_case = false # false/true
# Whether to put a newline after 'case' statement
nl_after_case = true # false/true
# Newline between namespace and {
nl_namespace_brace = add # ignore/add/remove/force
# Add or remove newline between 'template<>' and 'class'
nl_template_class = add # ignore/add/remove/force
# Add or remove newline between 'class' and '{'
nl_class_brace = add # ignore/add/remove/force
# Add or remove newline after each ',' in the constructor member initialization
nl_class_init_args = remove # ignore/add/remove/force
# Add or remove newline between return type and function name in definition
nl_func_type_name = add # ignore/add/remove/force
# Add or remove newline between return type and function name in a prototype
nl_func_proto_type_name = remove # ignore/add/remove/force
# Add or remove newline between a function name and the opening '('
nl_func_paren = remove # ignore/add/remove/force
# Add or remove newline after '(' in a function declaration
nl_func_decl_start = remove # ignore/add/remove/force
# Add or remove newline after each ',' in a function declaration
nl_func_decl_args = remove # ignore/add/remove/force
# Add or remove newline before the ')' in a function declaration
nl_func_decl_end = remove # ignore/add/remove/force
# Add or remove newline between function signature and '{'
nl_fdef_brace = add # ignore/add/remove/force
# Whether to put a newline after 'return' statement
nl_after_return = false # false/true
# Whether to put a newline after semicolons, except in 'for' statements
nl_after_semicolon = true # false/true
# Whether to put a newline after brace open.
# This also adds a newline before the matching brace close.
nl_after_brace_open = false # false/true
# If nl_after_brace_open and nl_after_brace_open_cmt are true, a newline is
# placed between the open brace and a trailing single-line comment.
nl_after_brace_open_cmt = false # false/true
# Whether to put a newline after a virtual brace open.
# These occur in un-braced if/while/do/for statement bodies.
nl_after_vbrace_open = false # false/true
# Whether to alter newlines in '#define' macros
nl_define_macro = true # false/true
# Whether to not put blanks after '#ifxx', '#elxx', or before '#endif'
nl_squeeze_ifdef = false # false/true
# Add or remove newline before 'if'
nl_before_if = add # ignore/add/remove/force
# Add or remove newline after 'if'
nl_after_if = add # ignore/add/remove/force
# Add or remove newline before 'for'
nl_before_for = add # ignore/add/remove/force
# Add or remove newline after 'for'
nl_after_for = add # ignore/add/remove/force
# Add or remove newline before 'while'
nl_before_while = add # ignore/add/remove/force
# Add or remove newline after 'while'
nl_after_while = add # ignore/add/remove/force
# Add or remove newline before 'switch'
nl_before_switch = add # ignore/add/remove/force
# Add or remove newline after 'switch'
nl_after_switch = add # ignore/add/remove/force
# Add or remove newline before 'do'
nl_before_do = add # ignore/add/remove/force
# Add or remove newline after 'do'
nl_after_do = add # ignore/add/remove/force
# Whether to double-space commented-entries in struct/enum
nl_ds_struct_enum_cmt = false # false/true
# Whether to double-space before the close brace of a struct/union/enum
nl_ds_struct_enum_close_brace = false # false/true
# Add or remove a newline around a class colon.
# Related to pos_class_colon, nl_class_init_args, and pos_comma.
nl_class_colon = remove # ignore/add/remove/force
# Change simple unbraced if statements into a one-liner
# 'if(b)\n i++;' => 'if(b) i++;'
nl_create_if_one_liner = false # false/true
# Change simple unbraced for statements into a one-liner
# 'for (i=0;i<5;i++)\n foo(i);' => 'for (i=0;i<5;i++) foo(i);'
nl_create_for_one_liner = false # false/true
# Change simple unbraced while statements into a one-liner
# 'while (i<5)\n foo(i++);' => 'while (i<5) foo(i++);'
nl_create_while_one_liner = false # false/true
#
# Positioning options
#
# The position of boolean operators in wrapped expressions
pos_bool = trail # ignore/lead/trail
# The position of the comma in wrapped expressions
pos_comma = trail # ignore/lead/trail
# The position of the comma in the constructor initialization list
pos_class_comma = trail # ignore/lead/trail
# The position of colons between constructor and member initialization
pos_class_colon = trail # ignore/lead/trail
#
# Line Splitting options
#
# Try to limit code width to N number of columns
code_width = 80 # number
# Whether to fully split long 'for' statements at semi-colons
ls_for_split_full = true # false/true
# Whether to fully split long function protos/calls at commas
ls_func_split_full = true # false/true
#
# Blank line options
#
# The maximum consecutive newlines
nl_max = 2 # number
# The number of newlines after a function prototype, if followed by another function prototype
nl_after_func_proto = 1 # number
# The number of newlines after a function prototype, if not followed by another function prototype
nl_after_func_proto_group = 2 # number
# The number of newlines after '}' of a multi-line function body
nl_after_func_body = 2 # number
# The number of newlines after '}' of a single line function body
nl_after_func_body_one_liner = 1 # number
# The minimum number of newlines before a multi-line comment.
# Doesn't apply if after a brace open or another multi-line comment.
nl_before_block_comment = 2 # number
# The minimum number of newlines before a single-line C comment.
# Doesn't apply if after a brace open or other single-line C comments.
nl_before_c_comment = 0 # number
# The minimum number of newlines before a CPP comment.
# Doesn't apply if after a brace open or other CPP comments.
nl_before_cpp_comment = 0 # number
# Whether to force a newline after a mulit-line comment.
nl_after_multiline_comment = false # false/true
# The number of newlines before a 'private:', 'public:', 'protected:', 'signals:', or 'slots:' label.
# Will not change the newline count if after a brace open.
# 0 = No change.
nl_before_access_spec = 1 # number
# The number of newlines after a 'private:', 'public:', 'protected:', 'signals:', or 'slots:' label.
# 0 = No change.
nl_after_access_spec = 1 # number
# Whether to remove blank lines after '{'
eat_blanks_after_open_brace = true # false/true
# Whether to remove blank lines before '}'
eat_blanks_before_close_brace = true # false/true
#
# Code modifying options (non-whitespace)
#
# Add or remove braces on single-line 'do' statement
mod_full_brace_do = add # ignore/add/remove/force
# Add or remove braces on single-line 'for' statement
mod_full_brace_for = add # ignore/add/remove/force
# Add or remove braces on single-line function defintions. (Pawn)
mod_full_brace_function = add # ignore/add/remove/force
# Add or remove braces on single-line 'if' statement
mod_full_brace_if = add # ignore/add/remove/force
# Don't remove braces around statements that span N newlines
mod_full_brace_nl = 0 # number
# Add or remove braces on single-line 'while' statement
mod_full_brace_while = add # ignore/add/remove/force
# Add or remove unnecessary paren on 'return' statement
mod_paren_on_return = remove # ignore/add/remove/force
# Whether to change optional semicolons to real semicolons
mod_pawn_semicolon = false # false/true
# Add parens on 'while' and 'if' statement around bools
mod_full_paren_if_bool = true # false/true
# Whether to remove superfluous semicolons
mod_remove_extra_semicolon = true # false/true
# If a function body exceeds the specified number of newlines and doesn't have a comment after
# the close brace, a comment will be added.
mod_add_long_function_closebrace_comment = 0 # number
# If a switch body exceeds the specified number of newlines and doesn't have a comment after
# the close brace, a comment will be added.
mod_add_long_switch_closebrace_comment = 0 # number
# If TRUE, will sort consecutive single-line 'import' statements [Java, D]
mod_sort_import = false # false/true
# If TRUE, will sort consecutive single-line 'using' statements [C#]
mod_sort_using = false # false/true
# If TRUE, will sort consecutive single-line '#include' statements [C/C++] and '#import' statements [Obj-C]
# This is generally a bad idea, as it may break your code.
mod_sort_include = false # false/true
#
# Comment modifications
#
# Try to wrap comments at cmt_witdth columns
cmt_width = 0 # number
# Whether to group c-comments that look like they are in a block
cmt_c_group = false # false/true
# Whether to put an empty '/*' on the first line of the combined c-comment
cmt_c_nl_start = true # false/true
# Whether to put a newline before the closing '*/' of the combined c-comment
cmt_c_nl_end = true # false/true
# Whether to group cpp-comments that look like they are in a block
cmt_cpp_group = false # false/true
# Whether to put an empty '/*' on the first line of the combined cpp-comment
cmt_cpp_nl_start = false # false/true
# Whether to put a newline before the closing '*/' of the combined cpp-comment
cmt_cpp_nl_end = false # false/true
# Whether to change cpp-comments into c-comments
cmt_cpp_to_c = true # false/true
# Whether to put a star on subsequent comment lines
cmt_star_cont = true # false/true
# The number of spaces to insert at the start of subsequent comment lines
cmt_sp_before_star_cont = 0 # number
# The number of spaces to insert after the star on subsequent comment lines
cmt_sp_after_star_cont = 0 # number
# The filename that contains text to insert at the head of a file if the file doesn't start with a C/C++ comment.
# Will substitue $(filename) with the current file's name.
cmt_insert_file_header = "" # string
# The filename that contains text to insert before a function implementation if the function isn't preceeded with a C/C++ comment.
# Will substitue $(function) with the function name and $(javaparam) with the javadoc @param and @return stuff.
# Will also substitute $(fclass) with the class name: void CFoo::Bar() { ... }
cmt_insert_func_header = "" # string
# The filename that contains text to insert before a class if the class isn't preceeded with a C/C++ comment.
# Will substitue $(class) with the class name.
cmt_insert_class_header = "" # string
#
# Preprocessor options
#
# Control indent of preprocessors inside #if blocks at brace level 0
pp_indent = add # ignore/add/remove/force
# Whether to indent #if/#else/#endif at the brace level (true) or from column 1 (false)
pp_indent_at_level = false # false/true
# Add or remove space after # based on pp_level of #if blocks
pp_space = remove # ignore/add/remove/force
# Sets the number of spaces added with pp_space
pp_space_count = 0 # number
# The indent for #region and #endregion in C# and '#pragma region' in C/C++
pp_indent_region = 0 # number
# Whether to indent the code between #region and #endregion
pp_region_indent_code = false # false/true
# If pp_indent_at_level=true, sets the indent for #if, #else, and #endif when not at file-level
pp_indent_if = 0 # number
# Control whether to indent the code between #if, #else and #endif when not at file-level
pp_if_indent_code = false # false/true
# Whether to indent '#define' at the brace level (true) or from column 1 (false)
pp_define_at_level = false # false/true