Compare commits

..
Author SHA1 Message Date
Alug 0ac0f2bae2 forgor to remove this 2024-10-26 00:51:24 +02:00
Alug cee28c6166 refactor a bunch of crap and fix skyportals 2024-10-25 22:58:10 +02:00
Alug a6be267325 Add visplane portal creation functionality and use it to replace the skybox rendering.
https://git.do.srb2.org/STJr/SRB2/-/commit/264386f84257a47fe5480bb6300df02d039a2491
2024-10-25 22:58:05 +02:00
Alug 426740e0ac port srb2 software portal refactor 2024-10-25 22:57:43 +02:00
Alug 78c0f64135 dont pass skybox to r_setupframe
why was this even done?
neither srb2 nor v2/rr ever did this?
2024-10-25 22:57:38 +02:00
299 changed files with 52178 additions and 25727 deletions

No files matched your search

+1 -1
View File
@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.5)
cmake_minimum_required(VERSION 3.0)
# DO NOT CHANGE THIS SRB2 STRING! Some variable names depend on this string.
# Version change is fine.
project(SRB2
-9
View File
@@ -28,10 +28,6 @@ exist.
Returns the values of the given HUD item's `xoffset`/`yoffset` cvars.
Available for any HUD item with offset cvars.
## patch = v.cachePatchRotated(name, rollangle)
Like v.cachePatch, it caches a new patch with the corresponding name. Unlike v.cachePatch, however,
a rollangle can be supplied to the function so that it returns a rotated patch instead.
## x, y, flags = v.getDrawInfo(item)
Returns the X, Y and flags where the given HUD item will be drawn for the current displayplayer.
@@ -156,11 +152,6 @@ Add Gamepad Rumble support for things.
To be used with Displayplayers.
Duration is in milliseconds and is optional to set, default value is 84ms.
## P_CheckSightFast(mo1, mo2)
Exactly same as P_CheckSight but uses cheaper algorithm, useful for things like nametags. Doesn't work exactly
like P_CheckSight so don't use it for anything gameplay-related.
# Other changes
## P_PlayRinglossSound(source, damager)
-8
View File
@@ -1,8 +0,0 @@
ifdef SILENT
MAKEFLAGS+=--no-print-directory
endif
all :
% ::
@$(MAKE) -C src $(MAKECMDGOALS)
+1 -1
View File
@@ -76,7 +76,7 @@ Crashlogs now contain alot more informations. and even more if your build has de
Also allows 64bit Windows builds to produce Crashlogs!
## MISC
- Bird's Camera Tilting feature is no longer turned on by default
- Bird's Camara Tilting feature is no longer turned on by default
- Bird's warning on the title screen has been removed
## Bugs
+5
View File
@@ -1726,6 +1726,11 @@ HW3SOUND for 3D hardware sound support
<Option compilerVar="CC" />
</Unit>
<Unit filename="src/r_draw.h" />
<Unit filename="src/r_draw16.c">
<Option compilerVar="CC" />
<Option compile="0" />
<Option link="0" />
</Unit>
<Unit filename="src/r_draw8.c">
<Option compilerVar="CC" />
<Option compile="0" />
+10
View File
@@ -773,6 +773,16 @@ Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit79]
FileName=src\r_draw16.c
Folder=R_Rend
Compile=0
CompileCpp=0
Link=0
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit80]
FileName=src\r_draw8.c
Folder=R_Rend
+32 -32
View File
@@ -1,32 +1,32 @@
@echo off
set BRA=Unknown
set REV=illegal
copy nul: /b +%1\comptime.c tmp.$$$ > nul
move tmp.$$$ %1\comptime.c > nul
if exist .git goto gitrev
if exist ..\.git goto gitrev
if exist .svn goto svnrev
goto filwri
:gitrev
set GIT=%2
if "%GIT%"=="" set GIT=git
for /f "usebackq" %%s in (`%GIT% rev-parse --abbrev-ref HEAD`) do @set BRA=%%s
for /f "usebackq" %%s in (`%GIT% rev-parse HEAD`) do @set REV=%%s
set REV=%REV:~0,8%
goto filwri
:svnrev
set BRA=Subversion
for /f "usebackq" %%s in (`svnversion .`) do @set REV=%%s
set REV=r%REV%
goto filwri
:filwri
echo // Do not edit! This file was autogenerated > %1\comptime.h
echo // by the %0 batch file >> %1\comptime.h
echo // >> %1\comptime.h
echo const char* compbranch = "%BRA%"; >> %1\comptime.h
echo const char* comprevision = "%REV%"; >> %1\comptime.h
@echo off
set BRA=Unknown
set REV=illegal
copy nul: /b +%1\comptime.c tmp.$$$ > nul
move tmp.$$$ %1\comptime.c > nul
if exist .git goto gitrev
if exist ..\.git goto gitrev
if exist .svn goto svnrev
goto filwri
:gitrev
set GIT=%2
if "%GIT%"=="" set GIT=git
for /f "usebackq" %%s in (`%GIT% rev-parse --abbrev-ref HEAD`) do @set BRA=%%s
for /f "usebackq" %%s in (`%GIT% rev-parse HEAD`) do @set REV=%%s
set REV=%REV:~0,8%
goto filwri
:svnrev
set BRA=Subversion
for /f "usebackq" %%s in (`svnversion .`) do @set REV=%%s
set REV=r%REV%
goto filwri
:filwri
echo // Do not edit! This file was autogenerated > %1\comptime.h
echo // by the %0 batch file >> %1\comptime.h
echo // >> %1\comptime.h
echo const char* compbranch = "%BRA%"; >> %1\comptime.h
echo const char* comprevision = "%REV%"; >> %1\comptime.h
+1 -1
View File
@@ -17,7 +17,7 @@ EOF
versiongit() {
gitbranch="$(git rev-parse --abbrev-ref HEAD)"
gitversion="$(git show --pretty=format:'%h %s' -s HEAD | sed 's/"/\\"/g')"
gitversion="$(git rev-parse HEAD | cut -c -8)"
version "$gitbranch" "$gitversion";
exit 0
}
+8 -9
View File
@@ -1,5 +1,5 @@
/* backtrace.h -- Public header file for stack backtrace library.
Copyright (C) 2012-2024 Free Software Foundation, Inc.
Copyright (C) 2012-2020 Free Software Foundation, Inc.
Written by Ian Lance Taylor, Google.
Redistribution and use in source and binary forms, with or without
@@ -54,14 +54,13 @@ struct backtrace_state;
invalid after this function returns.
As a special case, the ERRNUM argument will be passed as -1 if no
debug info can be found for the executable, or if the debug info
exists but has an unsupported version, but the function requires
debug info (e.g., backtrace_full, backtrace_pcinfo). The MSG in
this case will be something along the lines of "no debug info".
Similarly, ERRNUM will be passed as -1 if there is no symbol table,
but the function requires a symbol table (e.g., backtrace_syminfo).
This may be used as a signal that some other approach should be
tried. */
debug info can be found for the executable, but the function
requires debug info (e.g., backtrace_full, backtrace_pcinfo). The
MSG in this case will be something along the lines of "no debug
info". Similarly, ERRNUM will be passed as -1 if there is no
symbol table, but the function requires a symbol table (e.g.,
backtrace_syminfo). This may be used as a signal that some other
approach should be tried. */
typedef void (*backtrace_error_callback) (void *data, const char *msg,
int errnum);
Binary file not shown.
+1 -2
View File
@@ -1,3 +1,2 @@
/cscope.out
*.json
*.idx
/srb2wii
+2 -10
View File
@@ -129,13 +129,11 @@ set(SRB2_CORE_RENDER_SOURCES
r_fps.c
r_main.c
r_patch.c
r_patchrotation.c
r_plane.c
r_segs.c
r_sky.c
r_splats.c
r_things.c
r_portal.c
r_bsp.h
r_data.h
@@ -144,15 +142,13 @@ set(SRB2_CORE_RENDER_SOURCES
r_fps.h
r_local.h
r_main.h
r_patch.h
r_patchrotation.h
r_patch
r_plane.h
r_segs.h
r_sky.h
r_splats.h
r_state.h
r_things.h
r_portal.h
)
set(SRB2_CORE_GAME_SOURCES
@@ -175,7 +171,6 @@ set(SRB2_CORE_GAME_SOURCES
p_user.c
k_director.c
k_kart.c
k_stats.c
i_time.c
p_local.h
@@ -190,7 +185,6 @@ set(SRB2_CORE_GAME_SOURCES
p_tick.h
k_director.h
k_kart.h
k_stats.h
)
if(NOT (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
@@ -476,7 +470,6 @@ if(${SRB2_CONFIG_HWRENDER})
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_clip.c
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_draw.c
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_main.c
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_portal.c
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md2.c
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md2load.c
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md3load.c
@@ -491,10 +484,9 @@ if(${SRB2_CONFIG_HWRENDER})
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_data.h
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_defs.h
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_dll.h
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_gl.h
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_drv.h
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_glob.h
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_main.h
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_portal.h
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md2.h
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md2load.h
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md3load.h
+130 -41
View File
@@ -31,6 +31,18 @@
# compile all HW render and 3D sound DLLs for the set
# opengl_dll
# Pure Mingw only, compile OpenGL HW render DLL
# minigl_dll
# Pure Mingw only, compile MiniGL HW render DLL
# ds3d_dll
# Pure Mingw only, compile DirectX DirectSound HW sound DLL
# fmod_dll
# Pure Mingw only, compile FMOD HW sound DLL
# openal_dll
# Pure Mingw only, compile OpenAL HW sound DLL
# fmod_so
# Non-Mingw, compile FMOD HW sound SO
# openal_so
# Non-Mingw, compile OpenAL HW sound SO
#
#
# Addon:
@@ -57,7 +69,10 @@
# Compile without SDL_Mixer, add 'NOMIXER=1'
# Compile without BSD API, add 'NONET=1'
# Compile without IPX/SPX, add 'NOIPX=1'
# Compile Mingw/SDL with S_DS3S, add 'DS3D=1'
# Compile without libopenmpt, add 'NOOPENMPT=1'
# Compile with S_FMOD3D, add 'FMOD=1' (WIP)
# Compile with S_OPENAL, add 'OPENAL=1' (WIP)
# To link with the whole SDL_Image lib to load Icons, add 'SDL_IMAGE=1' but it isn't not realy needed
# To link with SDLMain to hide console or make on a console-less binary, add 'SDLMAIN=1'
#
@@ -68,6 +83,7 @@ ALL_SYSTEMS=\
LINUX64\
MINGW64\
HAIKU\
DUMMY\
MINGW\
UNIX\
LINUX\
@@ -80,19 +96,18 @@ ALL_SYSTEMS=\
ifeq (,$(filter $(ALL_SYSTEMS),$(.VARIABLES)))
ifeq ($(OS),Windows_NT) # all windows are Windows_NT...
ifeq ($(shell uname -s | grep -o MINGW64),MINGW64) # 64-bit MinGW
$(info Detected a Windows system, compiling for 64-bit MinGW SDL2...)
MINGW64=1
else # 32-bit MinGW
$(info Detected a Windows system, compiling for 32-bit MinGW SDL2...)
MINGW=1
endif
$(info Detected a Windows system, compiling for 32-bit MinGW SDL2...)
# go for a 32-bit sdl mingw exe by default
MINGW=1
SDL=1
WINDOWSHELL=1
NOOBJDUMP=1
NOUPX=1
else # if you on the *nix
NOUPX=1
system:=$(shell uname -s)
ifeq ($(system),Linux)
@@ -116,7 +131,6 @@ else # if you on the *nix
endif
endif
NOUPX=1
# SRB2 data files
D_DIR?=../bin/Resources
@@ -157,6 +171,17 @@ endif
include Makefile.cfg
ifdef DUMMY
NOPNG=1
NOZLIB=1
NONET=1
NOHW=1
NOIPX=1
EXENAME?=srb2dummy
OBJS=$(OBJDIR)/i_video.o
LIBS=-lm
endif
ifdef HAIKU
NOIPX=1
ifndef NONET
@@ -183,6 +208,8 @@ endif
endif
ifndef NONET
ifndef NOSATURNSYNCH
DOSATURNSYNCH=1
ifndef NOSATURNJOIN
DOSATURNJOIN=1
endif
@@ -190,6 +217,7 @@ ifndef NOSATURNPAK
DOSATURNPAK=1
endif
endif
endif
ifdef MINGW
include win32/Makefile.cfg
@@ -201,7 +229,6 @@ endif
ifdef LINUX
UNIXCOMMON=1
NOOBJDUMP=1
ifndef NOGME
HAVE_LIBGME=1
endif
@@ -266,11 +293,11 @@ ifdef NOHW
else
OPTS+=-DHWRENDER
OBJS+=$(OBJDIR)/hw_bsp.o $(OBJDIR)/hw_draw.o \
$(OBJDIR)/hw_main.o $(OBJDIR)/hw_clip.o $(OBJDIR)/hw_md2.o $(OBJDIR)/hw_cache.o $(OBJDIR)/hw_portal.o\
$(OBJDIR)/hw_main.o $(OBJDIR)/hw_clip.o $(OBJDIR)/hw_md2.o $(OBJDIR)/hw_cache.o \
$(OBJDIR)/hw_md2load.o $(OBJDIR)/hw_md3load.o $(OBJDIR)/hw_model.o $(OBJDIR)/u_list.o $(OBJDIR)/hw_batching.o $(OBJDIR)/hw_shaders.o
endif
OPTS += -DCOMPVERSION
OPTS += -DCOMPVERSION -fwrapv
ifndef NONX86
ifndef GCC29
@@ -284,10 +311,6 @@ ifdef X86_64
endif
endif
# apparently MingW just completely ignores everything so just always force this shit
# FIXME: we should port our code to c24
CFLAGS+=-std=gnu17
CPPFLAGS+=-std=gnu17
ifndef NOPNG
OPTS+=-DHAVE_PNG
@@ -376,6 +399,8 @@ endif
endif
ifndef NONET
ifndef NOSATURNSYNCH
OPTS+=-DDOSATURNSYNCH
ifndef NOSATURNJOIN
OPTS+=-DDOSATURNJOIN
endif
@@ -383,6 +408,7 @@ ifndef NOSATURNPAK
OPTS+=-DDOSATURNPAK
endif
endif
endif
ifdef HAVE_MINIUPNPC
ifdef NONET
@@ -439,24 +465,7 @@ else
# build a normal optimised version
WINDRESFLAGS = -DNDEBUG
CFLAGS+=-O3
CPPFLAGS+=-O3
endif
ifndef DEBUGMODE
ifdef USELTO
# compile with LTO
CFLAGS+=-flto=auto
CPPFLAGS+=-flto=auto
endif
endif
ifdef USEASAN
# compile with asan
CFLAGS+=-fsanitize=address
CPPFLAGS+=-fsanitize=address
LDFLAGS+=-fsanitize=address
endif
CFLAGS+=-g $(OPTS) $(ARCHOPTS) $(WINDRESFLAGS)
ifdef PROFILEMODE
@@ -511,7 +520,6 @@ OBJS:=$(i_main_o) \
$(OBJDIR)/st_stuff.o \
$(OBJDIR)/k_director.o \
$(OBJDIR)/k_kart.o \
$(OBJDIR)/k_stats.o \
$(OBJDIR)/m_aatree.o \
$(OBJDIR)/m_anigif.o \
$(OBJDIR)/m_argv.o \
@@ -554,7 +562,6 @@ OBJS:=$(i_main_o) \
$(OBJDIR)/r_sky.o \
$(OBJDIR)/r_splats.o \
$(OBJDIR)/r_patch.o \
$(OBJDIR)/r_patchrotation.o \
$(OBJDIR)/r_things.o \
$(OBJDIR)/r_portal.o \
$(OBJDIR)/screen.o \
@@ -598,6 +605,10 @@ ifdef SDL
all: pre-build $(BIN)/$(EXENAME)
endif
ifdef DUMMY
all: $(BIN)/$(EXENAME)
endif
cleandep:
$(REMOVE) $(OBJDIR)/depend.dep
$(REMOVE) comptime.h
@@ -609,7 +620,7 @@ else
-$(.)../comptime.sh .
endif
clean: cleandep
clean:
$(REMOVE) *~ *.flc
$(REMOVE) $(OBJDIR)/*.o
@@ -679,7 +690,7 @@ else
dll : opengl_dll
endif
ifdef MINGW
all_dll: opengl_dll
all_dll: opengl_dll ds3d_dll fmod_dll openal_dll
opengl_dll: $(BIN)/r_opengl.dll
$(BIN)/r_opengl.dll: $(OBJDIR)/ogl_win.o $(OBJDIR)/r_opengl.o
@@ -689,24 +700,55 @@ $(BIN)/r_opengl.dll: $(OBJDIR)/ogl_win.o $(OBJDIR)/r_opengl.o
ifndef NOUPX
-$(UPX) $(UPX_OPTS) $@
endif
ds3d_dll: $(BIN)/s_ds3d.dll
$(BIN)/s_ds3d.dll: $(OBJDIR)/s_ds3d.o
@echo Linking S_DS3d.dll...
$(CC) --shared $^ -o $@ -g -Wl,--add-stdcall-alias -ldsound -luuid
fmod_dll: $(BIN)/s_fmod.dll
$(BIN)/s_fmod.dll: $(OBJDIR)/s_fmod.o
-$(MKDIR) $(BIN)
@echo Linking S_FMOD.dll...
$(CC) --shared $^ -o $@ -g -Wl,--add-stdcall-alias -lfmod
openal_dll: $(BIN)/s_openal.dll
$(BIN)/s_openal.dll: $(OBJDIR)/s_openal.o
-$(MKDIR) $(BIN)
@echo Linking S_OpenAL.dll...
$(CC) --shared $^ -o $@ -g -Wl,--add-stdcall-alias -lopenal32
else
all_dll: fmod_so openal_so
fmod_so: $(BIN)/s_fmod.so
$(BIN)/s_fmod.so: $(OBJDIR)/s_fmod.o
-$(MKDIR) $(BIN)
@echo Linking S_FMOD.so...
$(CC) --shared $^ -o $@ -g --nostartfiles -lm -lfmod
openal_so: $(BIN)/s_openal.so
$(BIN)/s_openal.so: $(OBJDIR)/s_openal.o
-$(MKDIR) $(BIN)
@echo Linking S_OpenAL.so...
$(CC) --shared $^ -o $@ -g --nostartfiles -lm -lopenal
endif
else
ifdef SDL
ifdef MINGW
$(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \
doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_gl.h screen.h \
doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \
command.h hardware/hw_data.h hardware/hw_defs.h hardware/hw_md2.h \
hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h hardware/hw_portal.h\
hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \
hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \
am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \
p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h
$(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@
else
$(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \
doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_gl.h screen.h \
doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \
command.h hardware/hw_data.h hardware/hw_defs.h hardware/hw_md2.h \
hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h hardware/hw_portal.h \
hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \
hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \
am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \
p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h
@@ -718,7 +760,9 @@ endif
#dependecy made by gcc itself !
$(OBJS):
ifndef DUMMY
-include $(OBJDIR)/depend.dep
endif
$(OBJDIR)/depend.dep:
@echo "Creating dependency file, depend.dep"
@@ -772,10 +816,55 @@ $(OBJDIR)/SRB2.res: win32/Srb2win.rc win32/afxres.h win32/resource.h
$(WINDRES) -i $< -O rc $(WINDRESFLAGS) --include-dir=win32 -o $@ -O coff
ifdef SDL
ifdef MINGW
$(OBJDIR)/win_dbg.o: win32/win_dbg.c
$(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@
endif
ifdef STATICHS
$(OBJDIR)/s_openal.o: hardware/s_openal/s_openal.c hardware/hw3dsdrv.h \
hardware/hw_dll.h
$(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@
$(OBJDIR)/s_fmod.o: hardware/s_fmod/s_fmod.c hardware/hw3dsdrv.h \
hardware/hw_dll.h
$(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@
ifdef MINGW
$(OBJDIR)/s_ds3d.o: hardware/s_ds3d/s_ds3d.c hardware/hw3dsdrv.h \
hardware/hw_dll.h
$(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@
endif
else
$(OBJDIR)/s_fmod.o: hardware/s_fmod/s_fmod.c hardware/hw3dsdrv.h \
hardware/hw_dll.h
$(CC) $(ARCHOPTS) -Os -o $(OBJDIR)/s_fmod.o -DHW3SOUND -DUNIXCOMMON -shared -nostartfiles -c hardware/s_fmod/s_fmod.c
$(OBJDIR)/s_openal.o: hardware/s_openal/s_openal.c hardware/hw3dsdrv.h \
hardware/hw_dll.h
$(CC) $(ARCHOPTS) -Os -o $(OBJDIR)/s_openal.o -DHW3SOUND -DUNIXCOMMON -shared -nostartfiles -c hardware/s_openal/s_openal.c
endif
ifdef FILTERS
$(OBJDIR)/%.o: $(INTERFACE)/filter/%.c
@echo $< needs deps
$(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@
$(OBJDIR)/filters.o: $(INTERFACE)/filter/filters.c $(INTERFACE)/filter/filters.c \
$(INTERFACE)/filter/filters.h
$(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@
$(OBJDIR)/hq2x.o: $(INTERFACE)/filter/hq2x.c $(INTERFACE)/filter/hq2x.c \
$(INTERFACE)/filter/filters.h
$(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@
$(OBJDIR)/lq2x.o: $(INTERFACE)/filter/lq2x.c $(INTERFACE)/filter/lq2x.c \
$(INTERFACE)/filter/filters.h $(INTERFACE)/filter/interp.h \
$(INTERFACE)/filter/hq2x.h $(INTERFACE)/filter/lq2x.h
$(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@
endif
endif
#############################################################
+11 -13
View File
@@ -12,7 +12,6 @@
# to avoid a false positive with the version detection...
SUPPORTED_GCC_VERSIONS:=\
151 150 15\
142 141 140 14\
132 131 130 13\
123 122 121 120 12\
@@ -79,18 +78,6 @@ ifeq (,$(filter GCC%,$(.VARIABLES)))
endif
endif
ifdef GCC151
GCC150=1
endif
ifdef GCC15
GCC150=1
endif
ifdef GCC150
GCC142=1
endif
ifdef GCC142
GCC141=1
endif
@@ -482,6 +469,7 @@ ifdef GCC81
WFLAGS+=-Wno-error=multistatement-macros
endif
#indicate platform and what interface use with
ifndef LINUX
ifndef FREEBSD
@@ -489,6 +477,7 @@ ifndef CYGWIN32
ifndef MINGW
ifndef MINGW64
ifndef SDL
ifndef DUMMY
$(error No interface or platform flag defined)
endif
endif
@@ -496,6 +485,7 @@ endif
endif
endif
endif
endif
#determine the interface directory (where you put all i_*.c)
i_net_o=$(OBJDIR)/i_net.o
@@ -520,6 +510,11 @@ UPX_OPTS+=-q
endif
#Interface Setup
ifdef DUMMY
INTERFACE=dummy
OBJDIR:=$(OBJDIR)/dummy
BIN:=$(BIN)/dummy
else
ifdef LINUX
SDL=1
ifdef LINUX64
@@ -566,6 +561,7 @@ endif
endif
endif
endif
endif
ifdef ARCHNAME
OBJDIR:=$(OBJDIR)/$(ARCHNAME)
@@ -580,6 +576,7 @@ ifdef SDL
OBJDIR:=$(OBJDIR)/SDL
endif
ifndef DUMMY
ifdef DEBUGMODE
OBJDIR:=$(OBJDIR)/Debug
BIN:=$(BIN)/Debug
@@ -587,3 +584,4 @@ else
OBJDIR:=$(OBJDIR)/Release
BIN:=$(BIN)/Release
endif
endif
+121 -465
View File
@@ -1,10 +1,8 @@
// SONIC ROBO BLAST 2 KART
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 2024 by Vivian "toastergrl" Grannell.
// Copyright (C) 2024 by Kart Krew.
// Copyright (C) 2020 by Sonic Team Junior.
// Copyright (C) 2000 by DooM Legacy Team.
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2018 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
@@ -35,31 +33,36 @@ static const UINT8 GRAYSRANGE = 16;
static const UINT8 BROWNS = (3*16);
static const UINT8 YELLOWS = (7*16);
static const UINT8 GREENS = (10*16);
//static const UINT8 CYANS = (13*16);
static const UINT8 BLUES = (14*16);
static const UINT8 DBLACK = 31;
static const UINT8 DWHITE = 0;
static const UINT8 NOCLIMBREDS = 248;
static const UINT8 NOCLIMBREDRANGE = 8;
static const UINT8 NOCLIMBGRAYS = 204;
static const UINT8 NOCLIMBBROWNS = (2*16);
static const UINT8 NOCLIMBYELLOWS = (11*16);
// Automap colors
#define BACKGROUND DBLACK
#define WALLCOLORS (REDS + REDRANGE/2)
#define WALLRANGE (REDRANGE/2)
#define NOCLIMBWALLCOLORS (NOCLIMBREDS + NOCLIMBREDRANGE/2)
#define NOCLIMBWALLRANGE (NOCLIMBREDRANGE/2)
#define THOKWALLCOLORS REDS
#define THOKWALLRANGE REDRANGE
#define TSWALLCOLORS DWHITE
#define TSFINISHLINE (GREENS + 2)
#define TSFOFINFO (BLUES + 4)
#define NOCLIMBTHOKWALLCOLORS NOCLIMBREDS
#define NOCLIMBTHOKWALLRANGE NOCLIMBREDRANGE
#define TSWALLCOLORS GRAYS
#define TSWALLRANGE GRAYSRANGE
#define NOCLIMBTSWALLCOLORS NOCLIMBGRAYS
#define FDWALLCOLORS BROWNS
#define NOCLIMBFDWALLCOLORS NOCLIMBBROWNS
#define CDWALLCOLORS YELLOWS
#define NOCLIMBCDWALLCOLORS NOCLIMBYELLOWS
#define THINGCOLORS GREENS
#define GRIDCOLORS (GRAYS + GRAYSRANGE/2)
#define XHAIRCOLORS GRAYS
// Automap passes
#define PASS_SOLID 1
#define PASS_INTANGIBLE 2
#define PASS_FOF 4
// controls
#define AM_PANUPKEY KEY_UPARROW
#define AM_PANDOWNKEY KEY_DOWNARROW
@@ -107,6 +110,11 @@ typedef struct
mpoint_t a, b;
} mline_t;
typedef struct
{
fixed_t slp, islp;
} islope_t;
//
// The vector graphics for the automap.
// A line drawing of the player pointing right,
@@ -128,14 +136,16 @@ static const mline_t player_arrow[] = {
#undef R
#define NUMPLYRLINES (sizeof (player_arrow)/sizeof (mline_t))
#if 0
#define R (FRACUNIT)
static const mline_t cross_mark[] =
{
{ { -R, 0 }, { R, 0} },
{ { 0, -R }, { 0, R } },
static mline_t triangle_guy[] = {
{ { (fixed_t)-.867f*R, (fixed_t)-.5f*R }, { (fixed_t) .867f*R, (fixed_t)-.5f*R } },
{ { (fixed_t) .867f*R, (fixed_t)-.5f*R }, { (fixed_t) 0, (fixed_t) R } },
{ { (fixed_t) 0, (fixed_t) R }, { (fixed_t)-.867f*R, (fixed_t)-.5f*R } }
};
#undef R
#define NUMCROSSMARKLINES (sizeof(cross_mark)/sizeof(mline_t))
#define NUMTRIANGLEGUYLINES (sizeof (triangle_guy)/sizeof (mline_t))
#endif
#define R (FRACUNIT)
static const mline_t thintriangle_guy[] = {
@@ -152,14 +162,10 @@ static boolean draw_grid = false;
boolean automapactive = false;
boolean am_recalc = false; //added : 05-02-98 : true when screen size changes
static boolean am_stopped = true;
static boolean am_minigen = false;
static UINT8 *am_buf = NULL;
static INT32 f_x, f_y; // location of window on screen (always zero for both)
static INT32 f_w, f_h; // size of window on screen (always the screen width and height respectively)
static boolean m_keydown[4]; // which window panning keys are being pressed down?
static mpoint_t m_paninc; // how far the window pans each tic (map coords)
static fixed_t mtof_zoommul; // how far the window zooms in each tic (map coords)
static fixed_t ftom_zoommul; // how far the window zooms in each tic (fb coords)
@@ -197,15 +203,14 @@ static fixed_t scale_mtof = (fixed_t)INITSCALEMTOF;
// used by FTOM to scale from frame-buffer-to-map coords (=1/scale_mtof)
static fixed_t scale_ftom;
static player_t *plr = NULL; // the player represented by an arrow
static player_t *plr; // the player represented by an arrow
static boolean followplayer = true; // specifies whether to follow the player around
static INT32 followplayer = true; // specifies whether to follow the player around
// function for drawing lines, depends on rendermode
typedef void (*AMDRAWFLINEFUNC) (const fline_t *fl, INT32 color);
static AMDRAWFLINEFUNC AM_drawFline;
static void AM_drawPixel(INT32 xx, INT32 yy, INT32 cc);
static void AM_drawFline_soft(const fline_t *fl, INT32 color);
static void AM_activateNewScale(void)
@@ -237,7 +242,7 @@ static inline void AM_restoreScaleAndLoc(void)
m_x = old_m_x;
m_y = old_m_y;
}
else if (plr && plr->mo)
else
{
m_x = (plr->mo->x >> FRACTOMAPBITS) - m_w/2;
m_y = (plr->mo->y >> FRACTOMAPBITS) - m_h/2;
@@ -265,6 +270,9 @@ static void AM_findMinMaxBoundaries(void)
max_w = minimapinfo.map_w << MAPBITS;
max_h = minimapinfo.map_h << MAPBITS;
max_w = (max_x >>= FRACTOMAPBITS) - (min_x >>= FRACTOMAPBITS);
max_h = (max_y >>= FRACTOMAPBITS) - (min_y >>= FRACTOMAPBITS);
a = FixedDiv(f_w<<FRACBITS, max_w);
b = FixedDiv(f_h<<FRACBITS, max_h);
@@ -318,8 +326,7 @@ static void AM_initVariables(void)
break;
plr = &players[pnum];
if (plr && plr->mo)
if (plr != NULL && plr->mo != NULL)
{
m_x = (plr->mo->x >> FRACTOMAPBITS) - m_w/2;
m_y = (plr->mo->y >> FRACTOMAPBITS) - m_h/2;
@@ -333,23 +340,22 @@ static void AM_initVariables(void)
old_m_h = m_h;
}
//
// Called when the screen size changes.
//
static void AM_FrameBufferInit(void)
{
f_x = f_y = 0;
f_w = vid.width;
f_h = vid.height;
am_buf = screens[0];
}
//
// should be called at the start of every level
// right now, i figure it out myself
//
static void AM_LevelInit(void)
{
f_x = f_y = 0;
f_w = vid.width;
f_h = vid.height;
AM_drawFline = AM_drawFline_soft;
#ifdef HWRENDER
if (rendermode == render_opengl)
AM_drawFline = HWR_drawAMline;
#endif
AM_findMinMaxBoundaries();
scale_mtof = FixedDiv(min_scale_mtof*10, 7*FRACUNIT);
if (scale_mtof > max_scale_mtof)
@@ -371,7 +377,7 @@ void AM_Stop(void)
*
* \sa AM_Stop
*/
void AM_Start(void)
static inline void AM_Start(void)
{
static INT32 lastlevel = -1;
@@ -380,12 +386,8 @@ void AM_Start(void)
am_stopped = false;
if (lastlevel != gamemap || am_recalc) // screen size changed
{
AM_FrameBufferInit();
if (lastlevel != gamemap)
{
AM_LevelInit();
lastlevel = gamemap;
}
AM_LevelInit();
lastlevel = gamemap;
am_recalc = false;
}
AM_initVariables();
@@ -411,28 +413,6 @@ static void AM_maxOutWindowScale(void)
AM_activateNewScale();
}
//
// set window panning
//
static void AM_setWindowPanning(void)
{
// up and down
if (m_keydown[2]) // pan up
m_paninc.y = FTOM(F_PANINC);
else if (m_keydown[3]) // pan down
m_paninc.y = -FTOM(F_PANINC);
else
m_paninc.y = 0;
// left and right
if (m_keydown[0]) // pan right
m_paninc.x = FTOM(F_PANINC);
else if (m_keydown[1]) // pan left
m_paninc.x = -FTOM(F_PANINC);
else
m_paninc.x = 0;
}
/** Responds to user inputs in automap mode.
*
* \param ev Event to possibly respond to.
@@ -465,49 +445,35 @@ boolean AM_Responder(event_t *ev)
{
case AM_PANRIGHTKEY: // pan right
if (!followplayer)
{
m_keydown[0] = true;
AM_setWindowPanning();
}
m_paninc.x = FTOM(F_PANINC);
else
rc = false;
break;
case AM_PANLEFTKEY: // pan left
if (!followplayer)
{
m_keydown[1] = true;
AM_setWindowPanning();
}
m_paninc.x = -FTOM(F_PANINC);
else
rc = false;
break;
case AM_PANUPKEY: // pan up
if (!followplayer)
{
m_keydown[2] = true;
AM_setWindowPanning();
}
m_paninc.y = FTOM(F_PANINC);
else
rc = false;
break;
case AM_PANDOWNKEY: // pan down
if (!followplayer)
{
m_keydown[3] = true;
AM_setWindowPanning();
}
m_paninc.y = -FTOM(F_PANINC);
else
rc = false;
break;
case AM_ZOOMOUTKEY: // zoom out
mtof_zoommul = M_ZOOMOUT;
ftom_zoommul = M_ZOOMIN;
AM_setWindowPanning();
break;
case AM_ZOOMINKEY: // zoom in
mtof_zoommul = M_ZOOMIN;
ftom_zoommul = M_ZOOMOUT;
AM_setWindowPanning();
break;
case AM_TOGGLEKEY:
AM_Stop();
@@ -521,7 +487,6 @@ boolean AM_Responder(event_t *ev)
}
else
AM_restoreScaleAndLoc();
AM_setWindowPanning();
break;
case AM_FOLLOWKEY:
followplayer = !followplayer;
@@ -541,32 +506,14 @@ boolean AM_Responder(event_t *ev)
switch (ev->data1)
{
case AM_PANRIGHTKEY:
if (!followplayer)
{
m_keydown[0] = false;
AM_setWindowPanning();
}
break;
case AM_PANLEFTKEY:
if (!followplayer)
{
m_keydown[1] = false;
AM_setWindowPanning();
}
m_paninc.x = 0;
break;
case AM_PANUPKEY:
if (!followplayer)
{
m_keydown[2] = false;
AM_setWindowPanning();
}
break;
case AM_PANDOWNKEY:
if (!followplayer)
{
m_keydown[3] = false;
AM_setWindowPanning();
}
m_paninc.y = 0;
break;
case AM_ZOOMOUTKEY:
case AM_ZOOMINKEY:
@@ -598,9 +545,6 @@ static inline void AM_changeWindowScale(void)
static inline void AM_doFollowPlayer(void)
{
if (!plr || !plr->mo)
return;
if (f_oldloc.x != plr->mo->x || f_oldloc.y != plr->mo->y)
{
m_x = FTOM(MTOF(plr->mo->x >> FRACTOMAPBITS)) - m_w/2;
@@ -770,16 +714,6 @@ static boolean AM_clipMline(const mline_t *ml, fline_t *fl)
}
#undef DOOUTCODE
//
// Draws a pixel.
//
static void AM_drawPixel(INT32 xx, INT32 yy, INT32 cc)
{
if (xx < 0 || yy < 0 || xx >= f_w || yy >= f_h)
return; // off the screen
am_buf[(yy*f_w) + xx] = cc;
}
//
// Classic Bresenham w/ whatever optimizations needed for speed
//
@@ -801,6 +735,8 @@ static void AM_drawFline_soft(const fline_t *fl, INT32 color)
}
#endif
#define PUTDOT(xx,yy,cc) V_DrawFill(xx,yy,1,1,cc|V_NOSCALESTART);
dx = fl->b.x - fl->a.x;
ax = 2 * (dx < 0 ? -dx : dx);
sx = dx < 0 ? -1 : 1;
@@ -817,7 +753,7 @@ static void AM_drawFline_soft(const fline_t *fl, INT32 color)
d = ay - ax/2;
for (;;)
{
AM_drawPixel(x, y, color);
PUTDOT(x, y, color)
if (x == fl->b.x)
return;
if (d >= 0)
@@ -834,7 +770,7 @@ static void AM_drawFline_soft(const fline_t *fl, INT32 color)
d = ax - ay/2;
for (;;)
{
AM_drawPixel(x, y, color);
PUTDOT(x, y, color)
if (y == fl->b.y)
return;
if (d >= 0)
@@ -846,6 +782,8 @@ static void AM_drawFline_soft(const fline_t *fl, INT32 color)
d += ax;
}
}
#undef PUTDOT
}
//
@@ -867,18 +805,17 @@ static void AM_drawGrid(INT32 color)
fixed_t x, y;
fixed_t start, end;
mline_t ml;
fixed_t gridsize = (MAPBLOCKUNITS<<MAPBITS);
// Figure out start of vertical gridlines
start = m_x;
if ((start - (bmaporgx>>FRACTOMAPBITS)) % gridsize)
start += gridsize - ((start - (bmaporgx>>FRACTOMAPBITS)) % gridsize);
if ((start - bmaporgx) % (MAPBLOCKUNITS<<FRACBITS))
start += (MAPBLOCKUNITS<<FRACBITS) - ((start - bmaporgx) % (MAPBLOCKUNITS<<FRACBITS));
end = m_x + m_w;
// draw vertical gridlines
ml.a.y = m_y;
ml.b.y = m_y + m_h;
for (x = start; x < end; x += gridsize)
for (x = start; x < end; x += (MAPBLOCKUNITS<<FRACBITS))
{
ml.a.x = x;
ml.b.x = x;
@@ -887,14 +824,14 @@ static void AM_drawGrid(INT32 color)
// Figure out start of horizontal gridlines
start = m_y;
if ((start - (bmaporgy>>FRACTOMAPBITS)) % gridsize)
start += gridsize - ((start - (bmaporgy>>FRACTOMAPBITS)) % gridsize);
if ((start - bmaporgy) % (MAPBLOCKUNITS<<FRACBITS))
start += (MAPBLOCKUNITS<<FRACBITS) - ((start - bmaporgy) % (MAPBLOCKUNITS<<FRACBITS));
end = m_y + m_h;
// draw horizontal gridlines
ml.a.x = m_x;
ml.b.x = m_x + m_w;
for (y = start; y < end; y += gridsize)
for (y = start; y < end; y += (MAPBLOCKUNITS<<FRACBITS))
{
ml.a.y = y;
ml.b.y = y;
@@ -902,118 +839,14 @@ static void AM_drawGrid(INT32 color)
}
}
static INT32 GetDamage(INT32 special)
{
switch (special)
{
case 1: // Damage (Generic)
return 1;
case 6: // Death Pit (Camera Tilt)
return 6;
case 7: // Death Pit (No Camera Tilt)
return 7;
case 8: // Instant Kill
return 8;
default:
return 0;
}
}
static INT32 GetOffroad(INT32 special)
{
switch (special)
{
case 2: // Offroad (Weak)
return 2;
case 3: // Offroad
return 3;
case 4: // Offroad (Strong)
return 4;
default:
return 0;
}
}
#define SLOPEPARAMS(slope, end1, end2, normalheight) \
end1 = (P_GetZAt(slope, lines[i].v1->x, lines[i].v1->y, ((normalheight + FRACUNIT/2) >> FRACBITS)) + FRACUNIT/2) >> FRACBITS; \
end2 = (P_GetZAt(slope, lines[i].v2->x, lines[i].v2->y, ((normalheight + FRACUNIT/2) >> FRACBITS)) + FRACUNIT/2) >> FRACBITS;
static ffloor_t *AM_CompareFOFs(size_t i, ffloor_t *rover, ffloor_t *secondarystore)
{
ffloor_t *secondaryrover = NULL;
for (; rover; rover = rover->next)
{
fixed_t rovt1, rovt2;
fixed_t rovb1, rovb2;
if (!(rover->flags & FF_EXISTS))
continue;
if (!(rover->flags & FF_BLOCKPLAYER))
continue;
SLOPEPARAMS(*rover->t_slope, rovt1, rovt2, *rover->topheight)
SLOPEPARAMS(*rover->b_slope, rovb1, rovb2, *rover->bottomheight)
for (secondaryrover = secondarystore; secondaryrover; secondaryrover = secondaryrover->next)
{
fixed_t sect1, sect2;
fixed_t secb1, secb2;
if (!(secondaryrover->flags & FF_EXISTS))
continue;
if (!(secondaryrover->flags & FF_BLOCKPLAYER))
continue;
if (secondaryrover->secnum == rover->secnum)
break;
SLOPEPARAMS(*secondaryrover->t_slope, sect1, sect2, *secondaryrover->topheight)
SLOPEPARAMS(*secondaryrover->b_slope, secb1, secb2, *secondaryrover->bottomheight)
if (rovt1 != sect1)
continue;
if (rovt2 != sect2)
continue;
if (rovb1 != secb1)
continue;
if (rovb2 != secb2)
continue;
// this is fucking horrible
INT32 damage1, damage2;
INT32 offroad1, offroad2;
INT32 special1, special2;
special1 = GETSECSPECIAL(sectors[rover->secnum].special, 1);
special2 = GETSECSPECIAL(sectors[secondaryrover->secnum].special, 1);
damage1 = GetDamage(special1);
damage2 = GetDamage(special2);
offroad1 = GetOffroad(special1);
offroad2 = GetOffroad(special2);
if (damage1 != damage2
//|| sectors[rover->secnum].friction != sectors[secondaryrover->secnum].friction
|| offroad1 != offroad2)
continue;
break;
}
if (secondaryrover == NULL)
break;
}
return rover;
}
//
// Determines visible lines, draws them.
// This is LineDef based, not LineSeg based.
//
static void AM_drawWalls(UINT8 pass)
static inline void AM_drawWalls(void)
{
size_t i;
static mline_t l;
const fixed_t maxstep = FixedMul(MAXSTEPMOVE, mapobjectscale)>>FRACBITS;
fixed_t frontf1,frontf2, frontc1, frontc2; // front floor/ceiling ends
fixed_t backf1 = 0, backf2 = 0, backc1 = 0, backc2 = 0; // back floor ceiling ends
@@ -1023,142 +856,74 @@ static void AM_drawWalls(UINT8 pass)
l.a.y = lines[i].v1->y >> FRACTOMAPBITS;
l.b.x = lines[i].v2->x >> FRACTOMAPBITS;
l.b.y = lines[i].v2->y >> FRACTOMAPBITS;
#define SLOPEPARAMS(slope, end1, end2, normalheight) \
if (slope) { \
end1 = P_GetZAt(slope, lines[i].v1->x, lines[i].v1->y); \
end2 = P_GetZAt(slope, lines[i].v2->x, lines[i].v2->y); \
} else \
end1 = end2 = normalheight;
SLOPEPARAMS(lines[i].frontsector->f_slope, frontf1, frontf2, lines[i].frontsector->floorheight)
SLOPEPARAMS(lines[i].frontsector->c_slope, frontc1, frontc2, lines[i].frontsector->ceilingheight)
if (lines[i].backsector) {
SLOPEPARAMS(lines[i].backsector->f_slope, backf1, backf2, lines[i].backsector->floorheight)
SLOPEPARAMS(lines[i].backsector->c_slope, backc1, backc2, lines[i].backsector->ceilingheight)
}
#undef SLOPEPARAMS
if (!lines[i].backsector) // 1-sided
{
if (!(pass & PASS_SOLID))
;
else if (frontf1 != frontc1 || frontf2 != frontc2 || lines[i].frontsector->f_slope)
{
AM_drawMline(&l, TSWALLCOLORS);
}
else if (!am_minigen)
{
if (lines[i].flags & ML_NOCLIMB)
AM_drawMline(&l, NOCLIMBWALLCOLORS);
else
AM_drawMline(&l, WALLCOLORS);
}
continue;
}
SLOPEPARAMS(lines[i].backsector->f_slope, backf1, backf2, lines[i].backsector->floorheight)
SLOPEPARAMS(lines[i].backsector->c_slope, backc1, backc2, lines[i].backsector->ceilingheight)
if ((backf1 == backc1 && backf2 == backc2) // Back is thok barrier
else if ((backf1 == backc1 && backf2 == backc2) // Back is thok barrier
|| (frontf1 == frontc1 && frontf2 == frontc2)) // Front is thok barrier
{
if (backf1 == backc1 && backf2 == backc2
&& frontf1 == frontc1 && frontf2 == frontc2) // BOTH are thok barriers
{
if (!am_minigen && (pass & PASS_INTANGIBLE))
{
AM_drawMline(&l, GRIDCOLORS);
}
if (lines[i].flags & ML_NOCLIMB)
AM_drawMline(&l, NOCLIMBTSWALLCOLORS);
else
AM_drawMline(&l, TSWALLCOLORS);
}
else if (pass & PASS_SOLID)
else
{
AM_drawMline(&l, TSWALLCOLORS);
if (lines[i].flags & ML_NOCLIMB)
AM_drawMline(&l, NOCLIMBTHOKWALLCOLORS);
else
AM_drawMline(&l, THOKWALLCOLORS);
}
}
else
{
if (lines[i].flags & ML_IMPASSIBLE) // (ML_IMPASSABLE|ML_BLOCKPLAYERS)
{
if (pass & PASS_SOLID)
AM_drawMline(&l, TSWALLCOLORS); // Completely solid course boundary
}
else if ((lines[i].flags & ML_EFFECT4) // ML_MIDSOLID
&& sides[lines->sidenum[0]].midtexture)
{
if (pass & PASS_SOLID)
AM_drawMline(&l, TSWALLCOLORS); // solid midtexture, likely a course boundary
}
if ((backf1 != frontf1 && abs(backf1 - frontf1) > maxstep)
|| (backf2 != frontf2 && abs(backf2 - frontf2) > maxstep))
{
if (pass & PASS_SOLID)
AM_drawMline(&l, TSWALLCOLORS); // floor-wall, likely a course boundary
}
else if (GETSECSPECIAL(lines[i].frontsector->special, 4) == 10 || GETSECSPECIAL(lines[i].backsector->special, 4) == 10)
{
if (pass & PASS_SOLID)
AM_drawMline(&l, TSFINISHLINE); // finish line
}
else if (backf1 != frontf1 || backf2 != frontf2)
{
if (pass & PASS_INTANGIBLE)
AM_drawMline(&l, FDWALLCOLORS); // floorlevel change
}
else if (backc1 != frontc1 || backc2 != frontc2)
{
if (!(pass & PASS_INTANGIBLE))
;
else if (abs(backc1 - frontc1) < maxstep
|| abs(backc2 - frontc2) < maxstep)
{
AM_drawMline(&l, CDWALLCOLORS); // ceilinglevel change
if (lines[i].flags & ML_NOCLIMB) {
if (backf1 != frontf1 || backf2 != frontf2) {
AM_drawMline(&l, NOCLIMBFDWALLCOLORS); // floor level change
}
else if (backc1 != frontc1 || backc2 != frontc2) {
AM_drawMline(&l, NOCLIMBCDWALLCOLORS); // ceiling level change
}
else
{
AM_drawMline(&l, GRIDCOLORS); // ceiling-wall, not likely to be a course boundary but flagged up just in case
}
AM_drawMline(&l, NOCLIMBTSWALLCOLORS);
}
else
{
ffloor_t *rover = NULL;
if (lines[i].frontsector->ffloors || lines[i].backsector->ffloors)
{
if (lines[i].backsector->ffloors == NULL)
{
// Check frontside for one solid
for (rover = lines[i].frontsector->ffloors; rover; rover = rover->next)
{
if (!(rover->flags & FF_EXISTS))
continue;
if (!(rover->flags & FF_BLOCKPLAYER))
continue;
break;
}
}
else if (lines[i].frontsector->ffloors == NULL)
{
// Check backside for one solid
for (rover = lines[i].backsector->ffloors; rover; rover = rover->next)
{
if (!(rover->flags & FF_EXISTS))
continue;
if (!(rover->flags & FF_BLOCKPLAYER))
continue;
break;
}
}
else
{
// Check to see if any secnums exist in one but not the other.
rover = AM_CompareFOFs(i, lines[i].frontsector->ffloors, lines[i].backsector->ffloors);
if (rover == NULL)
rover = AM_CompareFOFs(i, lines[i].backsector->ffloors, lines[i].frontsector->ffloors);
}
if (backf1 != frontf1 || backf2 != frontf2) {
AM_drawMline(&l, FDWALLCOLORS); // floor level change
}
if (rover != NULL)
{
if (pass & PASS_FOF)
AM_drawMline(&l, TSFOFINFO); // a FOF is here but we don't know how to distinguish them yet
}
else if (!am_minigen)
{
if (pass & PASS_INTANGIBLE)
AM_drawMline(&l, GRIDCOLORS); // likely low-relevance line
else if (backc1 != frontc1 || backc2 != frontc2) {
AM_drawMline(&l, CDWALLCOLORS); // ceiling level change
}
else
AM_drawMline(&l, TSWALLCOLORS);
}
}
}
}
#undef SLOPEPARAMS
//
// Rotation in 2D.
// Used to rotate player arrow line character.
@@ -1229,11 +994,18 @@ static inline void AM_drawPlayers(void)
player_t *p;
INT32 color = GREENS;
if (!multiplayer)
{
AM_drawLineCharacter(player_arrow, NUMPLYRLINES, 0, plr->mo->angle, DWHITE, plr->mo->x, plr->mo->y);
return;
}
// multiplayer (how??)
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i] || players[i].spectator)
continue;
if (!players[i].mo)
continue;
@@ -1241,7 +1013,7 @@ static inline void AM_drawPlayers(void)
if (p->skincolor > 0)
color = R_GetTranslationColormap(TC_DEFAULT, p->skincolor, GTC_CACHE)[GREENS + 8];
AM_drawLineCharacter(player_arrow, NUMPLYRLINES, 16<<FRACBITS, p->mo->angle, color, p->mo->x, p->mo->y);
AM_drawLineCharacter(player_arrow, NUMPLYRLINES, 0, p->mo->angle, color, p->mo->x, p->mo->y);
}
}
@@ -1255,65 +1027,19 @@ static inline void AM_drawThings(UINT8 colors)
t = sectors[i].thinglist;
while (t)
{
if (!t->player)
AM_drawLineCharacter(thintriangle_guy, NUMTHINTRIANGLEGUYLINES, 16<<FRACBITS, t->angle, colors, t->x, t->y);
AM_drawLineCharacter(thintriangle_guy, NUMTHINTRIANGLEGUYLINES, 16<<FRACBITS, t->angle, colors, t->x, t->y);
t = t->snext;
}
}
}
static inline void AM_drawSpecialThingsOnly(UINT8 colors)
{
size_t i;
for (i = 0; i < numsectors; i++)
{
mobj_t *t = NULL;
// this is fucking horrible
const INT32 special = GETSECSPECIAL(sectors[i].special, 1);
if (GetDamage(special) != 0
//|| sectors[i].friction < ORIG_FRICTION
|| GetOffroad(special) != 0)
continue;
t = sectors[i].thinglist;
while (t)
{
if (t->type == MT_RANDOMITEM
|| t->type == MT_STARPOST
|| (t->flags & MF_SPRING))
AM_drawLineCharacter(thintriangle_guy, NUMTHINTRIANGLEGUYLINES, 16<<FRACBITS, t->angle, colors, t->x, t->y);
t = t->snext;
}
}
}
/** Draws the crosshair.
/** Draws the crosshair, actually just a dot in software mode.
*
* \param color Color for the crosshair.
*/
static inline void AM_drawCrosshair(UINT8 color)
{
const fixed_t scale = 4<<FRACBITS;
size_t i;
fline_t fl;
for (i = 0; i < NUMCROSSMARKLINES; i++)
{
fl.a.x = FixedMul(cross_mark[i].a.x, scale) >> FRACBITS;
fl.a.y = FixedMul(cross_mark[i].a.y, scale) >> FRACBITS;
fl.b.x = FixedMul(cross_mark[i].b.x, scale) >> FRACBITS;
fl.b.y = FixedMul(cross_mark[i].b.y, scale) >> FRACBITS;
fl.a.x += f_x + (f_w / 2);
fl.a.y += f_y + (f_h / 2);
fl.b.x += f_x + (f_w / 2);
fl.b.y += f_y + (f_h / 2);
AM_drawFline(&fl, color);
}
V_DrawFill(f_w/2 + f_x, f_h/2 + f_y, 1, 1, color|V_NOSCALESTART);
}
/** Draws the automap.
@@ -1323,81 +1049,11 @@ void AM_Drawer(void)
if (!automapactive)
return;
AM_drawFline = AM_drawFline_soft;
#ifdef HWRENDER
if (rendermode == render_opengl)
AM_drawFline = HWR_drawAMline;
#endif
AM_clearFB(BACKGROUND);
if (draw_grid) AM_drawGrid(GRIDCOLORS);
AM_drawWalls(PASS_FOF|PASS_INTANGIBLE|PASS_SOLID);
AM_drawThings(THINGCOLORS);
AM_drawWalls();
AM_drawPlayers();
AM_drawThings(THINGCOLORS);
if (!followplayer) AM_drawCrosshair(XHAIRCOLORS);
}
minigen_t *AM_MinimapGenerate(INT32 mul)
{
static minigen_t ret = {0};
if (automapactive)
return NULL;
am_minigen = true;
AM_drawFline = AM_drawFline_soft; // yes, even in GL
//AM_FrameBufferInit();
f_x = f_y = 0;
ret.w = f_w = minimapinfo.minimap_w * mul;
ret.h = f_h = minimapinfo.minimap_h * mul;
am_buf = ret.buf = NULL;
//AM_LevelInit();
AM_findMinMaxBoundaries();
scale_mtof = min_scale_mtof - (min_scale_mtof/20);
scale_ftom = FixedDiv(FRACUNIT, scale_mtof);
//AM_initVariables();
f_oldloc.x = INT32_MAX;
m_paninc.x = m_paninc.y = 0;
ftom_zoommul = FRACUNIT;
mtof_zoommul = FRACUNIT;
m_w = FTOM(f_w);
m_h = FTOM(f_h);
//AM_changeWindowLoc();
m_x = min_x - FixedMul(m_w, FRACUNIT/40);
m_y = min_y - FixedMul(m_h, FRACUNIT/40);
m_x2 = m_x + m_w;
m_y2 = m_y + m_h;
// for saving & restoring
old_m_x = m_x;
old_m_y = m_y;
old_m_w = m_w;
old_m_h = m_h;
am_buf = ret.buf = malloc((f_w*f_h));
if (ret.buf == NULL)
return NULL;
//AM_clearFB(BACKGROUND);
memset(am_buf, 0xff, (f_w*f_h));
AM_drawSpecialThingsOnly(BACKGROUND);
AM_drawWalls(PASS_FOF);
AM_drawWalls(PASS_INTANGIBLE);
AM_drawWalls(PASS_SOLID);
am_buf = NULL;
am_recalc = true;
am_minigen = false;
return &ret;
AM_drawCrosshair(XHAIRCOLORS);
}
+8 -17
View File
@@ -1,10 +1,8 @@
// SONIC ROBO BLAST 2 KART
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 2024 by Vivian "toastergrl" Grannell.
// Copyright (C) 2024 by Kart Krew.
// Copyright (C) 2020 by Sonic Team Junior.
// Copyright (C) 2000 by DooM Legacy Team.
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2018 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
@@ -28,6 +26,11 @@ typedef struct
fpoint_t a, b;
} fline_t;
// Used by ST StatusBar stuff.
#define AM_MSGHEADER (('a'<<24)+('m'<<16))
#define AM_MSGENTERED (AM_MSGHEADER | ('e'<<8))
#define AM_MSGEXITED (AM_MSGHEADER | ('x'<<8))
extern boolean am_recalc; // true if screen size changes
extern boolean automapactive; // In AutoMap mode?
@@ -40,19 +43,7 @@ void AM_Ticker(void);
// Called by main loop, instead of view drawer if automap is active.
void AM_Drawer(void);
// Enables the automap.
void AM_Start(void);
// Called to force the automap to quit if the level is completed while it is up.
void AM_Stop(void);
typedef struct
{
INT32 w, h;
UINT8 *buf;
} minigen_t;
// Minimap generation
minigen_t *AM_MinimapGenerate(INT32 mul);
#endif
+4
View File
@@ -184,6 +184,8 @@ void I_OutputMsg(const char *fmt, ...)
void I_StartupMouse(void){}
void I_StartupMouse2(void){}
void I_StartupKeyboard(void){}
INT32 I_GetKey(void)
@@ -240,6 +242,8 @@ void I_GetJoystickEvents(void){}
void I_GetJoystick2Events(void){}
void I_GetMouseEvents(void){}
char *I_GetEnv(const char *name)
{
LOGW("I_GetEnv() called?!");
+5 -2
View File
@@ -36,7 +36,7 @@ static inline void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cm
return;
// Lua can handle it!
if (LUA_HookBotAI(sonic, tails, cmd))
if (LUAh_BotAI(sonic, tails, cmd))
return;
if (tails->player->pflags & (PF_MACESPIN|PF_ITEMHANG))
@@ -118,8 +118,11 @@ void B_BuildTiccmd(player_t *player, ticcmd_t *cmd)
return;
}
// Bot AI isn't programmed in analog.
//CV_SetValue(&cv_analog2, false);
// Let Lua scripts build ticcmds
if (LUA_HookTiccmd(player, cmd, HOOK(BotTiccmd)))
if (LUAh_BotTiccmd(player, cmd))
return;
// We don't have any main character AI, sorry. D:
+23 -28
View File
@@ -1,7 +1,7 @@
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2024 by Sonic Team Junior.
// Copyright (C) 1999-2018 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
@@ -11,9 +11,6 @@
/// \brief Macros to read/write from/to a UINT8 *,
/// used for packet creation and such
#ifndef __BYTEPTR_H__
#define __BYTEPTR_H__
#if defined (__alpha__) || defined (__arm__) || defined (__mips__) || defined (__ia64__) || defined (__clang__)
#define DEALIGNED
#endif
@@ -153,7 +150,7 @@ FUNCINLINE static ATTRINLINE UINT32 readulong(void *ptr)
#undef DEALIGNED
#define WRITESTRINGN(p, s, n) do { \
#define WRITESTRINGN(p, s, n) ({ \
size_t tmp_i; \
\
for (tmp_i = 0; tmp_i < n && s[tmp_i] != '\0'; tmp_i++) \
@@ -161,72 +158,70 @@ FUNCINLINE static ATTRINLINE UINT32 readulong(void *ptr)
\
if (tmp_i < n) \
WRITECHAR(p, '\0'); \
} while (0)
})
#define WRITESTRINGL(p, s, n) do { \
#define WRITESTRINGL(p, s, n) ({ \
size_t tmp_i; \
\
for (tmp_i = 0; tmp_i < n - 1 && s[tmp_i] != '\0'; tmp_i++) \
WRITECHAR(p, s[tmp_i]); \
\
WRITECHAR(p, '\0'); \
} while (0)
})
#define WRITESTRING(p, s) do { \
#define WRITESTRING(p, s) ({ \
size_t tmp_i; \
\
for (tmp_i = 0; s[tmp_i] != '\0'; tmp_i++) \
WRITECHAR(p, s[tmp_i]); \
\
WRITECHAR(p, '\0'); \
} while (0)
})
#define WRITEMEM(p, s, n) do { \
memcpy(p, s, n); \
p += n; \
} while (0)
#define WRITEMEM(p, s, n) ({ \
memcpy(p, s, n); \
p += n; \
})
#define SKIPSTRING(p) while (READCHAR(p) != '\0')
#define SKIPSTRINGN(p, n) do { \
#define SKIPSTRINGN(p, n) ({ \
size_t tmp_i = 0; \
\
while (tmp_i < n && READCHAR(p) != '\0') \
tmp_i++; \
} while (0)
})
#define SKIPSTRINGL(p, n) SKIPSTRINGN(p, n)
#define READSTRINGN(p, s, n) do { \
#define READSTRINGN(p, s, n) ({ \
size_t tmp_i = 0; \
\
while (tmp_i < n && (s[tmp_i] = READCHAR(p)) != '\0') \
tmp_i++; \
\
s[tmp_i] = '\0'; \
} while (0)
})
#define READSTRINGL(p, s, n) do { \
#define READSTRINGL(p, s, n) ({ \
size_t tmp_i = 0; \
\
while (tmp_i < n - 1 && (s[tmp_i] = READCHAR(p)) != '\0') \
tmp_i++; \
\
s[tmp_i] = '\0'; \
} while (0)
})
#define READSTRING(p, s) do { \
#define READSTRING(p, s) ({ \
size_t tmp_i = 0; \
\
while ((s[tmp_i] = READCHAR(p)) != '\0') \
tmp_i++; \
\
s[tmp_i] = '\0'; \
} while (0)
})
#define READMEM(p, s, n) do { \
memcpy(s, p, n); \
p += n; \
} while (0)
#endif // __BYTEPTR_H__
#define READMEM(p, s, n) ({ \
memcpy(s, p, n); \
p += n; \
})
+17 -3
View File
@@ -240,6 +240,7 @@ void COM_ImmedExecute(const char *ptext)
while (i < strlen(ptext))
{
quotes = 0;
for (j = 0; i < strlen(ptext); i++,j++)
{
@@ -627,7 +628,7 @@ static void COM_ExecuteString(char *ptext)
// check cvars
// Hurdler: added at Ebola's request ;)
// (don't flood the console in software mode with bad gl_xxx command)
// (don't flood the console in software mode with bad gr_xxx command)
if (!CV_Command() && con_destlines)
CONS_Printf(M_GetText("Unknown command '%s'\n"), COM_Argv(0));
}
@@ -1492,7 +1493,11 @@ static void Got_NetVar(UINT8 **p, INT32 playernum)
if (server)
{
SendKick(playernum, KICK_MSG_CON_FAIL);
UINT8 buf[2];
buf[0] = (UINT8)playernum;
buf[1] = KICK_MSG_CON_FAIL;
SendNetXCmd(XD_KICK, &buf, 2);
}
return;
}
@@ -1983,7 +1988,7 @@ static boolean CV_FilterJoyAxisVars(consvar_t *v, const char *valstr)
return true;
}
// Block the Xbox DInput default axes and reset to the current defaults
// Block the Xbox DInput default axes and reset to the current defaults
static boolean CV_FilterJoyAxisVars2(consvar_t *v, const char *valstr)
{
if (!stricmp(v->name, "joyaxis_turn") && !stricmp(valstr, "X-Axis"))
@@ -2040,6 +2045,15 @@ static boolean CV_FilterVarByVersion(consvar_t *v, const char *valstr)
if (GETMAJOREXECVERSION(cv_execversion.value) < 2) // 2 = 1.0.2
{
#if 0
// We don't have changed saved cvars yet
if (!stricmp(v->name, "alwaysmlook")
|| !stricmp(v->name, "alwaysmlook2")
|| !stricmp(v->name, "mousemove")
|| !stricmp(v->name, "mousemove2"))
return false;
#endif
// axis defaults were changed to be friendly to 360 controllers
// if ALL axis settings are defaults, then change them to new values
if (!CV_FilterJoyAxisVars(v, valstr))
+34 -44
View File
@@ -275,28 +275,29 @@ void CON_SetupBackColormap(void)
switch (cons_backcolor.value)
{
case 0: palindex = 15; break; // White
case 1: palindex = 31; break; // Gray
case 2: palindex = 47; break; // Sepia
case 3: palindex = 63; break; // Brown
case 4: palindex = 150; shift = 7; break; // Pink
case 5: palindex = 127; shift = 7; break; // Raspberry
case 6: palindex = 143; break; // Red
case 7: palindex = 86; shift = 7; break; // Creamsicle
case 8: palindex = 95; break; // Orange
case 9: palindex = 119; shift = 7; break; // Gold
case 10: palindex = 111; break; // Yellow
case 11: palindex = 191; shift = 7; break; // Emerald
case 12: palindex = 175; break; // Green
case 13: palindex = 219; break; // Cyan
case 14: palindex = 207; shift = 7; break; // Steel
case 15: palindex = 230; shift = 7; break; // Periwinkle
case 16: palindex = 239; break; // Blue
case 17: palindex = 199; shift = 7; break; // Purple
case 18: palindex = 255; shift = 7; break; // Lavender
case 0: palindex = 15; break; // White
case 1: palindex = 31; break; // Gray
case 2: palindex = 47; break; // Sepia
case 3: palindex = 63; break; // Brown
case 4: palindex = 150; shift = 7; break; // Pink
case 5: palindex = 127; shift = 7; break; // Raspberry
case 6: palindex = 143; break; // Red
case 7: palindex = 86; shift = 7; break; // Creamsicle
case 8: palindex = 95; break; // Orange
case 9: palindex = 119; shift = 7; break; // Gold
case 10: palindex = 111; break; // Yellow
case 11: palindex = 191; shift = 7; break; // Emerald
case 12: palindex = 175; break; // Green
case 13: palindex = 219; break; // Cyan
case 14: palindex = 207; shift = 7; break; // Steel
case 15: palindex = 230; shift = 7; break; // Periwinkle
case 16: palindex = 239; break; // Blue
case 17: palindex = 199; shift = 7; break; // Purple
case 18: palindex = 255; shift = 7; break; // Lavender
// Default green
default: palindex = 175; break;
}
}
// setup background colormap
for (i = 0, j = 0; i < 768; i += 3, j++)
@@ -607,7 +608,7 @@ static void CON_MoveConsole(void)
}
// Not instant - Increment fracmovement fractionally
fracmovement += FixedMul(cons_speed.value*vid.fdupy, (cv_uncappedhud.value ? renderdeltatics : FRACUNIT));
fracmovement += FixedMul(cons_speed.value*vid.fdupy, renderdeltatics);
if (con_curlines < con_destlines) // Move the console downwards
{
@@ -620,11 +621,11 @@ static void CON_MoveConsole(void)
con_curlines -= FixedInt(fracmovement);
if (con_curlines < con_destlines)
con_curlines = con_destlines;
if (con_destlines == 0) // If the console is being closed, not just moved up...
con_tick = 0; // ...don't show the blinking cursor
}
fracmovement %= FRACUNIT; // Reset fracmovement's integer value, but keep the fraction
Unlock_state();
@@ -634,7 +635,7 @@ INT32 CON_ShiftChar(INT32 ch)
{
if (I_UseNativeKeyboard())
return ch;
if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))
{
if (cv_keyboardlayout.value == 3)
@@ -826,7 +827,7 @@ boolean CON_Responder(event_t *ev)
// let go keyup events, don't eat them
if (ev->type != ev_keydown && ev->type != ev_console)
{
if (ev->data1 == gamecontrol[0][gc_console][0] || ev->data1 == gamecontrol[0][gc_console][1])
if (ev->data1 == gamecontrol[gc_console][0] || ev->data1 == gamecontrol[gc_console][1])
consdown = false;
return false;
}
@@ -844,7 +845,7 @@ boolean CON_Responder(event_t *ev)
INT32 i;
for (i = 0; i < num_gamecontrols; i++)
{
if (gamecontrol[0][i][0] == ev->data1 || gamecontrol[0][i][1] == ev->data1)
if (gamecontrol[i][0] == ev->data1 || gamecontrol[i][1] == ev->data1)
break;
}
@@ -852,7 +853,7 @@ boolean CON_Responder(event_t *ev)
return false;
}
if (key == gamecontrol[0][gc_console][0] || key == gamecontrol[0][gc_console][1])
if (key == gamecontrol[gc_console][0] || key == gamecontrol[gc_console][1])
{
if (consdown) // ignore repeat
return true;
@@ -1235,7 +1236,7 @@ void CONS_Printf(const char *fmt, ...)
txt = malloc(8192);
va_start(argptr, fmt);
vsnprintf(txt, 8192, fmt, argptr);
vsprintf(txt, fmt, argptr);
va_end(argptr);
// echo console prints to log file
@@ -1243,7 +1244,7 @@ void CONS_Printf(const char *fmt, ...)
if (con_started)
CON_Print(txt);
CON_LogMessage(txt);
Lock_state();
@@ -1333,12 +1334,7 @@ void CONS_Error(const char *msg)
// dirty quick hack, but for the good cause
while (I_GetKey() != KEY_ENTER)
{
// Sleep so we don't take too much of cpu usage
I_Sleep(1.f/TICRATE*1000);
I_OsPolling();
}
}
//======================================================================
@@ -1470,15 +1466,12 @@ static void CON_DrawHudlines(void)
{
charflags = (*p & 0x7f) << V_CHARCOLORSHIFT;
p++;
c++;
}
if (c >= con_width)
break;
if (*p < HU_FONTSTART)
;//charwidth = 4 * con_scalefactor;
else
{
//charwidth = hu_font['A'-HU_FONTSTART]->width * con_scalefactor;
//charwidth = SHORT(hu_font['A'-HU_FONTSTART]->width) * con_scalefactor;
V_DrawCharacter(x, y, (INT32)(*p) | charflags | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value);
}
}
@@ -1513,7 +1506,7 @@ static void CON_DrawConsole(void)
// draw console background
if (cons_backpic.value || con_forcepic)
{
patch_t *con_backpic = W_CachePatchName("KARTKREW", PU_PATCH_LOWPRIORITY);
patch_t *con_backpic = W_CachePatchName("KARTKREW", PU_CACHE);
// Jimita: CON_DrawBackpic just called V_DrawScaledPatch
V_DrawFixedPatch(0, 0, FRACUNIT/2, 0, con_backpic, NULL);
@@ -1553,10 +1546,7 @@ static void CON_DrawConsole(void)
{
charflags = (*p & 0x7f) << V_CHARCOLORSHIFT;
p++;
c++;
}
if (c >= con_width)
break;
V_DrawCharacter(x, y, (INT32)(*p) | charflags | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value);
}
}
@@ -1581,11 +1571,11 @@ void CON_Drawer(void)
if (con_recalc)
{
CON_RecalcSize();
if (con_curlines <= 0)
CON_ClearHUD();
}
// console movement
if (con_curlines != con_destlines)
CON_MoveConsole();
+597 -657
View File
File diff suppressed because it is too large. Load diff
+9 -26
View File
@@ -41,15 +41,6 @@ applications may follow different packet versions.
#define BACKUPTICS 32
#define TICQUEUE 512 // more than enough for most timeouts....
#define MAXTEXTCMD 256
// No. of tics your controls can be delayed by.
// TODO: Instead of storing a ton of extra cmds for gentlemens' delay,
// keep them in a linked-list, with timestamps to discard everything that's older than already sent.
// That will support any amount of lag, and be less wasteful for clients who don't use it.
// This just works as a quick implementation.
#define MAXGENTLEMENDELAY TICRATE
//
// Packet structure
//
@@ -108,11 +99,12 @@ typedef enum
PT_PING, // Packet sent to tell clients the other client's latency to server.
#ifdef SATURNPAK
#ifdef SATURNSYNCH
PT_WILLRESENDGAMESTATE, // Hey Client, I am about to resend you the gamestate!
PT_CANRECEIVEGAMESTATE, // Okay Server, I'm ready to receive it, you can go ahead.
PT_RECEIVEDGAMESTATE, // Thank you Server, I am ready to play again!
// we will reserve this for now even if unused, so order wont get mangled
PT_ISSATURN, // Saturn specific identifier packet
#endif
@@ -393,7 +385,6 @@ typedef struct
#define MAXSERVERNAME 32
#define MAXFILENEEDED 915
#define MAX_MIRROR_LENGTH 256
// This packet is too large
typedef struct
{
@@ -585,11 +576,6 @@ extern UINT32 realpingtable[MAXPLAYERS];
extern UINT32 playerpingtable[MAXPLAYERS];
extern tic_t servermaxping;
extern boolean server_lagless;
extern tic_t simulated_lag;
extern tic_t lowest_lag;
extern consvar_t cv_mindelay, cv_gentlemens;
extern consvar_t
#ifdef VANILLAJOINNEXTROUND
cv_joinnextround,
@@ -599,7 +585,7 @@ extern consvar_t
cv_allownewsaturnplayer,
#endif
cv_joinrefusemessage, cv_maxplayers, cv_resynchattempts,
#ifdef SATURNPAK
#ifdef SATURNSYNCH
cv_resynchcooldown, cv_gamestateattempts,
#endif
cv_blamecfail, cv_maxsend, cv_noticedownload, cv_downloadspeed;
@@ -614,9 +600,10 @@ void D_ClientServerInit(void);
// Initialise the other field
void RegisterNetXCmd(netxcmd_t id, void (*cmd_f)(UINT8 **p, INT32 playernum));
void SendNetXCmdForPlayer(UINT8 playerid, netxcmd_t id, const void *param, size_t nparam);
#define SendNetXCmd(id, param, nparam) SendNetXCmdForPlayer(0, id, param, nparam) // Shortcut for P1
void SendKick(UINT8 playernum, UINT8 msg);
void SendNetXCmd(netxcmd_t id, const void *param, size_t nparam);
void SendNetXCmd2(netxcmd_t id, const void *param, size_t nparam); // splitsreen player
void SendNetXCmd3(netxcmd_t id, const void *param, size_t nparam); // splitsreen3 player
void SendNetXCmd4(netxcmd_t id, const void *param, size_t nparam); // splitsreen4 player
// Create any new ticcmds and broadcast to other players.
void NetKeepAlive(void);
@@ -635,9 +622,6 @@ void CL_RemovePlayer(INT32 playernum, INT32 reason);
void CL_QueryServerList(msg_server_t *list);
void CL_UpdateServerList(void);
void CL_TimeoutServerList(void);
void CL_AbortConnection(void);
// Is there a game running
boolean Playing(void);
@@ -663,14 +647,13 @@ extern char motd[254], server_context[8];
extern UINT8 playernode[MAXPLAYERS];
INT32 D_NumPlayers(void);
void D_ResetTiccmds(void);
tic_t GetLag(INT32 node);
//UINT8 GetFreeXCmdSize(UINT8 playerid);
UINT8 GetFreeXCmdSize(void);
extern UINT8 hu_resynching;
#ifdef SATURNPAK
#ifdef SATURNSYNCH
extern UINT8 hu_redownloadinggamestate;
#endif
extern boolean hu_stopped; // kart, true when the game is stopped for players due to a disconnecting or connecting player
+1
View File
@@ -25,6 +25,7 @@ typedef enum
ev_console,
ev_mouse,
ev_joystick,
ev_mouse2,
ev_joystick2,
ev_joystick3,
ev_joystick4,
+311 -468
View File
File diff suppressed because it is too large. Load diff
+14 -25
View File
@@ -17,9 +17,9 @@
#include "d_event.h"
#include "w_wad.h" // for MAX_WADFILES
// make sure not to write back the config until it's been correctly loaded
extern tic_t rendergametic;
// make sure not to write back the config until it's been correctly loaded
extern boolean loaded_config;
extern char srb2home[256]; //Alam: My Home
@@ -27,34 +27,23 @@ extern boolean usehome; //Alam: which path?
extern const char *pandf; //Alam: how to path?
extern char srb2path[256]; //Alam: SRB2's Home
// extra graphic patches for saturn specific thingies
extern boolean found_extra_kart; // for use in k_kart.c
extern boolean found_extra2_kart; // for use in k_kart.c
extern boolean found_extra3_kart; // for use in k_kart.c
extern boolean xtra_speedo; // extra speedometer check
extern boolean xtra_speedo_clr; // extra speedometer colour check
extern boolean xtra_speedo3; // 80x11 extra speedometer check
extern boolean xtra_speedo_clr3; // 80x11 extra speedometer colour check
extern boolean achi_speedo; // achiiro speedometer check
extern boolean achi_speedo_clr; // extra speedometer colour check
extern boolean dial_speedo; // dial speedometer check
extern boolean dial_speedo_clr; // dial speedometer colour check
extern boolean kartz_speedo; // kartZ speedo
extern boolean kartz_speedo_smol; // kartZ speedo but smol
extern boolean clr_hud; // colour hud check
extern boolean driftgaugegfx_clr; // driftgauge colour check
extern boolean big_lap; // bigger lap counter
extern boolean big_lap_color; // bigger lap counter but colour
extern boolean statdp; // stat display for extended player setup
extern boolean nametaggfx; // Nametag stuffs
extern boolean driftgaugegfx; // Driftgauge stuffs
extern boolean multiitem_icon; // Extra icons for Sneakers, Banana and Jawz
extern boolean joystickicon; // Extra icons for the joystick input display
extern boolean minidoticon; // Dot icon for minimap player angle display
extern boolean minilighticon; // mkwii-style minimap headlight
//
extern boolean xtra_speedo; // extra speedometer check
extern boolean xtra_speedo_clr; // extra speedometer colour check
extern boolean xtra_speedo3; // 80x11 extra speedometer check
extern boolean xtra_speedo_clr3; // 80x11 extra speedometer colour check
extern boolean achi_speedo; // achiiro speedometer check
extern boolean achi_speedo_clr; // extra speedometer colour check
extern boolean clr_hud; // colour hud check
extern boolean big_lap; // bigger lap counter
extern boolean big_lap_color; // bigger lap counter but colour
extern boolean kartzspeedo; // kartZ speedo
extern boolean statdp; // stat display for extended player setup
extern boolean nametaggfx; // Nametag stuffs
extern boolean driftgaugegfx;
// autoload stuff
extern boolean autoloading;
+83 -66
View File
@@ -69,6 +69,8 @@ INT16 hardware_MAXPACKETLENGTH;
boolean (*I_NetGet)(void) = NULL;
void (*I_NetSend)(void) = NULL;
boolean (*I_NetCanSend)(void) = NULL;
boolean (*I_NetCanGet)(void) = NULL;
void (*I_NetCloseSocket)(void) = NULL;
void (*I_NetFreeNodenum)(INT32 nodenum) = NULL;
SINT8 (*I_NetMakeNodewPort)(const char *address, const char* port) = NULL;
@@ -109,24 +111,20 @@ boolean Net_GetNetStat(void)
{
const tic_t t = I_GetTime();
static INT64 oldsendbyte = 0;
if (statstarttic+STATLENGTH <= t)
{
const tic_t df = t-statstarttic;
const INT64 newsendbyte = sendbytes - oldsendbyte;
sendbps = (INT32)(newsendbyte*TICRATE)/df;
getbps = (getbytes*TICRATE)/df;
if (sendackpacket)
lostpercent = 100.0f*(float)retransmit/(float)sendackpacket;
else
lostpercent = 0.0f;
if (getackpacket)
duppercent = 100.0f*(float)duppacket/(float)getackpacket;
else
duppercent = 0.0f;
if (ticruned)
gamelostpercent = 100.0f*(float)ticmiss/(float)ticruned;
else
@@ -224,7 +222,7 @@ FUNCMATH static INT32 cmpack(UINT8 a, UINT8 b)
* \param lowtimer ???
* \return True if a free acknum was found
*/
static boolean GetFreeAcknum(UINT8 *freeack)
static boolean GetFreeAcknum(UINT8 *freeack, boolean lowtimer)
{
node_t *node = &nodes[doomcom->remotenode];
INT32 i, numfreeslot = 0;
@@ -236,7 +234,6 @@ static boolean GetFreeAcknum(UINT8 *freeack)
}
for (i = 0; i < MAXACKPACKETS; i++)
{
if (!ackpak[i].acknum)
{
// For low priority packets, make sure to let freeslots so urgent packets can be sent
@@ -254,8 +251,17 @@ static boolean GetFreeAcknum(UINT8 *freeack)
node->nextacknum++;
ackpak[i].destinationnode = (UINT8)(node - nodes);
ackpak[i].length = doomcom->datalength;
ackpak[i].senttime = I_GetTime();
ackpak[i].resentnum = 0;
if (lowtimer)
{
// Lowtime means can't be sent now so try it as soon as possible
ackpak[i].senttime = 0;
ackpak[i].resentnum = 1;
}
else
{
ackpak[i].senttime = I_GetTime();
ackpak[i].resentnum = 0;
}
M_Memcpy(ackpak[i].pak.raw, netbuffer, ackpak[i].length);
*freeack = ackpak[i].acknum;
@@ -264,17 +270,46 @@ static boolean GetFreeAcknum(UINT8 *freeack)
return true;
}
}
#ifdef PARANOIA
CONS_Debug(DBG_NETPLAY, "No more free ackpacket\n");
#endif
if (netbuffer->packettype < PT_CANFAIL)
I_Error("Connection lost\n");
return false;
}
/** Counts how many acks are free
*
* \param urgent True if the type of the packet meant to
* use an ack is lower than PT_CANFAIL
* If for some reason you don't want use it
* for any packet type in particular,
* just set to false
* \return The number of free acks
*
*/
INT32 Net_GetFreeAcks(boolean urgent)
{
INT32 i, numfreeslot = 0;
INT32 n = 0; // Number of free acks found
for (i = 0; i < MAXACKPACKETS; i++)
if (!ackpak[i].acknum)
{
// For low priority packets, make sure to let freeslots so urgent packets can be sent
if (!urgent)
{
numfreeslot++;
if (numfreeslot <= URGENTFREESLOTNUM)
continue;
}
n++;
}
return n;
}
// Get a ack to send in the queue of this node
static UINT8 GetAcktosend(INT32 node)
{
@@ -287,7 +322,6 @@ static void RemoveAck(INT32 i)
INT32 node = ackpak[i].destinationnode;
DEBFILE(va("Remove ack %d\n",ackpak[i].acknum));
ackpak[i].acknum = 0;
if (nodes[node].flags & NF_CLOSE)
Net_CloseConnection(node);
}
@@ -303,16 +337,13 @@ static boolean Processackpak(void)
if (netbuffer->ackreturn && cmpack(node->remotefirstack, netbuffer->ackreturn) < 0)
{
node->remotefirstack = netbuffer->ackreturn;
// Search the ackbuffer and free it
for (i = 0; i < MAXACKPACKETS; i++)
{
if (ackpak[i].acknum && ackpak[i].destinationnode == node - nodes
&& cmpack(ackpak[i].acknum, netbuffer->ackreturn) <= 0)
{
RemoveAck(i);
}
}
}
// Received a packet with ack, queue it to send the ack back
@@ -320,7 +351,6 @@ static boolean Processackpak(void)
{
UINT8 ack = netbuffer->ack;
getackpacket++;
if (cmpack(ack, node->firstacktosend) <= 0)
{
DEBFILE(va("Discard(1) ack %d (duplicated)\n", ack));
@@ -331,7 +361,6 @@ static boolean Processackpak(void)
{
// Check if it is not already in the queue
for (i = node->acktosend_tail; i != node->acktosend_head; i = (i+1) % MAXACKTOSEND)
{
if (node->acktosend[i] == ack)
{
DEBFILE(va("Discard(2) ack %d (duplicated)\n", ack));
@@ -339,14 +368,11 @@ static boolean Processackpak(void)
goodpacket = false; // Discard packet (duplicate)
break;
}
}
if (goodpacket)
{
// Is a good packet so increment the acknowledge number,
// Then search for a "hole" in the queue
UINT8 nextfirstack = (UINT8)(node->firstacktosend + 1);
if (!nextfirstack)
nextfirstack = 1;
@@ -359,11 +385,9 @@ static boolean Processackpak(void)
if (!nextfirstack)
nextfirstack = 1;
hm1 = (UINT8)((node->acktosend_head-1+MAXACKTOSEND) % MAXACKTOSEND);
while (change)
{
change = false;
for (i = node->acktosend_tail; i != node->acktosend_head;
i = (i+1) % MAXACKTOSEND)
{
@@ -376,7 +400,6 @@ static boolean Processackpak(void)
nextfirstack = 1;
change = true;
}
if (i == node->acktosend_tail)
{
node->acktosend[node->acktosend_tail] = 0;
@@ -398,7 +421,6 @@ static boolean Processackpak(void)
// Will be incremented when the nextfirstack comes (code above)
UINT8 newhead = (UINT8)((node->acktosend_head+1) % MAXACKTOSEND);
DEBFILE(va("out of order packet (%d expected)\n", nextfirstack));
if (newhead != node->acktosend_tail)
{
node->acktosend[node->acktosend_head] = ack;
@@ -435,11 +457,8 @@ static void GotAcks(void)
INT32 i, j;
for (j = 0; j < MAXACKTOSEND; j++)
{
if (netbuffer->u.textcmd[j])
{
for (i = 0; i < MAXACKPACKETS; i++)
{
if (ackpak[i].acknum && ackpak[i].destinationnode == doomcom->remotenode)
{
if (ackpak[i].acknum == netbuffer->u.textcmd[j])
@@ -454,9 +473,6 @@ static void GotAcks(void)
ackpak[i].senttime--; // hurry up
}
}
}
}
}
}
#endif
@@ -491,7 +507,6 @@ void Net_AckTicker(void)
{
const INT32 nodei = ackpak[i].destinationnode;
node_t *node = &nodes[nodei];
if (ackpak[i].acknum && ackpak[i].senttime + NODETIMEOUT < I_GetTime())
{
if (ackpak[i].resentnum > 10 && (node->flags & NF_CLOSE))
@@ -544,10 +559,8 @@ void Net_UnAcknowledgePacket(INT32 node)
#else
INT32 hm1 = (nodes[node].acktosend_head-1+MAXACKTOSEND) % MAXACKTOSEND;
DEBFILE(va("UnAcknowledge node %d\n", node));
if (!node)
return;
if (nodes[node].acktosend[hm1] == netbuffer->ack)
{
nodes[node].acktosend[hm1] = 0;
@@ -571,7 +584,6 @@ void Net_UnAcknowledgePacket(INT32 node)
if (!nodes[node].firstacktosend)
nodes[node].firstacktosend = UINT8_MAX;
}
nodes[node].firstacktosend++;
if (!nodes[node].firstacktosend)
nodes[node].firstacktosend = 1;
@@ -590,10 +602,8 @@ static boolean Net_AllAcksReceived(void)
INT32 i;
for (i = 0; i < MAXACKPACKETS; i++)
{
if (ackpak[i].acknum)
return false;
}
return true;
}
@@ -613,7 +623,6 @@ void Net_WaitAllAckReceived(UINT32 timeout)
timeout = tictac + timeout*NEWTICRATE;
HGetPacket();
while (timeout > I_GetTime() && !Net_AllAcksReceived())
{
while (tictac == I_GetTime())
@@ -621,7 +630,6 @@ void Net_WaitAllAckReceived(UINT32 timeout)
I_Sleep(cv_sleep.value);
I_UpdateTime(cv_timescale.value);
}
tictac = I_GetTime();
HGetPacket();
Net_AckTicker();
@@ -632,7 +640,6 @@ void Net_WaitAllAckReceived(UINT32 timeout)
static void InitNode(node_t *node)
{
node->acktosend_head = node->acktosend_tail = 0;
memset(node->acktosend, 0, sizeof(node->acktosend));
node->firstacktosend = 0;
node->nextacknum = 1;
node->remotefirstack = 0;
@@ -662,14 +669,13 @@ void Net_AbortPacketType(UINT8 packettype)
#ifdef NONET
(void)packettype;
#else
for (INT32 i = 0; i < MAXACKPACKETS; i++)
{
INT32 i;
for (i = 0; i < MAXACKPACKETS; i++)
if (ackpak[i].acknum && (ackpak[i].pak.data.packettype == packettype
|| packettype == UINT8_MAX))
{
ackpak[i].acknum = 0;
}
}
#endif
}
@@ -714,7 +720,6 @@ void Net_CloseConnection(INT32 node)
// check if we are waiting for an ack from this node
for (i = 0; i < MAXACKPACKETS; i++)
{
if (ackpak[i].acknum && ackpak[i].destinationnode == node)
{
if (!forceclose)
@@ -722,7 +727,6 @@ void Net_CloseConnection(INT32 node)
else
ackpak[i].acknum = 0;
}
}
InitNode(&nodes[node]);
SV_AbortSendFiles(node);
@@ -739,8 +743,9 @@ static UINT32 NetbufferChecksum(void)
UINT32 c = 0x1234567;
const INT32 l = doomcom->datalength - 4;
const UINT8 *buf = (UINT8 *)netbuffer + 4;
INT32 i;
for (INT32 i = 0; i < l; i++, buf++)
for (i = 0; i < l; i++, buf++)
c += (*buf) * (i+1);
return LONG(c);
@@ -755,7 +760,6 @@ static void fprintfstring(char *s, size_t len)
size_t i;
for (i = 0; i < len; i++)
{
if (s[i] < 32)
{
if (!mode)
@@ -775,8 +779,6 @@ static void fprintfstring(char *s, size_t len)
}
fprintf(debugfile, "%c", s[i]);
}
}
if (mode)
fprintf(debugfile, "]");
}
@@ -831,14 +833,15 @@ const char *packettypename[NUMPACKETTYPE] =
"MOREFILESNEEDED",
"PING"
#ifdef SATURNPAK
#ifdef SATURNSYNCH
,
"WILLRESENDGAMESTATE",
"CANRECEIVEGAMESTATE",
"RECEIVEDGAMESTATE",
"ISSATURN" // special packet to identify saturn clients
// we will reserve this for now even if unused, so order wont get mangled
"ISSATURN"
#endif
};
@@ -1033,7 +1036,6 @@ static boolean ShouldDropPacket(void)
boolean HSendPacket(INT32 node, boolean reliable, UINT8 acknum, size_t packetlength)
{
doomcom->datalength = (INT16)(packetlength + BASEPACKETSIZE);
if (node == 0) // Packet is to go back to us
{
if ((rebound_head+1) % MAXREBOUND == rebound_tail)
@@ -1069,7 +1071,6 @@ boolean HSendPacket(INT32 node, boolean reliable, UINT8 acknum, size_t packetlen
// do this before GetFreeAcknum because this function backups
// the current packet
doomcom->remotenode = (INT16)node;
if (doomcom->datalength <= 0)
{
DEBFILE("HSendPacket: nothing to send\n");
@@ -1084,10 +1085,17 @@ boolean HSendPacket(INT32 node, boolean reliable, UINT8 acknum, size_t packetlen
netbuffer->ackreturn = GetAcktosend(node);
else
netbuffer->ackreturn = 0;
if (reliable)
{
if (!GetFreeAcknum(&netbuffer->ack))
if (I_NetCanSend && !I_NetCanSend())
{
if (netbuffer->packettype < PT_CANFAIL)
GetFreeAcknum(&netbuffer->ack, true);
DEBFILE("HSendPacket: Out of bandwidth\n");
return false;
}
else if (!GetFreeAcknum(&netbuffer->ack, false))
return false;
}
else
@@ -1159,6 +1167,7 @@ boolean HGetPacket(void)
while(true)
{
//nodejustjoined = I_NetGet();
I_NetGet();
if (doomcom->remotenode == -1) // No packet received
@@ -1187,6 +1196,21 @@ boolean HGetPacket(void)
DebugPrintpacket("GET");
#endif
/*// If a new node sends an unexpected packet, just ignore it
if (nodejustjoined && server
&& !(netbuffer->packettype == PT_ASKINFO
|| netbuffer->packettype == PT_SERVERINFO
|| netbuffer->packettype == PT_PLAYERINFO
|| netbuffer->packettype == PT_REQUESTFILE
|| netbuffer->packettype == PT_ASKINFOVIAMS
|| netbuffer->packettype == PT_CLIENTJOIN))
{
DEBFILE(va("New node sent an unexpected %s packet\n", packettypename[netbuffer->packettype]));
//CONS_Alert(CONS_NOTICE, "New node sent an unexpected %s packet\n", packettypename[netbuffer->packettype]);
Net_CloseConnection(doomcom->remotenode | FORCECLOSE);
continue;
}*/
// Proceed the ack and ackreturn field
if (!Processackpak())
continue; // discarded (duplicated)
@@ -1223,7 +1247,6 @@ static void Internal_FreeNodenum(INT32 nodenum)
SINT8 I_NetMakeNode(const char *hostname)
{
SINT8 newnode = -1;
if (I_NetMakeNodewPort)
{
char *localhostname = strdup(hostname);
@@ -1250,10 +1273,7 @@ void D_SetDoomcom(void)
{
if (doomcom) return;
doomcom = Z_Calloc(sizeof (doomcom_t), PU_STATIC, NULL);
doomcom->id = DOOMCOM_ID;
doomcom->numslots = doomcom->numnodes = 1;
doomcom->gametype = 0;
doomcom->consoleplayer = 0;
doomcom->extratics = 0;
}
@@ -1272,12 +1292,12 @@ boolean D_CheckNetGame(void)
I_NetGet = Internal_Get;
I_NetSend = Internal_Send;
I_NetCanSend = NULL;
I_NetCloseSocket = NULL;
I_NetFreeNodenum = Internal_FreeNodenum;
I_NetMakeNodewPort = NULL;
hardware_MAXPACKETLENGTH = MAXPACKETLENGTH;
// I_InitNetwork sets doomcom and netgame
// check and initialize the network driver
multiplayer = false;
@@ -1297,7 +1317,6 @@ boolean D_CheckNetGame(void)
server = true; // WTF? server always true???
// no! The deault mode is server. Client is set elsewhere
// when the client executes connect command.
doomcom->ticdup = 1;
if (M_CheckParm("-extratic"))
{
@@ -1327,21 +1346,19 @@ boolean D_CheckNetGame(void)
if (netgame)
multiplayer = true;
if (doomcom->id != DOOMCOM_ID)
I_Error("Doomcom buffer invalid!");
if (doomcom->numnodes > MAXNETNODES)
I_Error("Too many nodes (%d), max:%d", doomcom->numnodes, MAXNETNODES);
netbuffer = (doomdata_t *)(void *)&doomcom->data;
#ifdef HOLEPUNCH
#ifdef HOLEPUNCH
holepunchpacket = (holepunch_t *)(void *)&doomcom->data;
#endif
#endif
#ifdef DEBUGFILE
if (M_CheckParm("-debugfile"))
{
char filename[21];
INT32 k = doomcom->consoleplayer - 1;
INT32 k = consoleplayer - 1;
if (M_IsNextParm())
k = atoi(M_GetNextParm()) - 1;
while (!debugfile && k < MAXPLAYERS)
@@ -1397,7 +1414,6 @@ void Command_Ping_f(void)
INT32 i;
pingc = 0;
for (i = 1; i < MAXPLAYERS; ++i)
{
if (playeringame[i])
@@ -1475,6 +1491,7 @@ void D_CloseConnection(void)
I_NetGet = Internal_Get;
I_NetSend = Internal_Send;
I_NetCanSend = NULL;
I_NetCloseSocket = NULL;
I_NetFreeNodenum = Internal_FreeNodenum;
I_NetMakeNodewPort = NULL;
+3 -1
View File
@@ -45,10 +45,12 @@ extern boolean nodeingame[MAXNETNODES]; // Set false as nodes leave game
extern boolean serverrunning;
INT32 Net_GetFreeAcks(boolean urgent);
void Net_AckTicker(void);
// If reliable return true if packet sent, 0 else
boolean HSendPacket(INT32 node, boolean reliable, UINT8 acknum, size_t packetlength);
boolean HSendPacket(INT32 node, boolean reliable, UINT8 acknum,
size_t packetlength);
boolean HGetPacket(void);
void D_SetDoomcom(void);
#ifndef NONET
+596 -387
View File
File diff suppressed because it is too large. Load diff
+20 -4
View File
@@ -43,12 +43,25 @@ extern consvar_t cv_seenames, cv_allowseenames;
extern consvar_t cv_usemouse;
//WTF
extern consvar_t cv_mouseturn;
extern consvar_t cv_usejoystick[4]; //MAXSPLITSCREENPLAYERS
extern consvar_t cv_usejoystick;
extern consvar_t cv_usejoystick2;
extern consvar_t cv_usejoystick3;
extern consvar_t cv_usejoystick4;
#ifdef LJOYSTICK
extern consvar_t cv_joyport;
extern consvar_t cv_joyport2;
#endif
extern consvar_t cv_joyscale[4]; //MAXSPLITSCREENPLAYERS
extern consvar_t cv_joyscale;
extern consvar_t cv_joyscale2;
extern consvar_t cv_joyscale3;
extern consvar_t cv_joyscale4;
// splitscreen with second mouse
extern consvar_t cv_mouse2port;
extern consvar_t cv_usemouse2;
#if defined (__unix__) || defined (__APPLE__) || defined (UNIXCOMMON)
extern consvar_t cv_mouse2opt;
#endif
// normally in p_mobj but the .h is not read
extern consvar_t cv_itemrespawntime;
@@ -149,9 +162,8 @@ extern consvar_t cv_pingstyle;
//extern consvar_t cv_smallpos;
extern consvar_t cv_showminimapnames;
extern consvar_t cv_minihead;
extern consvar_t cv_showminimapangle;
extern consvar_t cv_showlapemblem;
extern consvar_t cv_showlapemblem;
extern consvar_t cv_showviewpointtext;
extern consvar_t cv_showdownloadprompt;
@@ -173,7 +185,9 @@ extern consvar_t cv_nametagdist;
extern consvar_t cv_showownnametag;
extern consvar_t cv_smallnametags;
extern consvar_t cv_nametagrestat;
extern consvar_t cv_nametaghop;
extern consvar_t cv_nametagscore;
extern consvar_t cv_shownametagfinish;
extern consvar_t cv_shownametagspectator;
#define SKINSELECTSPIN_PAIN 25
@@ -296,6 +310,8 @@ typedef union {
#pragma pack()
#endif
extern tic_t driftsparkGrowTimer[16];
// add game commands, needs cleanup
void D_RegisterServerCommands(void);
void D_RegisterClientCommands(void);
+59 -81
View File
@@ -64,11 +64,11 @@ static boolean SV_SendFile(INT32 node, const char *filename, UINT8 fileid);
#ifdef HAVE_CURL
size_t curlwrite_data(void *ptr, size_t size, size_t nmemb, FILE *stream);
#if (LIBCURL_VERSION_MAJOR <= 7) && (LIBCURL_VERSION_MINOR < 35)
static int curlprogress_callback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow);
#else
#if defined(CURL_AT_LEAST_VERSION) && CURL_AT_LEAST_VERSION(7, 35, 0)
static int curlprogress_callbackx(void *clientp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow);
#define XFERINFOFUNCTION
#else
static int curlprogress_callback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow);
#endif
#endif
@@ -111,17 +111,26 @@ static fileused_t transferFiles[UINT8_MAX + 1];
// Receiver structure
INT32 fileneedednum; // Number of files needed to join the server
fileneeded_t fileneeded[MAX_WADFILES]; // List of needed files
static I_mutex downloadmutex;
char downloaddir[512] = "DOWNLOAD";
file_download_t filedownload;
#ifdef CLIENT_LOADINGSCREEN
// for cl loading screen
INT32 lastfilenum = -1;
INT32 downloadcompletednum = 0;
UINT32 downloadcompletedsize = 0;
INT32 totalfilesrequestednum = 0;
UINT32 totalfilesrequestedsize = 0;
#endif
#ifdef HAVE_CURL
static CURL *http_handle;
static CURLM *multi_handle;
static UINT32 curl_dlnow;
static UINT32 curl_dltotal;
boolean curl_running = false;
boolean curl_failedwebdownload = false;
static double curl_dlnow;
static double curl_dltotal;
static time_t curl_starttime;
INT32 curl_transfers = 0;
static int curl_runninghandles = 0;
static UINT32 curl_origfilesize;
static UINT32 curl_origtotalfilesize;
@@ -212,7 +221,6 @@ void D_ParseFileneeded(INT32 fileneedednum_parm, UINT8 *fileneededstr, UINT16 fi
for (i = firstfile; i < fileneedednum; i++)
{
fileneeded[i].status = FS_NOTCHECKED; // We haven't even started looking for the file yet
fileneeded[i].justdownloaded = false;
filestatus = READUINT8(p); // The first byte is the file status
fileneeded[i].willsend = (UINT8)(filestatus >> 4);
fileneeded[i].totalsize = READUINT32(p); // The four next bytes are the file size
@@ -224,12 +232,8 @@ void D_ParseFileneeded(INT32 fileneedednum_parm, UINT8 *fileneededstr, UINT16 fi
void CL_PrepareDownloadSaveGame(const char *tmpsave)
{
#ifdef CLIENT_LOADINGSCREEN
filedownload.current = -1;
#endif
fileneedednum = 1;
fileneeded[0].status = FS_REQUESTED;
fileneeded[0].justdownloaded = false;
fileneeded[0].totalsize = UINT32_MAX;
fileneeded[0].file = NULL;
memset(fileneeded[0].md5sum, 0, 16);
@@ -544,13 +548,13 @@ INT32 CL_CheckFiles(void)
{
if (fileneeded[i].status == FS_NOTFOUND || fileneeded[i].status == FS_MD5SUMBAD || fileneeded[i].status == FS_FALLBACK)
downloadrequired = true;
if (fileneeded[i].status != FS_OPEN)
filestoload++;
if (fileneeded[i].status != FS_NOTCHECKED) //since we're running this over multiple tics now, its possible for us to come across files checked in previous tics
continue;
CONS_Debug(DBG_NETPLAY, "searching for '%s' ", fileneeded[i].filename);
// Check in already loaded files
@@ -654,10 +658,13 @@ static boolean SV_SendFile(INT32 node, const char *filename, UINT8 fileid)
q = &((*q)->next);
// Allocate a file request and append it to the file list
p = *q = (filetx_t *)calloc(1, sizeof(filetx_t)); // Initialise with zeros
p = *q = (filetx_t *)malloc(sizeof (filetx_t));
if (!p)
I_Error("SV_SendFile: No more memory\n");
// Initialise with zeros
memset(p, 0, sizeof (filetx_t));
// Allocate the file name
p->id.filename = (char *)malloc(MAX_WADPATH);
if (!p->id.filename)
@@ -736,10 +743,13 @@ void SV_SendRam(INT32 node, void *data, size_t size, freemethod_t freemethod, UI
q = &((*q)->next);
// Allocate a file request and append it to the file list
p = *q = (filetx_t *)calloc(1, sizeof(filetx_t)); // Initialise with zeros
p = *q = (filetx_t *)malloc(sizeof (filetx_t));
if (!p)
I_Error("SV_SendRam: No more memory\n");
// Initialise with zeros
memset(p, 0, sizeof (filetx_t));
p->ram = freemethod; // Remember how to free the memory block for when we're done sending it
p->id.ram = data;
p->size = (UINT32)size;
@@ -823,7 +833,6 @@ void SV_FileSendTicker(void)
netbuffer->packettype = PT_FILEFRAGMENT;
// (((sendbytes-nowsentbyte)*TICRATE)/(I_GetTime()-starttime)<(UINT32)net_bandwidth)
while (packetsent-- && filestosend != 0)
{
for (i = currentnode, j = 0; j < MAXNETNODES;
@@ -854,12 +863,8 @@ void SV_FileSendTicker(void)
if (!transferFiles[f->fileid].file)
{
CONS_Alert(CONS_ERROR, "Can't open file %s: %s\n",
I_Error("Can't open file %s: %s",
f->id.filename, strerror(errno));
SV_EndFileSend(i);
HSendPacket(i, true, 0, PT_SERVERREFUSE);
break;
}
}
@@ -964,7 +969,7 @@ void Got_Filetxpak(void)
if (filenum >= fileneedednum)
{
DEBFILE(va("filefragment not needed %d>%d\n", filenum, fileneedednum));
DEBFILE(va("fileframent not needed %d>%d\n", filenum, fileneedednum));
//I_Error("Received an unneeded file fragment (file id received: %d, file id needed: %d)\n", filenum, fileneedednum);
return;
}
@@ -985,7 +990,6 @@ void Got_Filetxpak(void)
{
UINT32 pos = LONG(netbuffer->u.filetxpak.position);
UINT16 size = SHORT(netbuffer->u.filetxpak.size);
// Use a special trick to know when the file is complete (not always used)
// WARNING: file fragments can arrive out of order so don't stop yet!
if (pos & 0x80000000)
@@ -1005,16 +1009,15 @@ void Got_Filetxpak(void)
fclose(file->file);
file->file = NULL;
file->status = FS_FOUND;
file->justdownloaded = true;
CONS_Printf(M_GetText("Downloading %s...(done)\n"),
filename);
#ifndef NONET
filedownload.completednum++;
filedownload.completedsize += file->totalsize;
downloadcompletednum++;
downloadcompletedsize += file->totalsize;
#endif
}
}
else if (!file->justdownloaded)
else
{
const char *s;
switch(file->status)
@@ -1037,7 +1040,6 @@ void Got_Filetxpak(void)
}
I_Error("Received a file not requested (file id: %d, file status: %s)\n", filenum, s);
}
// Send ack back quickly
if (++filetime == 3)
{
@@ -1046,7 +1048,7 @@ void Got_Filetxpak(void)
}
#ifdef CLIENT_LOADINGSCREEN
filedownload.current = filenum;
lastfilenum = filenum;
#endif
}
@@ -1195,7 +1197,9 @@ filestatus_t findfile(char *filename, const UINT8 *wantedmd5sum, boolean complet
#ifdef HAVE_CURL
size_t curlwrite_data(void *ptr, size_t size, size_t nmemb, FILE *stream)
{
return fwrite(ptr, size, nmemb, stream);
size_t written;
written = fwrite(ptr, size, nmemb, stream);
return written;
}
#ifdef XFERINFOFUNCTION
@@ -1209,12 +1213,12 @@ static int curlprogress_callbackx(void *clientp, curl_off_t dltotal, curl_off_t
curtime = time(NULL);
curl_dlnow = (UINT32)dlnow;
curl_dltotal = (UINT32)dltotal;
curl_dlnow = dlnow;
curl_dltotal = dltotal;
if (curtime > curl_starttime)
{
getbytes = ((double)dlnow) / (curtime - curl_starttime); // To-do: Make this more accurate???
getbytes = curl_dlnow / (curtime - curl_starttime); // To-do: Make this more accurate???
}
else
{
@@ -1234,12 +1238,12 @@ static int curlprogress_callback(void *clientp, double dltotal, double dlnow, do
curtime = time(NULL);
curl_dlnow = (UINT32)dlnow;
curl_dltotal = (UINT32)dltotal;
curl_dlnow = dlnow;
curl_dltotal = dltotal;
if (curtime > curl_starttime)
{
getbytes = ((double)dlnow) / (curtime - curl_starttime); // To-do: Make this more accurate???
getbytes = curl_dlnow / (curtime - curl_starttime); // To-do: Make this more accurate???
}
else
{
@@ -1281,10 +1285,10 @@ void CURLPrepareFile(const char* url, int dfilenum)
curl_easy_setopt(http_handle, CURLOPT_URL, va("%s/%s", url, curl_realname));
// Only allow HTTP and HTTPS
#if (LIBCURL_VERSION_MAJOR <= 7) && (LIBCURL_VERSION_MINOR < 85)
curl_easy_setopt(http_handle, CURLOPT_PROTOCOLS, CURLPROTO_HTTP|CURLPROTO_HTTPS);
#else
#if defined(CURL_AT_LEAST_VERSION) && CURL_AT_LEAST_VERSION(7, 85, 0)
curl_easy_setopt(http_handle, CURLOPT_PROTOCOLS_STR, "http,https");
#else
curl_easy_setopt(http_handle, CURLOPT_PROTOCOLS, CURLPROTO_HTTP|CURLPROTO_HTTPS);
#endif
curl_easy_setopt(http_handle, CURLOPT_USERAGENT, va("SRB2Kart/v%d.%d", VERSION, SUBVERSION)); // Set user agent as some servers won't accept invalid user agents.
@@ -1306,21 +1310,6 @@ void CURLPrepareFile(const char* url, int dfilenum)
strcatbf(curl_curfile->filename, downloaddir, "/");
curl_curfile->file = fopen(curl_curfile->filename, "wb");
if (!curl_curfile->file)
{
CONS_Alert(CONS_ERROR, "Couldnt open %s for writing!\nAborting file download.\nCheck if you have write access to your download folder!\n", curl_curfile->filename);
CL_AbortConnection();
M_StartMessage(M_GetText(
"An error occured when trying to\n"
"download missing addons.\n"
"See the console or log file\n"
"for additional details.\n\n"
"Press ESC\n"
), NULL, MM_NOTHING);
return;
}
curl_easy_setopt(http_handle, CURLOPT_WRITEDATA, curl_curfile->file);
curl_easy_setopt(http_handle, CURLOPT_WRITEFUNCTION, curlwrite_data);
curl_easy_setopt(http_handle, CURLOPT_NOPROGRESS, 0L);
@@ -1331,34 +1320,26 @@ void CURLPrepareFile(const char* url, int dfilenum)
#endif
curl_curfile->status = FS_DOWNLOADING;
lastfilenum = dfilenum;
curl_multi_add_handle(multi_handle, http_handle);
curl_multi_perform(multi_handle, &curl_runninghandles);
curl_starttime = time(NULL);
filedownload.current = dfilenum;
filedownload.http_running = true;
curl_running = true;
#ifdef HAVE_THREADS
I_spawn_thread("http-download", (I_thread_fn)CURLGetFile, NULL);
#endif
}
else
filedownload.http_running = false;
}
void CURLAbortFile(void)
{
filedownload.http_running = false;
// lock and unlock to wait for the download thread to exit
I_lock_mutex(&downloadmutex);
I_unlock_mutex(downloadmutex);
curl_running = false;
}
void CURLGetFile(void)
{
I_lock_mutex(&downloadmutex);
CURLMcode mc; /* return code used by curl_multi_wait() */
CURLcode easyres; /* Return from easy interface */
CURLMsg *m; /* for picking up messages with the transfer status */
@@ -1366,8 +1347,10 @@ void CURLGetFile(void)
int msgs_left; /* how many messages are left */
const char *easy_handle_error;
boolean running = true;
long response_code = 0;
static char *filename;
while (running && filedownload.http_running)
while (running && curl_running)
{
if (curl_runninghandles)
{
@@ -1381,7 +1364,6 @@ void CURLGetFile(void)
CONS_Alert(CONS_WARNING, "curl_multi_wait() failed, code %d.\n", mc);
continue;
}
curl_curfile->currentsize = curl_dlnow;
curl_curfile->totalsize = curl_dltotal;
}
@@ -1395,13 +1377,11 @@ void CURLGetFile(void)
e = m->easy_handle;
easyres = m->data.result;
char *filename = Z_StrDup(curl_realname);
filename = Z_StrDup(curl_realname);
nameonly(filename);
if (easyres != CURLE_OK)
{
long response_code = 0;
if (easyres == CURLE_HTTP_RETURNED_ERROR)
curl_easy_getinfo(e, CURLINFO_RESPONSE_CODE, &response_code);
@@ -1409,7 +1389,7 @@ void CURLGetFile(void)
curl_curfile->status = FS_FALLBACK;
curl_curfile->currentsize = curl_origfilesize;
curl_curfile->totalsize = curl_origtotalfilesize;
filedownload.http_failed = true;
curl_failedwebdownload = true;
fclose(curl_curfile->file);
remove(curl_curfile->filename);
CONS_Printf(M_GetText("Failed to download %s (%s)\n"), filename, easy_handle_error);
@@ -1422,38 +1402,36 @@ void CURLGetFile(void)
{
CONS_Alert(CONS_ERROR, M_GetText("HTTP Download of %s finished but is corrupt or has been modified\n"), filename);
curl_curfile->status = FS_FALLBACK;
filedownload.http_failed = true;
curl_failedwebdownload = true;
}
else
{
CONS_Printf(M_GetText("Finished HTTP download of %s\n"), filename);
filedownload.completednum++;
filedownload.completedsize += curl_curfile->totalsize;
downloadcompletednum++;
downloadcompletedsize += curl_curfile->totalsize;
curl_curfile->status = FS_FOUND;
}
}
Z_Free(filename);
curl_curfile->file = NULL;
filedownload.remaining--;
curl_transfers--;
curl_multi_remove_handle(multi_handle, e);
curl_easy_cleanup(e);
if (!filedownload.remaining)
if (!curl_transfers)
break;
}
}
}
if (!filedownload.remaining || !filedownload.http_running)
if (!curl_transfers || !curl_running)
{
curl_multi_cleanup(multi_handle);
curl_global_cleanup();
multi_handle = NULL;
}
filedownload.http_running = false;
I_unlock_mutex(downloadmutex);
curl_running = false;
}
HTTP_login *
+8 -20
View File
@@ -13,7 +13,6 @@
#ifndef __D_NETFIL__
#define __D_NETFIL__
#include "d_clisrv.h"
#include "w_wad.h"
typedef enum
@@ -46,35 +45,24 @@ typedef struct
UINT32 currentsize;
UINT32 totalsize;
filestatus_t status; // The value returned by recsearch
boolean justdownloaded; // To prevent late fragments from causing an I_Error
} fileneeded_t;
extern INT32 fileneedednum;
extern fileneeded_t fileneeded[MAX_WADFILES];
extern char downloaddir[512];
typedef struct
{
#ifdef CLIENT_LOADINGSCREEN
INT32 current;
INT32 completednum;
UINT32 completedsize;
INT32 totalnum;
UINT32 totalsize;
extern INT32 lastfilenum;
extern INT32 downloadcompletednum;
extern UINT32 downloadcompletedsize;
extern INT32 totalfilesrequestednum;
extern UINT32 totalfilesrequestedsize;
#endif
#ifdef HAVE_CURL
INT32 remaining;
boolean http_failed;
boolean http_running;
char http_source[MAX_MIRROR_LENGTH+1];
#endif
} file_download_t;
extern file_download_t filedownload;
#ifdef HAVE_CURL
extern boolean curl_failedwebdownload;
extern boolean curl_running;
extern INT32 curl_transfers;
typedef struct HTTP_login HTTP_login;
+6 -19
View File
@@ -351,21 +351,10 @@ typedef enum
typedef enum
{
LAP_CUR,
LAP_BEST,
LAP_LAST,
LAP__MAX
} laptime_e;
// yes i made a whole struct for this :chonkbuncle:
typedef struct squishdance_s
{
tic_t countdown; // hold "custom 3" for 2 seconds to engange le dance
tic_t time;
fixed_t work;
fixed_t ang;
fixed_t bounce; // hehe squishy
} squishdance_t;
// ========================================================================
// PLAYER STRUCTURE
// ========================================================================
@@ -412,8 +401,9 @@ typedef struct player_s
INT32 kartstuff[NUMKARTSTUFF];
angle_t frameangle; // for the player add the ability to have the sprite only face other angles
angle_t old_frameangle, old_frameangle2;
// SRB2Kart CEP: Sliptide rolling
INT32 sliptidemem;
angle_t sliproll;
INT16 lturn_max[MAXPREDICTTICS]; // What's the expected turn value for full-left for a number of frames back (to account for netgame latency)?
@@ -423,6 +413,8 @@ typedef struct player_s
// See pflags_t, above.
pflags_t pflags;
UINT16 postimgflags;
// playing animation.
panim_t panim;
@@ -560,14 +552,9 @@ typedef struct player_s
UINT8 hitemvictim;
UINT8 splitscreenindex;
tic_t driftsparkGrowTimer;
fixed_t spinoutrot; // When a player spins out, this value increments modulus 360.
squishdance_t squishdance;
#ifdef HWRENDER
fixed_t fovadd; // adjust FOV for hw rendering
#endif
} player_t;
#endif
-7
View File
@@ -17,8 +17,6 @@
#ifndef __D_THINK__
#define __D_THINK__
#include "doomdef.h"
#ifdef __GNUG__
#pragma interface
#endif
@@ -51,11 +49,6 @@ typedef struct thinker_s
// killough 11/98: count of how many other objects reference
// this one using pointers. Used for garbage collection.
INT32 references;
boolean cachable;
#ifdef PARANOIA
INT32 debug_mobjtype;
tic_t debug_time;
#endif
} thinker_t;
#endif
+35 -125
View File
@@ -14,6 +14,7 @@
#include "d_main.h" // for srb2home
#include "g_game.h"
#include "sounds.h"
#include "info.h"
#include "d_think.h"
#include "m_argv.h"
#include "z_zone.h"
@@ -28,16 +29,16 @@
#include "p_local.h" // for var1 and var2, and some constants
#include "p_setup.h"
#include "r_data.h"
#include "r_fps.h"
#include "r_patch.h"
#include "r_sky.h"
#include "r_draw.h" // translation colormap consts (for lua)
#include "fastcmp.h"
#include "lua_script.h"
#include "lua_glib.h"
#include "lua_hook.h"
#include "d_clisrv.h"
#include "v_video.h" // video flags (for lua)
#include "lua_glib.h"
#include "lua_hook.h"
#include "lua_script.h"
#include "lua_libs.h"
@@ -47,14 +48,13 @@
// Free slot names
// The crazy word-reading stuff uses these.
char *FREE_STATES[NUMSTATEFREESLOTS];
char *FREE_MOBJS[NUMMOBJFREESLOTS];
UINT8 used_spr[(NUMSPRITEFREESLOTS / 8) + 1]; // Bitwise flag for sprite freeslot in use! I would use ceil() here if I could, but it only saves 1 byte of memory anyway.
static char *FREE_STATES[NUMSTATEFREESLOTS];
static char *FREE_MOBJS[NUMMOBJFREESLOTS];
static UINT8 used_spr[(NUMSPRITEFREESLOTS / 8) + 1]; // Bitwise flag for sprite freeslot in use! I would use ceil() here if I could, but it only saves 1 byte of memory anyway.
#define initfreeslots() {\
memset(FREE_STATES,0,sizeof(char *) * NUMSTATEFREESLOTS);\
memset(FREE_MOBJS,0,sizeof(char *) * NUMMOBJFREESLOTS);\
memset(used_spr,0,sizeof(UINT8) * ((NUMSPRITEFREESLOTS / 8) + 1));\
memset(FREE_STATES,0,sizeof(char *) * NUMSTATEFREESLOTS);\
memset(FREE_MOBJS,0,sizeof(char *) * NUMMOBJFREESLOTS);\
memset(used_spr,0,sizeof(UINT8) * ((NUMSPRITEFREESLOTS / 8) + 1));\
}
// Crazy word-reading stuff
@@ -690,20 +690,6 @@ static const struct {
{NULL, 0}
};
static mapheader_lighting_t *usemaplighting(INT32 mapnum, const char *word)
{
if (fastncmp(word, "ENCORE", 6))
{
mapheaderinfo[mapnum]->use_encore_lighting = true;
return &mapheaderinfo[mapnum]->lighting_encore;
}
else
{
return &mapheaderinfo[mapnum]->lighting;
}
}
static void readlevelheader(MYFILE *f, INT32 num, INT32 wadnum)
{
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
@@ -997,35 +983,6 @@ static void readlevelheader(MYFILE *f, INT32 num, INT32 wadnum)
}*/
else if (fastcmp(word, "MOBJSCALE"))
mapheaderinfo[num-1]->mobj_scale = get_number(word2);
else if (fastcmp(word, "LIGHTCONTRAST") || fastcmp(word, "ENCORELIGHTCONTRAST"))
{
mapheader_lighting_t *lighting = usemaplighting(num-1, word);
lighting->light_contrast = (UINT8)i;
lighting->use_custom_light = true;
}
else if (fastcmp(word, "SPRITEBACKLIGHT") || fastcmp(word, "ENCORESPRITEBACKLIGHT"))
{
mapheader_lighting_t *lighting = usemaplighting(num-1, word);
lighting->sprite_backlight = (SINT8)i;
lighting->use_custom_light = true;
}
else if (fastcmp(word, "LIGHTANGLE") || fastcmp(word, "ENCORELIGHTANGLE"))
{
mapheader_lighting_t *lighting = usemaplighting(num-1, word);
if (fastcmp(word2, "EVEN"))
{
lighting->use_light_angle = false;
lighting->light_angle = 0;
}
else
{
lighting->use_light_angle = true;
lighting->light_angle = FixedAngle(FloatToFixed(atof(word2)));
}
lighting->use_custom_light = true;
}
// Individual triggers for level flags, for ease of use (and 2.0 compatibility)
else if (fastcmp(word, "SCRIPTISFILE"))
@@ -1536,6 +1493,9 @@ actionpointer_t actionpointers[] =
{{A_SpawnObjectRelative}, "A_SPAWNOBJECTRELATIVE"},
{{A_ChangeAngleRelative}, "A_CHANGEANGLERELATIVE"},
{{A_ChangeAngleAbsolute}, "A_CHANGEANGLEABSOLUTE"},
{{A_RollAngle}, "A_ROLLANGLE"},
{{A_ChangeRollAngleRelative},"A_CHANGEROLLANGLERELATIVE"},
{{A_ChangeRollAngleAbsolute},"A_CHANGEROLLANGLEABSOLUTE"},
{{A_PlaySound}, "A_PLAYSOUND"},
{{A_FindTarget}, "A_FINDTARGET"},
{{A_FindTracer}, "A_FINDTRACER"},
@@ -1799,7 +1759,7 @@ static void readsound(MYFILE *f, INT32 num, const char *savesfxnames[])
* \sa readmaincfg()
* \author Graue <graue@oceanbase.org>
*/
/*static boolean GoodDataFileName(const char *s)
static boolean GoodDataFileName(const char *s)
{
const char *p;
const char *tail = ".dat";
@@ -1819,7 +1779,7 @@ static void readsound(MYFILE *f, INT32 num, const char *savesfxnames[])
if (fasticmp(s, "online.dat")) return false; // SRB2Kart online replay folder
return true;
}*/
}
static void reademblemdata(MYFILE *f, INT32 num)
{
@@ -2597,10 +2557,10 @@ static void readmaincfg(MYFILE *f)
{
maxXtraLife = (UINT8)get_number(word2);
}
else if (fastcmp(word, "GAMEDATA"))
{
// just ignore it but dont throw a warning
/*size_t filenamelen;
size_t filenamelen;
// Check the data filename so that mods
// can't write arbitrary files.
@@ -2624,7 +2584,7 @@ static void readmaincfg(MYFILE *f)
// can't use sprintf since there is %u in savegamename
strcatbf(savegamename, srb2home, PATHSEP);
refreshdirmenu |= REFRESHDIR_GAMEDATA;*/
refreshdirmenu |= REFRESHDIR_GAMEDATA;
}
else if (fastcmp(word, "RESETDATA"))
{
@@ -3190,7 +3150,7 @@ void DEH_LoadDehackedLump(lumpnum_t lumpnum)
// RegEx to generate this from info.h: ^\tS_([^,]+), --> \t"S_\1",
// I am leaving the prefixes solely for clarity to programmers,
// because sadly no one remembers this place while searching for full state names.
const char *const STATE_LIST[] = { // array length left dynamic for sanity testing later.
static const char *const STATE_LIST[] = { // array length left dynamic for sanity testing later.
"S_NULL",
"S_UNKNOWN",
"S_INVISIBLE", // state for invisible sprite
@@ -6404,7 +6364,7 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
// RegEx to generate this from info.h: ^\tMT_([^,]+), --> \t"MT_\1",
// I am leaving the prefixes solely for clarity to programmers,
// because sadly no one remembers this place while searching for full state names.
const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity testing later.
static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity testing later.
"MT_NULL",
"MT_UNKNOWN",
@@ -7195,7 +7155,7 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t
#endif
};
const char *const MOBJFLAG_LIST[] = {
static const char *const MOBJFLAG_LIST[] = {
"SPECIAL",
"SOLID",
"SHOOTABLE",
@@ -7231,7 +7191,7 @@ const char *const MOBJFLAG_LIST[] = {
};
// \tMF2_(\S+).*// (.+) --> \t"\1", // \2
const char *const MOBJFLAG2_LIST[] = {
static const char *const MOBJFLAG2_LIST[] = {
"AXIS", // It's a NiGHTS axis! (For faster checking)
"TWOD", // Moves like it's in a 2D level
"DONTRESPAWN", // Don't respawn this object!
@@ -7264,7 +7224,7 @@ const char *const MOBJFLAG2_LIST[] = {
NULL
};
const char *const MOBJEFLAG_LIST[] = {
static const char *const MOBJEFLAG_LIST[] = {
"ONGROUND", // The mobj stands on solid floor (not on another mobj or in air)
"JUSTHITFLOOR", // The mobj just hit the floor while falling, this is cleared on next frame
"TOUCHWATER", // The mobj stands in a sector with water, and touches the surface
@@ -7282,14 +7242,14 @@ const char *const MOBJEFLAG_LIST[] = {
NULL
};
const char *const MAPTHINGFLAG_LIST[4] = {
static const char *const MAPTHINGFLAG_LIST[4] = {
NULL,
"OBJECTFLIP", // Reverse gravity flag for objects.
"OBJECTSPECIAL", // Special flag used with certain objects.
"AMBUSH" // Deaf monsters/do not react to sound.
};
const char *const PLAYERFLAG_LIST[] = {
static const char *const PLAYERFLAG_LIST[] = {
// Flip camera angle with gravity flip prefrence.
"FLIPCAM",
@@ -7361,7 +7321,7 @@ const char *const PLAYERFLAG_LIST[] = {
};
// Linedef flags
const char *const ML_LIST[16] = {
static const char *const ML_LIST[16] = {
"IMPASSIBLE",
"BLOCKMONSTERS",
"TWOSIDED",
@@ -7382,7 +7342,7 @@ const char *const ML_LIST[16] = {
// This DOES differ from r_draw's Color_Names, unfortunately.
// Also includes Super colors
const char *COLOR_ENUMS[] = { // Rejigged for Kart.
static const char *COLOR_ENUMS[] = { // Rejigged for Kart.
"NONE", // SKINCOLOR_NONE
"WHITE", // SKINCOLOR_WHITE
"SILVER", // SKINCOLOR_SILVER
@@ -7550,7 +7510,7 @@ const char *COLOR_ENUMS[] = { // Rejigged for Kart.
"CSUPER5" // SKINCOLOR_CSUPER5,
};
const char *const POWERS_LIST[] = {
static const char *const POWERS_LIST[] = {
"INVULNERABILITY",
"SNEAKERS",
"FLASHING",
@@ -7585,7 +7545,7 @@ const char *const POWERS_LIST[] = {
"INGOOP" // In goop
};
const char *const KARTSTUFF_LIST[] = {
static const char *const KARTSTUFF_LIST[] = {
"POSITION",
"OLDPOSITION",
"POSITIONDELAY",
@@ -7672,7 +7632,7 @@ const char *const KARTSTUFF_LIST[] = {
"GROWCANCEL"
};
const char *const HUDITEMS_LIST[] = {
static const char *const HUDITEMS_LIST[] = {
"LIVESNAME",
"LIVESPIC",
"LIVESNUM",
@@ -7761,18 +7721,7 @@ struct {
{"FF_HORIZONTALFLIP",FF_HORIZONTALFLIP},
{"FF_PAPERSPRITE",FF_PAPERSPRITE},
{"FF_ANIMATE",FF_ANIMATE},
// brightness
{"FF_BRIGHTMASK",FF_BRIGHTMASK},
{"FF_FULLBRIGHT",FF_FULLBRIGHT},
{"FF_SEMIBRIGHT",FF_SEMIBRIGHT},
{"FF_FULLDARK",FF_FULLDARK},
// blending
{"FF_BLENDMASK",FF_BLENDMASK},
{"FF_BLENDSHIFT",FF_BRIGHTMASK},
{"FF_ADD",FF_ADD},
{"FF_SUBTRACT",FF_SUBTRACT},
{"FF_REVERSESUBTRACT",FF_REVERSESUBTRACT},
{"FF_MODULATE",FF_MODULATE},
{"FF_TRANSMASK",FF_TRANSMASK},
{"FF_TRANSSHIFT",FF_TRANSSHIFT},
// new preshifted translucency (used in source)
@@ -7808,15 +7757,6 @@ struct {
{"tr_trans90",tr_trans90},
{"NUMTRANSMAPS",NUMTRANSMAPS},
// Alpha styles (blend modes)
{"AST_COPY",AST_COPY},
{"AST_TRANSLUCENT",AST_TRANSLUCENT},
{"AST_ADD",AST_ADD},
{"AST_SUBTRACT",AST_SUBTRACT},
{"AST_REVERSESUBTRACT",AST_REVERSESUBTRACT},
{"AST_MODULATE",AST_MODULATE},
{"AST_OVERLAY",AST_OVERLAY},
// Type of levels
{"TOL_SP",TOL_SP},
{"TOL_COOP",TOL_COOP},
@@ -8181,14 +8121,6 @@ struct {
{"V_CHARCOLORSHIFT",V_CHARCOLORSHIFT},
{"V_ALPHASHIFT",V_ALPHASHIFT},
// Blending
{"V_BLENDSHIFT",V_BLENDSHIFT},
{"V_BLENDMASK",V_BLENDMASK},
{"B_ADD",B_ADD},
{"B_SUBTRACT",B_SUBTRACT},
{"B_REVERSESUBTRACT",B_REVERSESUBTRACT},
{"B_MODULATE",B_MODULATE},
//Kick Reasons
{"KR_KICK",KR_KICK},
{"KR_PINGLIMIT",KR_PINGLIMIT},
@@ -8613,16 +8545,6 @@ static int lua_enumlib_mariomode_get(lua_State *L)
return 1;
}
static int lua_enumlib_replayfreecam_get(lua_State *L)
{
if (dedicated) // huh?
lua_pushboolean(L, false);
else
lua_pushboolean(L, camera[R_GetViewNumber()].freecam);
return 1;
}
static int lua_enumlib_twodlevel_get(lua_State *L)
{
lua_pushboolean(L, twodlevel);
@@ -9227,6 +9149,9 @@ int LUA_EnumLib(lua_State *L)
PUSHGETTER(globalweather, u8);
PUSHGETTER(levelskynum, i32);
PUSHGETTER(globallevelskynum, i32);
PUSHGETTER((*mapmusname), str);
PUSHGETTER(mapmusflags, u16);
PUSHGETTER(mapmusposition, u32);
PUSHGETTER(gravity, fxp);
PUSHGETTER(gamespeed, u8);
PUSHGETTER(encoremode, bool);
@@ -9241,21 +9166,6 @@ int LUA_EnumLib(lua_State *L)
PUSHGETTER(racecountdown, u32);
PUSHGETTER(exitcountdown, u32);
lua_pushcfunction(L, lua_glib_new_getter);
lua_pushliteral(L, "mapmusflags");
lua_glib_push_u16_getter(L, &mapmusic.flags);
lua_call(L, 2, 0);
lua_pushcfunction(L, lua_glib_new_getter);
lua_pushliteral(L, "mapmusposition");
lua_glib_push_u32_getter(L, &mapmusic.position);
lua_call(L, 2, 0);
lua_pushcfunction(L, lua_glib_new_getter);
lua_pushliteral(L, "mapmusname");
lua_glib_push_str_getter(L, mapmusic.name);
lua_call(L, 2, 0);
lua_pushcfunction(L, lua_glib_new_getter);
lua_pushliteral(L, "mariomode");
lua_pushcfunction(L, lua_enumlib_mariomode_get);
@@ -9308,7 +9218,7 @@ int LUA_EnumLib(lua_State *L)
lua_pushcfunction(L, lua_glib_new_getter);
lua_pushliteral(L, "replayfreecam");
lua_pushcfunction(L, lua_enumlib_replayfreecam_get);
lua_glib_push_bool_getter(L, &demo.freecam);
lua_call(L, 2, 0);
if (!mathlib)
-20
View File
@@ -14,26 +14,6 @@
#define __DEHACKED_H__
#include "m_fixed.h" // for get_number
#include "info.h"
// Free slot names
// The crazy word-reading stuff uses these.
extern char *FREE_STATES[NUMSTATEFREESLOTS];
extern char *FREE_MOBJS[NUMMOBJFREESLOTS];
extern UINT8 used_spr[(NUMSPRITEFREESLOTS / 8) + 1]; // Bitwise flag for sprite freeslot in use! I would use ceil() here if I could, but it only saves 1 byte of memory anyway.
extern const char *const STATE_LIST[];
extern const char *const MOBJTYPE_LIST[];
extern const char *const MOBJFLAG_LIST[];
extern const char *const MOBJFLAG2_LIST[]; // \tMF2_(\S+).*// (.+) --> \t"\1", // \2
extern const char *const MOBJEFLAG_LIST[];
extern const char *const MAPTHINGFLAG_LIST[4];
extern const char *const PLAYERFLAG_LIST[];
extern const char *const ML_LIST[]; // Linedef flags
extern const char *COLOR_ENUMS[];
extern const char *const POWERS_LIST[];
extern const char *const KARTSTUFF_LIST[];
extern const char *const HUDITEMS_LIST[];
void DEH_LoadDehackedLump(lumpnum_t lumpnum);
void DEH_LoadDehackedLumpPwad(UINT16 wad, UINT16 lump);
+4 -10
View File
@@ -388,7 +388,7 @@ static void DRPC_GotServerIP(UINT32 address)
--------------------------------------------------*/
static const char *DRPC_GetServerIP(void)
{
const char *address;
const char *address;
// If you're connected
if (I_GetNodeAddress && (address = I_GetNodeAddress(servernode)) != NULL)
@@ -489,7 +489,7 @@ void DRPC_UpdatePresence(void)
{
#endif
discordPresence.state = "Private";
#ifdef MASTERSERVER
#ifdef MASTERSERVER
}
#endif
@@ -571,15 +571,9 @@ void DRPC_UpdatePresence(void)
{
// Map name on tool tip
char *title = G_BuildMapTitle(gamemap);
if (title)
{
snprintf(mapname, 48, "Map: %s", title);
Z_Free(title);
}
else
snprintf(mapname, 48, "Map: UNKNOWN");
snprintf(mapname, 48, "Map: %s", title);
discordPresence.largeImageText = mapname;
Z_Free(title);
}
if (gamestate == GS_LEVEL && Playing())
+28 -36
View File
@@ -21,6 +21,7 @@
#define SOUND_DUMMY 0
#define SOUND_SDL 1
#define SOUND_MIXER 2
#define SOUND_FMOD 3
#ifndef SOUND
#ifdef HAVE_SDL
@@ -28,6 +29,9 @@
// Use Mixer interface?
#ifdef HAVE_MIXER
#define SOUND SOUND_MIXER
#ifdef HW3SOUND
#undef HW3SOUND
#endif
#endif
// Use generic SDL interface.
@@ -36,8 +40,18 @@
#endif
#else // No SDL.
// No more interfaces. :(
#define SOUND SOUND_DUMMY
// Use FMOD?
#ifdef HAVE_FMOD
#define SOUND SOUND_FMOD
#ifdef HW3SOUND
#undef HW3SOUND
#endif
#else
// No more interfaces. :(
#define SOUND SOUND_DUMMY
#endif
#endif
#endif
@@ -113,8 +127,8 @@ extern char logfilename[1024];
#else
#define VERSION 1 // Game version
#define SUBVERSION 6 // more precise version number
#define VERSIONSTRING "Saturn v8.2"
#define VERSIONSTRINGW L"Saturn v8.2"
#define VERSIONSTRING "Saturn v7.1"
#define VERSIONSTRINGW L"Saturn v7.1"
// Hey! If you change this, add 1 to the MODVERSION below! Otherwise we can't force updates!
// And change CMakeLists.txt (not src/, but in root), for CMake users!
// AND appveyor.yml, for the build bots!
@@ -508,30 +522,15 @@ extern boolean capslock;
// i_system.c, replace getchar() once the keyboard has been appropriated
INT32 I_GetKey(void);
/* http://www.cse.yorku.ca/~oz/hash.html */
static inline
UINT32 quickncasehash (const char *p, size_t n)
{
size_t i = 0;
UINT32 x = 5381;
while (i < n && p[i])
{
x = (x * 33) ^ tolower(p[i]);
i++;
}
return x;
}
#ifndef min // Double-Check with WATTCP-32's cdefs.h
#define min(x, y) (((x) < (y)) ? (x) : (y))
#endif
#ifndef max // Double-Check with WATTCP-32's cdefs.h
#define max(x, y) (((x) > (y)) ? (x) : (y))
#endif
#ifndef CLAMP
#define CLAMP(x, y, z) ((x) < (y) ? (y) : ((x) > (z) ? (z) : (x)))
#define CLAMP(x, min_val, max_val) ((x) < (min_val) ? (min_val) : ((x) > (max_val) ? (max_val) : (x)))
#endif
#ifndef M_PIl
@@ -547,19 +546,6 @@ UINT32 quickncasehash (const char *p, size_t n)
#define DBL_EPSILON 2.2204460492503131e-16l
#endif
#if defined(__GNUC__) || defined(__clang__)
#ifndef LIKELY
#define LIKELY(x) __builtin_expect(!!(x), 1)
#endif
#ifndef UNLIKELY
#define UNLIKELY(x) __builtin_expect(!!(x), 0)
#endif
#else
#define LIKELY(x) (x)
#define UNLIKELY(x) (x)
#endif
// An assert-type mechanism.
#ifdef PARANOIA
#define I_Assert(e) ((e) ? (void)0 : I_Error("assert failed: %s, file %s, line %d", #e, __FILE__, __LINE__))
@@ -584,15 +570,21 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
#ifndef NONET
//-- SATURN __
/// Enable gamestate resynching between Saturn servers and clients
/// Like SRB2 and RR does
/// Still highly experimental
#ifdef DOSATURNSYNCH
#define SATURNSYNCH
/// Detect if a client is on Saturn in the clientconfig.
/// To seperately allow them to join or block joining from vanilla clients.
#ifdef DOSATURNJOIN
#define SATURNJOIN
#endif
#endif
/// Server detection for if a connecting client is on Saturn.
/// This also enables gamestate resynching between Saturn servers and clients
/// Like SRB2 and RR does
/// For stuff like extra synching, etc.
#ifdef DOSATURNPAK
#define SATURNPAK
#endif
+26 -38
View File
@@ -30,26 +30,16 @@
// =============================
// Selected by user.
typedef struct
{
char name[7]; // Music name, up to 6-character name
void *data; // Music lump
UINT16 flags; // Track and reset bit
boolean looping; // Is this music looping?
UINT32 position; // Position to jump to
UINT32 resume; // Saved Position when music was stopped
UINT32 fadeinms; // Fade in time in ms (used for queue)
} music_t;
extern music_t mapmusic;
extern INT16 gamemap;
extern char mapmusname[7];
extern UINT16 mapmusflags;
extern UINT32 mapmusposition;
extern UINT32 mapmusresume;
#define MUSIC_TRACKMASK 0x0FFF // ----************
#define MUSIC_RELOADRESET 0x8000 // *---------------
#define MUSIC_FORCERESET 0x4000 // -*--------------
// Use other bits if necessary.
extern INT16 gamemap;
extern INT16 maptol;
extern UINT8 globalweather;
extern INT32 curWeather;
@@ -222,15 +212,6 @@ typedef struct
char value[256]; // 255 usable characters. If this seriously isn't enough then wtf.
} customoption_t;
typedef struct
{
boolean use_custom_light;
UINT8 light_contrast; ///< Range of wall lighting. 0 is no lighting.
SINT8 sprite_backlight; ///< Subtract from wall lighting for sprites only.
boolean use_light_angle; ///< When false, wall lighting is evenly distributed. When true, wall lighting is directional.
angle_t light_angle; ///< Angle of directional wall lighting.
} mapheader_lighting_t;
/** Map header information.
*/
typedef struct
@@ -244,7 +225,7 @@ typedef struct
INT16 nextlevel; ///< Map number of next level, or 1100-1102 to end.
char musname[7]; ///< Music track to play. "" for no music.
UINT16 mustrack; ///< Subsong to play. Only really relevant for music modules and specific formats supported by GME. 0 to ignore.
UINT32 muspos; ///< Music position to jump to.
UINT32 muspos; ///< Music position to jump to.
char forcecharacter[17]; ///< (SKINNAMESIZE+1) Skin to switch to or "" to disable.
UINT8 weather; ///< 0 = sunny day, 1 = storm, 2 = snow, 3 = rain, 4 = blank, 5 = thunder w/o rain, 6 = rain w/o lightning, 7 = heat wave.
INT16 skynum; ///< Sky number to use.
@@ -276,11 +257,7 @@ typedef struct
// SRB2kart
//boolean automap; ///< Displays a level's white map outline in modified games
fixed_t mobj_scale; ///< Replacement for TOL_ERZ3
mapheader_lighting_t lighting; ///< Wall and sprite lighting
mapheader_lighting_t lighting_encore; ///< Alternative lighting for Encore mode
boolean use_encore_lighting; ///< Whether to use separate Encore lighting
fixed_t mobj_scale; ///< Replacement for TOL_ERZ3
// Music stuff.
UINT32 musinterfadeout; ///< Fade out level music on intermission screen in milliseconds
@@ -361,6 +338,9 @@ enum GameType // SRB2Kart
// String names for gametypes
extern const char *Gametype_Names[NUMGAMETYPES];
extern tic_t totalplaytime;
extern UINT32 matchesplayed;
extern UINT8 stagefailed;
// Emeralds stored as bits to throw savegame hackers off.
@@ -474,14 +454,6 @@ extern tic_t racecountdown, exitcountdown;
extern fixed_t gravity;
extern fixed_t mapobjectscale;
extern struct maplighting
{
UINT8 contrast;
SINT8 backlight;
boolean directional;
angle_t angle;
} maplighting;
//for CTF balancing
extern INT16 autobalance;
extern INT16 teamscramble;
@@ -510,6 +482,7 @@ extern boolean startedInFreePlay;
extern boolean legitimateexit;
extern boolean comebackshowninfo;
extern tic_t curlap, bestlap;
extern INT16 votelevels[4][2];
extern SINT8 votes[MAXPLAYERS];
@@ -536,6 +509,18 @@ extern mapthing_t *playerstarts[MAXPLAYERS]; // Cooperative
extern mapthing_t *bluectfstarts[MAXPLAYERS]; // CTF
extern mapthing_t *redctfstarts[MAXPLAYERS]; // CTF
#define WAYPOINTSEQUENCESIZE 256
#define NUMWAYPOINTSEQUENCES 256
extern mobj_t *waypoints[NUMWAYPOINTSEQUENCES][WAYPOINTSEQUENCESIZE];
extern UINT16 numwaypoints[NUMWAYPOINTSEQUENCES];
void P_AddWaypoint(UINT8 sequence, UINT8 id, mobj_t *waypoint);
mobj_t *P_GetFirstWaypoint(UINT8 sequence);
mobj_t *P_GetLastWaypoint(UINT8 sequence);
mobj_t *P_GetPreviousWaypoint(mobj_t *current, boolean wrap);
mobj_t *P_GetNextWaypoint(mobj_t *current, boolean wrap);
mobj_t *P_GetClosestWaypoint(UINT8 sequence, mobj_t *mo);
// =====================================
// Internal parameters, used for engine.
// =====================================
@@ -556,6 +541,9 @@ extern FILE *debugfile;
extern INT32 debugload;
#endif
// if true, load all graphics at level load
extern boolean precache;
// wipegamestate can be set to -1
// to force a wipe on the next draw
extern gamestate_t wipegamestate;
+9 -27
View File
@@ -342,6 +342,15 @@ union FColorRGBA
} ATTRPACK;
typedef union FColorRGBA RGBA_t;
typedef enum
{
POSTIMG_WATER = 1, // Underwater screen effect.
POSTIMG_MOTION = 1<<1, // Unused motion blur effect.
POSTIMG_FLIP = 1<<2, // Flipcam screen effect.
POSTIMG_HEAT = 1<<3, // Heatwave screen effect.
POSTIMG_MIRROR = 1<<4, // encore screen effect.
} postimgflag_t;
typedef UINT32 lumpnum_t; // 16 : 16 unsigned long (wad num: lump num)
#define LUMPERROR UINT32_MAX
@@ -356,33 +365,6 @@ typedef UINT32 tic_t;
#define UINT2RGBA(a) (UINT32)((a&0xff)<<24)|((a&0xff00)<<8)|((a&0xff0000)>>8)|(((UINT32)a&0xff000000)>>24)
#endif
#define TOSTR(x) #x
typedef UINT8 bitarray_t;
#define BIT_ARRAY_SIZE(n) (((n) + 7) >> 3)
static inline int
in_bit_array (const bitarray_t * const array, const int value)
{
return (array[value >> 3] & (1<<(value & 7)));
}
static inline void
set_bit_array (bitarray_t * const array, const int value)
{
array[value >> 3] |= (1<<(value & 7));
}
static inline void
unset_bit_array (bitarray_t * const array, const int value)
{
array[value >> 3] &= ~(1<<(value & 7));
}
#define intsign(n) \
((n) < 0 ? -1 : (n) > 0 ? 1 : 0)
typedef UINT64 precise_t;
#endif //__DOOMTYPE__
+21
View File
@@ -0,0 +1,21 @@
#include "../doomdef.h"
#include "../d_main.h"
#include "../m_argv.h"
int main(int argc, char **argv)
{
myargc = argc;
myargv = argv; /// \todo pull out path to exe from this string
// startup SRB2
CONS_Printf("Setting up SRB2...\n");
D_SRB2Main();
CONS_Printf("Entering main game loop...\n");
// never return
D_SRB2Loop();
// return to OS
#ifndef __GNUC__
return 0;
#endif
}
+6
View File
@@ -0,0 +1,6 @@
#include "../i_net.h"
boolean I_InitNetwork(void)
{
return false;
}
+217
View File
@@ -0,0 +1,217 @@
#include "../i_sound.h"
UINT8 sound_started = 0;
void *I_GetSfx(sfxinfo_t *sfx)
{
(void)sfx;
return NULL;
}
void I_FreeSfx(sfxinfo_t *sfx)
{
(void)sfx;
}
void I_StartupSound(void){}
void I_ShutdownSound(void){}
void I_UpdateSound(void){};
//
// SFX I/O
//
INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority, INT32 channel)
{
(void)id;
(void)vol;
(void)sep;
(void)pitch;
(void)priority;
(void)channel;
return -1;
}
void I_StopSound(INT32 handle)
{
(void)handle;
}
boolean I_SoundIsPlaying(INT32 handle)
{
(void)handle;
return false;
}
void I_UpdateSoundParams(INT32 handle, UINT8 vol, UINT8 sep, UINT8 pitch)
{
(void)handle;
(void)vol;
(void)sep;
(void)pitch;
}
void I_SetSfxVolume(UINT8 volume)
{
(void)volume;
}
/// ------------------------
// MUSIC SYSTEM
/// ------------------------
void I_InitMusic(void){}
void I_ShutdownMusic(void){}
/// ------------------------
// MUSIC PROPERTIES
/// ------------------------
musictype_t I_SongType(void)
{
return MU_NONE;
}
boolean I_SongPlaying(void)
{
return false;
}
boolean I_SongPaused(void)
{
return false;
}
/// ------------------------
// MUSIC EFFECTS
/// ------------------------
boolean I_SetSongSpeed(float speed)
{
(void)speed;
return false;
}
/// ------------------------
// MUSIC SEEKING
/// ------------------------
UINT32 I_GetSongLength(void)
{
return 0;
}
boolean I_SetSongLoopPoint(UINT32 looppoint)
{
(void)looppoint;
return false;
}
UINT32 I_GetSongLoopPoint(void)
{
return 0;
}
boolean I_SetSongPosition(UINT32 position)
{
(void)position;
return false;
}
UINT32 I_GetSongPosition(void)
{
return 0;
}
/// ------------------------
// MUSIC PLAYBACK
/// ------------------------
boolean I_LoadSong(char *data, size_t len)
{
(void)data;
(void)len;
return -1;
}
void I_UnloadSong(void)
{
(void)handle;
}
boolean I_PlaySong(boolean looping)
{
(void)handle;
(void)looping;
return false;
}
void I_StopSong(void)
{
(void)handle;
}
void I_PauseSong(void)
{
(void)handle;
}
void I_ResumeSong(void)
{
(void)handle;
}
void I_SetMusicVolume(UINT8 volume)
{
(void)volume;
}
boolean I_SetSongTrack(INT32 track)
{
(void)track;
return false;
}
/// ------------------------
// MUSIC FADING
/// ------------------------
void I_SetInternalMusicVolume(UINT8 volume)
{
(void)volume;
}
void I_StopFadingSong(void)
{
}
boolean I_FadeSongFromVolume(UINT8 target_volume, UINT8 source_volume, UINT32 ms, void (*callback)(void));
{
(void)target_volume;
(void)source_volume;
(void)ms;
return false;
}
boolean I_FadeSong(UINT8 target_volume, UINT32 ms, void (*callback)(void));
{
(void)target_volume;
(void)ms;
return false;
}
boolean I_FadeOutStopSong(UINT32 ms)
{
(void)ms;
return false;
}
boolean I_FadeInPlaySong(UINT32 ms, boolean looping)
{
(void)ms;
(void)looping;
return false;
}
+178
View File
@@ -0,0 +1,178 @@
#include "../doomdef.h"
#include "../i_system.h"
UINT8 graphics_started = 0;
UINT8 keyboard_started = 0;
size_t I_GetFreeMem(size_t *total)
{
*total = 0;
return 0;
}
void I_Sleep(UINT32 ms){}
precise_t I_GetPreciseTime(void) {
return 0;
}
UINT64 I_GetPrecisePrecision(void) {
return 1000000;
}
void I_GetEvent(void){}
void I_OsPolling(void){}
ticcmd_t *I_BaseTiccmd(void)
{
return NULL;
}
ticcmd_t *I_BaseTiccmd2(void)
{
return NULL;
}
void I_Quit(void)
{
exit(0);
}
void I_Error(const char *error, ...)
{
(void)error;
exit(-1);
}
void I_Tactile(FFType Type, const JoyFF_t *Effect)
{
(void)Type;
(void)Effect;
}
void I_Tactile2(FFType Type, const JoyFF_t *Effect)
{
(void)Type;
(void)Effect;
}
void I_JoyScale(void){}
void I_JoyScale2(void){}
void I_InitJoystick(void){}
void I_InitJoystick2(void){}
INT32 I_NumJoys(void)
{
return 0;
}
const char *I_GetJoyName(INT32 joyindex)
{
(void)joyindex;
return NULL;
}
#ifndef NOMUMBLE
void I_UpdateMumble(const mobj_t *mobj, const listener_t listener)
{
(void)mobj;
(void)listener;
}
#endif
void I_OutputMsg(const char *error, ...)
{
(void)error;
}
void I_StartupMouse(void){}
void I_StartupMouse2(void){}
void I_StartupKeyboard(void){}
INT32 I_GetKey(void)
{
return 0;
}
void I_StartupTimer(void){}
void I_AddExitFunc(void (*func)())
{
(void)func;
}
void I_RemoveExitFunc(void (*func)())
{
(void)func;
}
INT32 I_StartupSystem(void)
{
return -1;
}
void I_ShutdownSystem(void){}
void I_GetDiskFreeSpace(INT64* freespace)
{
*freespace = 0;
}
char *I_GetUserName(void)
{
return NULL;
}
INT32 I_mkdir(const char *dirname, INT32 unixright)
{
(void)dirname;
(void)unixright;
return -1;
}
const char *I_LocateWad(void)
{
return NULL;
}
void I_GetJoystickEvents(void){}
void I_GetJoystick2Events(void){}
void I_GetMouseEvents(void){}
char *I_GetEnv(const char *name)
{
(void)name;
return NULL;
}
INT32 I_PutEnv(char *variable)
{
(void)variable;
return -1;
}
INT32 I_ClipboardCopy(const char *data, size_t size)
{
(void)data;
(void)size;
return -1;
}
char *I_ClipboardPaste(void)
{
return NULL;
}
void I_RegisterSysCommands(void) {}
#include "../sdl/dosstr.c"
+67
View File
@@ -0,0 +1,67 @@
#include "../doomdef.h"
#include "../command.h"
#include "../i_video.h"
rendermode_t rendermode = render_none;
boolean highcolor = false;
boolean allow_fullscreen = false;
consvar_t cv_vidwait = {"vid_wait", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
void I_StartupGraphics(void){}
void I_ShutdownGraphics(void){}
void I_SetPalette(RGBA_t *palette)
{
(void)palette;
}
INT32 VID_NumModes(void)
{
return 0;
}
INT32 VID_GetModeForSize(INT32 w, INT32 h)
{
(void)w;
(void)h;
return 0;
}
void VID_PrepareModeList(void){}
INT32 VID_SetMode(INT32 modenum)
{
(void)modenum;
return 0;
}
const char *VID_GetModeName(INT32 modenum)
{
(void)modenum;
return NULL;
}
void I_UpdateNoBlit(void){}
void I_FinishUpdate(void){}
void I_UpdateNoVsync(void) {}
void I_WaitVBL(INT32 count)
{
(void)count;
}
void I_ReadScreen(UINT8 *scr)
{
(void)scr;
}
void I_BeginRead(void){}
void I_EndRead(void){}
+34 -38
View File
@@ -149,7 +149,7 @@ static UINT8 F_WriteText(void)
static void F_NewCutscene(const char *basetext)
{
cutscene_basetext = basetext;
memset(cutscene_disptext, 0, sizeof(cutscene_disptext));
memset(cutscene_disptext,0,sizeof(cutscene_disptext));
cutscene_writeptr = cutscene_baseptr = 0;
cutscene_textspeed = 9;
cutscene_textcount = TICRATE/2;
@@ -164,14 +164,14 @@ static void F_SkyScroll(INT32 scrollspeed)
patch_t *pat, *pat2;
INT32 anim2 = 0;
pat = W_CachePatchName("TITLEBG1", PU_PATCH_LOWPRIORITY);
pat2 = W_CachePatchName("TITLEBG2", PU_PATCH_LOWPRIORITY);
pat = W_CachePatchName("TITLEBG1", PU_CACHE);
pat2 = W_CachePatchName("TITLEBG2", PU_CACHE);
w = (vid.width / vid.dupx)<<FRACBITS;
// The scroll offset MUST be clamped before shifting by FRACBITS, or else it'll overflow in about 3 minutes
animtimer = ((((finalecount * scrollspeed) % (pat->width*16))<<FRACBITS) + (R_GetMenuUncap() * scrollspeed))/16;
anim2 = (pat2->width<<FRACBITS) - ((((finalecount * scrollspeed) % (pat2->width*16))<<FRACBITS) + (R_GetMenuUncap() * scrollspeed))/16;
animtimer = ((((finalecount * scrollspeed) % (SHORT(pat->width)*16))<<FRACBITS) + (R_GetMenuUncap() * scrollspeed))/16;
anim2 = (SHORT(pat2->width)<<FRACBITS) - ((((finalecount * scrollspeed) % (SHORT(pat2->width)*16))<<FRACBITS) + (R_GetMenuUncap() * scrollspeed))/16;
// SRB2Kart: F_DrawPatchCol is over-engineered; recoded to be less shitty and error-prone
if (rendermode != render_none)
@@ -183,15 +183,15 @@ static void F_SkyScroll(INT32 scrollspeed)
while (x < w)
{
V_DrawFixedPatch(x, y, FRACUNIT, V_SNAPTOTOP|V_SNAPTOLEFT, pat, NULL);
x += pat->width<<FRACBITS;
x += SHORT(pat->width)<<FRACBITS;
}
x = -anim2;
y = (BASEVIDHEIGHT - pat2->height)<<FRACBITS;
y = (BASEVIDHEIGHT - SHORT(pat2->height))<<FRACBITS;
while (x < w)
{
V_DrawFixedPatch(x, y, FRACUNIT, V_SNAPTOBOTTOM|V_SNAPTOLEFT, pat2, NULL);
x += pat2->width<<FRACBITS;
x += SHORT(pat2->width)<<FRACBITS;
}
}
@@ -263,7 +263,7 @@ void F_IntroDrawer(void)
// DRAW A FULL PIC INSTEAD OF FLAT!
if (intro_scenenum == 0)
{
background = W_CachePatchName("KARTKREW", PU_PATCH_LOWPRIORITY);
background = W_CachePatchName("KARTKREW", PU_CACHE);
highres = true;
}
@@ -534,15 +534,8 @@ static const char *credits[] = {
"\"Sunflower\" aka \"AnimeSonic\"",
"\"Yuz\" aka \"Yuzler\"",
"\"Democrab\"",
"\"EXpand\"",
"\"Expand\" aka \"Maver\"",
"\"Nexit\"",
"\"Spee\"",
"\"Jin\"",
"\"riomccloud\"",
"\"chromaticpipe\"",
"\"Achii\"",
"\"Anonimus\"",
"\"scizor300\"",
"",
"\1Special Thanks",
"SEGA",
@@ -630,10 +623,10 @@ void F_CreditDrawer(void)
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
// Draw background
V_DrawSciencePatch(0, 0 - FixedMul(32<<FRACBITS, FixedDiv(credbgtimer%TICRATE, TICRATE)), V_SNAPTOTOP, W_CachePatchName("CREDTILE", PU_PATCH_LOWPRIORITY), FRACUNIT);
V_DrawSciencePatch(0, 0 - FixedMul(32<<FRACBITS, FixedDiv(credbgtimer%TICRATE, TICRATE)), V_SNAPTOTOP, W_CachePatchName("CREDTILE", PU_CACHE), FRACUNIT);
V_DrawSciencePatch(0, 0 - FixedMul(40<<FRACBITS, FixedDiv(credbgtimer%(TICRATE/2), (TICRATE/2))), V_SNAPTOTOP, W_CachePatchName("CREDZIGZ", PU_PATCH_LOWPRIORITY), FRACUNIT);
V_DrawSciencePatch(320<<FRACBITS, 0 - FixedMul(40<<FRACBITS, FixedDiv(credbgtimer%(TICRATE/2), (TICRATE/2))), V_SNAPTOTOP|V_FLIP, W_CachePatchName("CREDZIGZ", PU_PATCH_LOWPRIORITY), FRACUNIT);
V_DrawSciencePatch(0, 0 - FixedMul(40<<FRACBITS, FixedDiv(credbgtimer%(TICRATE/2), (TICRATE/2))), V_SNAPTOTOP, W_CachePatchName("CREDZIGZ", PU_CACHE), FRACUNIT);
V_DrawSciencePatch(320<<FRACBITS, 0 - FixedMul(40<<FRACBITS, FixedDiv(credbgtimer%(TICRATE/2), (TICRATE/2))), V_SNAPTOTOP|V_FLIP, W_CachePatchName("CREDZIGZ", PU_CACHE), FRACUNIT);
// Draw pictures
for (i = 0; credits_pics[i].patch; i++)
@@ -647,7 +640,7 @@ void F_CreditDrawer(void)
sc = FRACUNIT; // quick hack so I don't have to add another field to credits_pics
}
V_DrawFixedPatch(credits_pics[i].x<<FRACBITS, (credits_pics[i].y<<FRACBITS) - 4*(animtimer<<FRACBITS)/5, sc, 0, W_CachePatchName(credits_pics[i].patch, PU_PATCH), colormap);
V_DrawFixedPatch(credits_pics[i].x<<FRACBITS, (credits_pics[i].y<<FRACBITS) - 4*(animtimer<<FRACBITS)/5, sc, 0, W_CachePatchName(credits_pics[i].patch, PU_CACHE), colormap);
}
// Dim the background
@@ -846,9 +839,9 @@ void F_GameEvaluationDrawer(void)
patchname[4] = 'A'+(char)i;
if (emeralds & (1<<i))
V_DrawScaledPatch(x, y, 0, W_CachePatchName(patchname, PU_PATCH_LOWPRIORITY));
V_DrawScaledPatch(x, y, 0, W_CachePatchName(patchname, PU_CACHE));
else
V_DrawTranslucentPatch(x, y, TRANSLEVEL, W_CachePatchName(patchname, PU_PATCH_LOWPRIORITY));
V_DrawTranslucentPatch(x, y, TRANSLEVEL, W_CachePatchName(patchname, PU_CACHE));
eemeralds_cur += INTERVAL;
}
@@ -864,6 +857,9 @@ void F_GameEvaluationDrawer(void)
if (ALL7EMERALDS(emeralds))
++timesBeatenWithEmeralds;
/*if (ultimatemode)
++timesBeatenUltimate;*/
if (M_UpdateUnlockablesAndExtraEmblems(false))
S_StartSound(NULL, sfx_ncitem);
@@ -874,10 +870,10 @@ void F_GameEvaluationDrawer(void)
if (finalecount >= 5*TICRATE)
{
if (drawemblem)
V_DrawScaledPatch(120, 192, 0, W_CachePatchName("NWNGA0", PU_PATCH_LOWPRIORITY));
V_DrawScaledPatch(120, 192, 0, W_CachePatchName("NWNGA0", PU_CACHE));
if (drawchaosemblem)
V_DrawScaledPatch(200, 192, 0, W_CachePatchName("NWNGA0", PU_PATCH_LOWPRIORITY));
V_DrawScaledPatch(200, 192, 0, W_CachePatchName("NWNGA0", PU_CACHE));
V_DrawString(8, 16, V_YELLOWMAP, "Unlocked:");
@@ -972,10 +968,10 @@ void F_StartTitleScreen(void)
demoDelayLeft = demoDelayTime;
demoIdleLeft = demoIdleTime;
ttbanner = W_CachePatchName("TTKBANNR", PU_PATCH_LOWPRIORITY);
ttkart = W_CachePatchName("TTKART", PU_PATCH_LOWPRIORITY);
ttcheckers = W_CachePatchName("TTCHECK", PU_PATCH_LOWPRIORITY);
ttkflash = W_CachePatchName("TTKFLASH", PU_PATCH_LOWPRIORITY);
ttbanner = W_CachePatchName("TTKBANNR", PU_LEVEL);
ttkart = W_CachePatchName("TTKART", PU_LEVEL);
ttcheckers = W_CachePatchName("TTCHECK", PU_LEVEL);
ttkflash = W_CachePatchName("TTKFLASH", PU_LEVEL);
}
// (no longer) De-Demo'd Title Screen
@@ -1010,7 +1006,7 @@ void F_TitleScreenDrawer(void)
else
{
INT32 transval = 0;
if (finalecount <= (50+(9<<1)))
transval = (finalecount - 50)>>1;
@@ -1057,8 +1053,8 @@ void F_TitleScreenTicker(boolean run)
return;
// are demos disabled?
if (!cv_rollingdemos.value || modifiedgame) // occasionally mappacks supply invalid replays which means the game crashes almost always when you idle on the titlescreen too long
return; // we check for all addons since added luas/socs and stuff like that makes them desynch like crazy so why would you even watch them?
if (!cv_rollingdemos.value)
return;
// Wait for a while (for the music to finish, preferably)
// before starting demos
@@ -1190,7 +1186,7 @@ void F_StartWaitingPlayers(void)
for (i = 0; i < 2; i++)
{
sprframe = &skins[randskin].spritedef.spriteframes[(6+(i*3)) & FF_FRAMEMASK];
driver[i] = W_CachePatchNum(sprframe->lumppat[1], PU_CACHE);
driver[i] = W_CachePatchNum(sprframe->lumppat[1], PU_LEVEL);
}
}
@@ -1259,15 +1255,15 @@ void F_ContinueDrawer(void)
ncontinues = 20;
if (imcontinuing)
contsonic = W_CachePatchName("CONT2", PU_PATCH_LOWPRIORITY);
contsonic = W_CachePatchName("CONT2", PU_CACHE);
else
contsonic = W_CachePatchName("CONT1", PU_PATCH_LOWPRIORITY);
contsonic = W_CachePatchName("CONT1", PU_CACHE);
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
V_DrawCenteredString(BASEVIDWIDTH/2, 100, 0, "CONTINUE?");
// Draw a Sonic!
V_DrawScaledPatch((BASEVIDWIDTH - contsonic->width)/2, 32, 0, contsonic);
V_DrawScaledPatch((BASEVIDWIDTH - SHORT(contsonic->width))/2, 32, 0, contsonic);
// Draw the continue markers! Show continues minus one.
x -= ncontinues * 6;
@@ -1486,10 +1482,10 @@ void F_CutsceneDrawer(void)
{
if (cutscenes[cutnum]->scene[scenenum].pichires[picnum])
V_DrawSmallScaledPatch(picxpos, picypos, 0,
W_CachePatchName(cutscenes[cutnum]->scene[scenenum].picname[picnum], PU_PATCH_LOWPRIORITY));
W_CachePatchName(cutscenes[cutnum]->scene[scenenum].picname[picnum], PU_CACHE));
else
V_DrawScaledPatch(picxpos,picypos, 0,
W_CachePatchName(cutscenes[cutnum]->scene[scenenum].picname[picnum], PU_PATCH_LOWPRIORITY));
W_CachePatchName(cutscenes[cutnum]->scene[scenenum].picname[picnum], PU_CACHE));
}
if (dofadenow && rendermode != render_none)
+1 -1
View File
@@ -273,7 +273,7 @@ static void F_DoWipe(fademask_t *fademask)
else
{
// pointer to transtable that this mask would use
transtbl = R_GetTranslucencyTable((9 - *mask) + 1);
transtbl = transtables + ((9 - *mask)<<FF_TRANSSHIFT);
// DRAWING LOOP
while (draw_linestogo--)
+6 -11
View File
@@ -327,8 +327,7 @@ char menupath[1024];
size_t menupathindex[menudepth];
size_t menudepthleft = menudepth;
char menusearchbuf[MAXSTRINGLENGTH+1];
textinput_t menusearch;
char menusearch[MAXSTRINGLENGTH+1];
char **dirmenu, **coredirmenu; // core only local for this file
size_t sizedirmenu, sizecoredirmenu; // ditto
@@ -498,7 +497,7 @@ static boolean filemenucmp(char *haystack, char *needle)
strupr(localhaystack);
if (cv_addons_search_type.value)
return (strstr(localhaystack, needle) != 0);
return (!strncmp(localhaystack, needle, menusearch.length));
return (!strncmp(localhaystack, needle, menusearch[0]));
}
void closefilemenu(boolean validsize)
@@ -564,7 +563,7 @@ void searchfilemenu(char *tempname)
first = (((UINT8)(coredirmenu[0][DIR_TYPE]) == EXT_UP) ? 1 : 0); // skip UP...
if (!menusearch.length)
if (!menusearch[0])
{
if (dirmenu)
Z_Free(dirmenu);
@@ -591,7 +590,7 @@ void searchfilemenu(char *tempname)
return;
}
strcpy(localmenusearch, menusearch.buffer);
strcpy(localmenusearch, menusearch+1);
if (!cv_addons_search_case.value)
strupr(localmenusearch);
@@ -653,7 +652,7 @@ boolean preparefilemenu(boolean samedepth, boolean replayhut)
tempname = Z_StrDup(dirmenu[dir_on[menudepthleft]]+DIR_STRING); // don't need to I_Error if can't make - not important, just QoL
}
else
M_TextInputInit(&menusearch, menusearchbuf, MAXSTRINGLENGTH+1);
menusearch[0] = menusearch[1] = 0; // clear search
if (!(dirhandle = opendir(menupath))) // get directory
{
@@ -661,10 +660,6 @@ boolean preparefilemenu(boolean samedepth, boolean replayhut)
return false;
}
if (dirmenu != coredirmenu)
Z_Free(dirmenu);
dirmenu = NULL;
for (; sizecoredirmenu > 0; sizecoredirmenu--) // clear out existing items
{
Z_Free(coredirmenu[sizecoredirmenu-1]);
@@ -801,7 +796,7 @@ boolean preparefilemenu(boolean samedepth, boolean replayhut)
}
else if (ext == EXT_TXT)
{
if (!strncmp(dent->d_name, "log-", 4) || !strcmp(dent->d_name, "errorlog.txt"))
if (!strcmp(dent->d_name, "log.txt") || !strcmp(dent->d_name, "errorlog.txt"))
ext |= EXT_LOADED;
}
+1 -3
View File
@@ -7,7 +7,6 @@
#include "doomdef.h"
#include "d_netfil.h"
#include "m_menu.h" // MAXSTRINGLENGTH
#include "m_textinput.h"
extern consvar_t cv_addons_option, cv_addons_folder, cv_addons_md5, cv_addons_showall, cv_addons_search_case, cv_addons_search_type;
@@ -35,8 +34,7 @@ extern char menupath[1024];
extern size_t menupathindex[menudepth];
extern size_t menudepthleft;
extern char menusearchbuf[MAXSTRINGLENGTH+1];
extern textinput_t menusearch;
extern char menusearch[MAXSTRINGLENGTH+1];
extern char **dirmenu;
extern size_t sizedirmenu;
+1478 -1263
View File
File diff suppressed because it is too large. Load diff
+42 -89
View File
@@ -17,7 +17,6 @@
#include "doomdef.h"
#include "doomstat.h"
#include "d_event.h"
#include "p_saveg.h"
#include "m_textinput.h"
extern char gamedatafilename[64];
@@ -34,7 +33,7 @@ extern INT32 player_name_changes[MAXPLAYERS];
extern player_t players[MAXPLAYERS];
extern boolean playeringame[MAXPLAYERS];
extern savebuffer_t demobuf;
extern UINT8 *demo_p;
// ======================================
// DEMO playback/recording related stuff.
@@ -42,7 +41,6 @@ extern savebuffer_t demobuf;
// demoplaying back and demo recording
extern consvar_t cv_recordmultiplayerdemos, cv_netdemosyncquality, cv_maxdemosize, cv_demochangemap;
extern consvar_t cv_demodateformat;
// Publicly-accessible demo vars
struct demovars_s {
@@ -67,6 +65,9 @@ struct demovars_s {
DSM_WILLSAVE,
DSM_SAVED
} savemode;
boolean freecam;
};
extern struct demovars_s demo;
@@ -84,8 +85,6 @@ typedef struct menudemo_s {
menudemotype_e type;
char title[65]; // Null-terminated for string prints
char date[11]; // date when replay was recorded
char version[12]; // combined version and subversion
UINT16 map;
UINT8 addonstatus; // What do we need to do addon-wise to play this demo?
UINT8 gametype;
@@ -118,24 +117,15 @@ extern consvar_t cv_songcredits;
extern consvar_t cv_showfreeplay;
extern consvar_t cv_growmusic, cv_supermusic;
extern consvar_t cv_pauseifunfocused;
extern consvar_t cv_invertmouse;
extern consvar_t cv_turnaxis[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_moveaxis[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_camturnaxis[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_camstrafeaxis[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_brakeaxis[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_aimaxis[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_lookaxis[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_lookbackaxis[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_fireaxis[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_driftaxis[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_custom1axis[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_custom2axis[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_custom3axis[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_xdeadzone[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_ydeadzone[MAXSPLITSCREENPLAYERS];
//extern consvar_t cv_crosshair, cv_crosshair2, cv_crosshair3, cv_crosshair4;
extern consvar_t cv_invertmouse/*, cv_alwaysfreelook, cv_chasefreelook, cv_mousemove*/;
extern consvar_t cv_invertmouse2/*, cv_alwaysfreelook2, cv_chasefreelook2, cv_mousemove2*/;
extern consvar_t cv_useranalog, cv_useranalog2, cv_useranalog3, cv_useranalog4;
extern consvar_t cv_analog, cv_analog2, cv_analog3, cv_analog4;
extern consvar_t cv_turnaxis,cv_moveaxis,cv_brakeaxis,cv_aimaxis,cv_lookaxis,cv_fireaxis,cv_driftaxis,cv_lookbackaxis,cv_custom1axis,cv_custom2axis,cv_custom3axis,cv_xdeadzone,cv_ydeadzone;
extern consvar_t cv_turnaxis2,cv_moveaxis2,cv_brakeaxis2,cv_aimaxis2,cv_lookaxis2,cv_fireaxis2,cv_driftaxis2,cv_lookbackaxis2,cv_custom1axis2,cv_custom2axis2,cv_custom3axis2,cv_xdeadzone2,cv_ydeadzone2;
extern consvar_t cv_turnaxis3,cv_moveaxis3,cv_brakeaxis3,cv_aimaxis3,cv_lookaxis3,cv_fireaxis3,cv_driftaxis3,cv_lookbackaxis3,cv_custom1axis3,cv_custom2axis3,cv_custom3axis3,cv_xdeadzone3,cv_ydeadzone3;
extern consvar_t cv_turnaxis4,cv_moveaxis4,cv_brakeaxis4,cv_aimaxis4,cv_lookaxis4,cv_fireaxis4,cv_driftaxis4,cv_lookbackaxis4,cv_custom1axis4,cv_custom2axis4,cv_custom3axis4,cv_xdeadzone4,cv_ydeadzone4;
extern consvar_t cv_ghost_besttime, cv_ghost_bestlap, cv_ghost_last, cv_ghost_guest, cv_ghost_staff;
// Hud offsets
@@ -149,47 +139,38 @@ extern consvar_t cv_##name##_yoffset;
DECL_HUD_OFFSET_X(name)\
DECL_HUD_OFFSET_Y(name)
DECL_HUD_OFFSET(item); // Item box
DECL_HUD_OFFSET(time); // Time
DECL_HUD_OFFSET(laps); // Number of laps
DECL_HUD_OFFSET(dnft); // Countdown (did not finish timer)
DECL_HUD_OFFSET(speed); // Speedometer
DECL_HUD_OFFSET(posi); // Position in race
DECL_HUD_OFFSET(wheel); // RA Wheel
DECL_HUD_OFFSET(face); // Mini rankings
DECL_HUD_OFFSET(stcd); // Starting countdown
DECL_HUD_OFFSET(item); // Item box
DECL_HUD_OFFSET(time); // Time
DECL_HUD_OFFSET(laps); // Number of laps
DECL_HUD_OFFSET(dnft); // Countdown (did not finish timer)
DECL_HUD_OFFSET(speed); // Speedometer
DECL_HUD_OFFSET(posi); // Position in race
DECL_HUD_OFFSET(face); // Mini rankings
DECL_HUD_OFFSET(stcd); // Starting countdown
DECL_HUD_OFFSET_Y(chek); // Check gfx
DECL_HUD_OFFSET(mini); // Minimap
DECL_HUD_OFFSET(want); // Wanted
DECL_HUD_OFFSET(stat); // Stats
DECL_HUD_OFFSET(mini); // Minimap
DECL_HUD_OFFSET(want); // Wanted
DECL_HUD_OFFSET(stat); // Stats
#undef DECL_HUD_OFFSET
#undef DECL_HUD_OFFSET_X
#undef DECL_HUD_OFFSET_Y
extern consvar_t cv_showinput;
extern consvar_t cv_posanim;
extern consvar_t cv_smallposnum;
extern consvar_t cv_newspeedometer;
extern consvar_t cv_saltyhop;
extern consvar_t cv_saltyheight;
extern consvar_t cv_saltyhopsfx;
extern consvar_t cv_saltysquish;
extern consvar_t cv_saltyroll;
extern consvar_t cv_driftsparkpulse;
extern consvar_t cv_gravstretch;
extern consvar_t cv_sloperoll;
extern consvar_t cv_spriteroll;
extern consvar_t cv_sliptideroll;
extern consvar_t cv_slamsound;
extern consvar_t cv_sloperolldist;
extern consvar_t cv_sparkroll;
extern consvar_t cv_spinoutroll;
extern consvar_t cv_squishdance, cv_squishdancespeed;
extern consvar_t cv_playerblendeffects;
extern consvar_t cv_cechotoggle;
@@ -202,8 +183,6 @@ typedef enum
AXISNONE = 0,
AXISTURN,
AXISMOVE,
AXISCAMTURN,
AXISCAMSTRAFE,
AXISBRAKE,
AXISAIM,
AXISLOOK,
@@ -241,6 +220,8 @@ extern angle_t localangle[MAXSPLITSCREENPLAYERS];
extern INT32 localaiming[MAXSPLITSCREENPLAYERS]; // should be an angle_t but signed
extern boolean camspin[MAXSPLITSCREENPLAYERS]; // SRB2Kart
extern tic_t directortoggletimer;
//
// GAME
//
@@ -285,6 +266,7 @@ void G_SpawnPlayer(INT32 playernum, boolean starpost);
// A normal game starts at map 1, but a warp test can start elsewhere
void G_DeferedInitNew(boolean pencoremode, const char *mapname, INT32 pickedchar,
UINT8 ssplayers, boolean FLS);
void G_DoLoadLevel(boolean resetplayer);
void G_LoadDemoInfo(menudemo_t *pdemo);
void G_LoadDemoTitle(menudemo_t *pdemo); // For use in replay search feature
@@ -374,7 +356,6 @@ extern demoghost *ghosts;
#define DFILE_ERROR_CANNOTLOAD 0x04 // Files are missing and cannot be loaded.
#define DFILE_ERROR_EXTRAFILES 0x05 // Extra files outside of the replay's file list are loaded.
void G_ResetDemoRecording(void);
void G_DoPlayDemo(char *defdemoname);
void G_TimeDemo(const char *name);
void G_AddGhost(char *defdemoname);
@@ -388,24 +369,16 @@ boolean G_CheckDemoStatus(void);
void G_SaveDemo(void);
boolean G_DemoTitleResponder(event_t *ev);
#define G_GametypeHasTeams() (G_IsGameType(GT_TEAMMATCH) || G_IsGameType(GT_CTF))
#define G_BattleGametype() (G_IsGameType(GT_MATCH))
#define G_RaceGametype() (G_IsGameType(GT_RACE))
#define G_TagGametype() (G_IsGameType(GT_TAG) || G_IsGameType(GT_HIDEANDSEEK))
FUNCINLINE static ATTRINLINE boolean G_IsGameType(int type)
{
return (gametype == type);
}
FUNCINLINE static ATTRINLINE boolean G_GametypeHasSpectators(void)
{
return (netgame || (multiplayer && demo.playback));
}
INT32 G_GetGametypeByName(const char *gametypestr);
boolean G_IsSpecialStage(INT32 mapnum);
boolean G_GametypeUsesLives(void);
boolean G_GametypeHasTeams(void);
boolean G_GametypeHasSpectators(void);
boolean G_BattleGametype(void);
UINT8 G_SometimesGetDifferentGametype(UINT8 prefgametype);
UINT8 G_GetGametypeColor(INT16 gt);
boolean G_RaceGametype(void);
boolean G_TagGametype(void);
void G_ExitLevel(void);
void G_NextLevel(void);
void G_Continue(void);
@@ -435,6 +408,7 @@ void G_SetRetryFlag(void);
void G_ClearRetryFlag(void);
boolean G_GetRetryFlag(void);
void G_LoadGameData(void);
void G_LoadGameSettings(void);
@@ -449,32 +423,13 @@ void G_ClearRecords(void);
tic_t G_GetBestTime(INT16 map);
// Time utility functions
FUNCMATH INT32 G_TicsToHours(tic_t tics);
FUNCMATH INT32 G_TicsToMinutes(tic_t tics, boolean full);
FUNCMATH INT32 G_TicsToSeconds(tic_t tics);
FUNCMATH INT32 G_TicsToCentiseconds(tic_t tics);
FUNCMATH INT32 G_TicsToMilliseconds(tic_t tics);
FUNCINLINE static ATTRINLINE FUNCMATH INT32 G_TicsToHours(tic_t tics)
{
return tics/(3600*TICRATE);
}
FUNCINLINE static ATTRINLINE FUNCMATH INT32 G_TicsToMinutes(tic_t tics, boolean full)
{
return full ? (tics/(60*TICRATE)) : (tics/(60*TICRATE)%60);
}
FUNCINLINE static ATTRINLINE FUNCMATH INT32 G_TicsToSeconds(tic_t tics)
{
return (tics/TICRATE)%60;
}
FUNCINLINE static ATTRINLINE FUNCMATH INT32 G_TicsToCentiseconds(tic_t tics)
{
return (INT32)((tics%TICRATE) * (100.00f/TICRATE));
}
FUNCINLINE static ATTRINLINE FUNCMATH INT32 G_TicsToMilliseconds(tic_t tics)
{
return (INT32)((tics%TICRATE) * (1000.00f/TICRATE));
}
boolean K_DirectorIsPlayerAlone(void); // idk where else to put this lol
// Don't split up TOL handling
INT16 G_TOLFlag(INT32 pgametype);
@@ -482,6 +437,4 @@ INT16 G_TOLFlag(INT32 pgametype);
INT16 G_RandMap(INT16 tolflags, INT16 pprevmap, boolean ignorebuffer, UINT8 maphell, boolean callagainsoon, INT16 *extbuffer);
void G_AddMapToBuffer(INT16 map);
void G_FixCamera(UINT8 view);
#endif
+270 -170
View File
@@ -20,8 +20,6 @@
#include "d_net.h"
#include "console.h"
#include "m_menu.h"
#include "i_system.h"
#include "i_video.h"
#include "r_draw.h"
@@ -35,7 +33,9 @@ static CV_PossibleValue_t turnsmooth_cons_t[] = {{2, "Slow"}, {1, "Fast"}, {0, "
// mouse values are used once
consvar_t cv_mousesens = {"mousesens", "20", CV_SAVE, mousesens_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_mousesens2 = {"mousesens2", "20", CV_SAVE, mousesens_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_mouseysens = {"mouseysens", "20", CV_SAVE, mousesens_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_mouseysens2 = {"mouseysens2", "20", CV_SAVE, mousesens_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_controlperkey = {"controlperkey", "One", CV_SAVE, onecontrolperkey_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_turnsmooth = {"turnsmoothing", "Slow", CV_SAVE, turnsmooth_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
@@ -58,35 +58,44 @@ consvar_t cv_rumble[MAXSPLITSCREENPLAYERS] = {
{"rumble4", "Off", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, rumble_off_handle4, 0, NULL, NULL, 0, 0, NULL}
};
static CV_PossibleValue_t gamepadled_cons_t[] = {{0, "Off"}, {1, "Skincolor"}, {2, "Mobjcolor"}, {0, NULL}};
consvar_t cv_gamepadled[MAXSPLITSCREENPLAYERS] = {
{"gamepadled", "Skincolor", CV_SAVE|CV_CALL|CV_NOINIT, gamepadled_cons_t, led_off_handle, 0, NULL, NULL, 0, 0, NULL},
{"gamepadled2", "Skincolor", CV_SAVE|CV_CALL|CV_NOINIT, gamepadled_cons_t, led_off_handle2, 0, NULL, NULL, 0, 0, NULL},
{"gamepadled3", "Skincolor", CV_SAVE|CV_CALL|CV_NOINIT, gamepadled_cons_t, led_off_handle3, 0, NULL, NULL, 0, 0, NULL},
{"gamepadled4", "Skincolor", CV_SAVE|CV_CALL|CV_NOINIT, gamepadled_cons_t, led_off_handle4, 0, NULL, NULL, 0, 0, NULL}
{"gamepadled", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, led_off_handle, 0, NULL, NULL, 0, 0, NULL},
{"gamepadled2", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, led_off_handle2, 0, NULL, NULL, 0, 0, NULL},
{"gamepadled3", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, led_off_handle3, 0, NULL, NULL, 0, 0, NULL},
{"gamepadled4", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, led_off_handle4, 0, NULL, NULL, 0, 0, NULL}
};
consvar_t cv_ledpowerup[MAXSPLITSCREENPLAYERS] = {
{"ledpowerup", "Off", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, led_off_handle, 0, NULL, NULL, 0, 0, NULL},
{"ledpowerup2", "Off", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, led_off_handle2, 0, NULL, NULL, 0, 0, NULL},
{"ledpowerup3", "Off", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, led_off_handle3, 0, NULL, NULL, 0, 0, NULL},
{"ledpowerup4", "Off", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, led_off_handle4, 0, NULL, NULL, 0, 0, NULL}
};
static void rumble_off_handle(void)
{
if (!cv_rumble[0].value)
if (cv_rumble[0].value == 0)
G_ResetPlayerDeviceRumble(0);
}
static void rumble_off_handle2(void)
{
if (!cv_rumble[1].value)
if (cv_rumble[1].value == 0)
G_ResetPlayerDeviceRumble(1);
}
static void rumble_off_handle3(void)
{
if (!cv_rumble[2].value)
if (cv_rumble[2].value == 0)
G_ResetPlayerDeviceRumble(2);
}
static void rumble_off_handle4(void)
{
if (!cv_rumble[3].value)
if (cv_rumble[3].value == 0)
G_ResetPlayerDeviceRumble(3);
}
@@ -95,16 +104,19 @@ static void led_off_handle(void)
G_ResetPlayerGamepadIndicatorColor(0);
}
static void led_off_handle2(void)
{
G_ResetPlayerGamepadIndicatorColor(1);
}
static void led_off_handle3(void)
{
G_ResetPlayerGamepadIndicatorColor(2);
}
static void led_off_handle4(void)
{
G_ResetPlayerGamepadIndicatorColor(3);
@@ -113,6 +125,8 @@ static void led_off_handle4(void)
INT32 mousex, mousey;
INT32 mlooky; // like mousey but with a custom sensitivity for mlook
INT32 mouse2x, mouse2y, mlook2y;
// joystick values are repeated
INT32 joyxmove[JOYAXISSET], joyymove[JOYAXISSET], joy2xmove[JOYAXISSET], joy2ymove[JOYAXISSET],
joy3xmove[JOYAXISSET], joy3ymove[JOYAXISSET], joy4xmove[JOYAXISSET], joy4ymove[JOYAXISSET];
@@ -121,7 +135,10 @@ joy3xmove[JOYAXISSET], joy3ymove[JOYAXISSET], joy4xmove[JOYAXISSET], joy4ymove[J
UINT8 gamekeydown[NUMINPUTS];
// two key codes (or virtual key) per game control
INT32 gamecontrol[MAXSPLITSCREENPLAYERS][num_gamecontrols][2];
INT32 gamecontrol[num_gamecontrols][2];
INT32 gamecontrolbis[num_gamecontrols][2]; // secondary splitscreen player
INT32 gamecontrol3[num_gamecontrols][2]; // tertiary splitscreen player
INT32 gamecontrol4[num_gamecontrols][2]; // quarternary splitscreen player
typedef struct
{
@@ -131,6 +148,7 @@ typedef struct
} dclick_t;
static dclick_t mousedclicks[MOUSEBUTTONS];
static dclick_t joydclicks[JOYBUTTONS + JOYHATS*4];
static dclick_t mouse2dclicks[MOUSEBUTTONS];
static dclick_t joy2dclicks[JOYBUTTONS + JOYHATS*4];
static dclick_t joy3dclicks[JOYBUTTONS + JOYHATS*4];
static dclick_t joy4dclicks[JOYBUTTONS + JOYHATS*4];
@@ -215,6 +233,14 @@ void G_MapEventsToControls(event_t *ev)
if (ev->data3 != INT32_MAX) joy4ymove[i] = ev->data3;
break;
case ev_mouse2: // buttons are virtual keys
if (menuactive || CON_Ready() || chat_on)
break;
mouse2x = (INT32)(ev->data2*((cv_mousesens2.value*cv_mousesens2.value)/110.0f + 0.1f));
mouse2y = (INT32)(ev->data3*((cv_mousesens2.value*cv_mousesens2.value)/110.0f + 0.1f));
mlook2y = (INT32)(ev->data3*((cv_mouseysens2.value*cv_mousesens2.value)/110.0f + 0.1f));
break;
default:
break;
}
@@ -232,6 +258,12 @@ void G_MapEventsToControls(event_t *ev)
gamekeydown[KEY_DBLJOY1+i] = flag;
}
for (i = 0; i < MOUSEBUTTONS; i++)
{
flag = G_CheckDoubleClick(gamekeydown[KEY_2MOUSE1+i], &mouse2dclicks[i]);
gamekeydown[KEY_DBL2MOUSE1+i] = flag;
}
for (i = 0; i < JOYBUTTONS + JOYHATS*4; i++)
{
flag = G_CheckDoubleClick(gamekeydown[KEY_2JOY1+i], &joy2dclicks[i]);
@@ -251,26 +283,6 @@ void G_MapEventsToControls(event_t *ev)
}
}
void G_ResetControls(void)
{
memset(gamekeydown, 0, NUMINPUTS);
memset(joyxmove, 0, sizeof(joyxmove));
memset(joyymove, 0, sizeof(joyymove));
memset(joy2xmove, 0, sizeof(joy2xmove));
memset(joy2ymove, 0, sizeof(joy2ymove));
memset(joy3xmove, 0, sizeof(joy3xmove));
memset(joy3ymove, 0, sizeof(joy3ymove));
memset(joy4xmove, 0, sizeof(joy4xmove));
memset(joy4ymove, 0, sizeof(joy4ymove));
// reset those just in case the game missed the keyup event
memset(dpadscrollstate, false, sizeof(dpadscrollstate));
}
//
// General double-click detection routine for any kind of input.
//
@@ -389,8 +401,18 @@ static keyname_t keynames[] =
{KEY_MOUSE1+5,"MOUSE6"},
{KEY_MOUSE1+6,"MOUSE7"},
{KEY_MOUSE1+7,"MOUSE8"},
{KEY_2MOUSE1+0,"SEC_MOUSE2"}, // BP: sorry my mouse handler swap button 1 and 2
{KEY_2MOUSE1+1,"SEC_MOUSE1"},
{KEY_2MOUSE1+2,"SEC_MOUSE3"},
{KEY_2MOUSE1+3,"SEC_MOUSE4"},
{KEY_2MOUSE1+4,"SEC_MOUSE5"},
{KEY_2MOUSE1+5,"SEC_MOUSE6"},
{KEY_2MOUSE1+6,"SEC_MOUSE7"},
{KEY_2MOUSE1+7,"SEC_MOUSE8"},
{KEY_MOUSEWHEELUP, "Wheel 1 UP"},
{KEY_MOUSEWHEELDOWN, "Wheel 1 Down"},
{KEY_2MOUSEWHEELUP, "Wheel 2 UP"},
{KEY_2MOUSEWHEELDOWN, "Wheel 2 Down"},
{KEY_JOY1+0, "JOY1"},
{KEY_JOY1+1, "JOY2"},
@@ -401,7 +423,7 @@ static keyname_t keynames[] =
{KEY_JOY1+6, "JOY7"},
{KEY_JOY1+7, "JOY8"},
{KEY_JOY1+8, "JOY9"},
#if !defined (NOMOREJOYBTN_1S)
// we use up to 32 buttons in DirectInput
{KEY_JOY1+9, "JOY10"},
@@ -454,6 +476,14 @@ static keyname_t keynames[] =
{KEY_DBLMOUSE1+5, "DBLMOUSE6"},
{KEY_DBLMOUSE1+6, "DBLMOUSE7"},
{KEY_DBLMOUSE1+7, "DBLMOUSE8"},
{KEY_DBL2MOUSE1+0, "DBLSEC_MOUSE2"}, // BP: sorry my mouse handler swap button 1 and 2
{KEY_DBL2MOUSE1+1, "DBLSEC_MOUSE1"},
{KEY_DBL2MOUSE1+2, "DBLSEC_MOUSE3"},
{KEY_DBL2MOUSE1+3, "DBLSEC_MOUSE4"},
{KEY_DBL2MOUSE1+4, "DBLSEC_MOUSE5"},
{KEY_DBL2MOUSE1+5, "DBLSEC_MOUSE6"},
{KEY_DBL2MOUSE1+6, "DBLSEC_MOUSE7"},
{KEY_DBL2MOUSE1+7, "DBLSEC_MOUSE8"},
{KEY_DBLJOY1+0, "DBLJOY1"},
{KEY_DBLJOY1+1, "DBLJOY2"},
@@ -838,6 +868,7 @@ static keyname_t keynames[] =
{KEY_DBL4HAT1+13, "DBLFOR_HATDOWN4"},
{KEY_DBL4HAT1+14, "DBLFOR_HATLEFT4"},
{KEY_DBL4HAT1+15, "DBLFOR_HATRIGHT4"},
};
static const char *gamecontrolname[num_gamecontrols] =
@@ -871,106 +902,149 @@ static const char *gamecontrolname[num_gamecontrols] =
"custom2",
"custom3",
"director",
"freecam",
"camfloat",
"camsink",
"strafeleft",
"straferight",
};
#define NUMKEYNAMES (sizeof (keynames)/sizeof (keyname_t))
#include "k_kart.h"
UINT16 G_GetSkinColor(INT32 playernum)
INT32 G_GetDeviceForPlayer(INT32 player)
{
if (gamestate == GS_LEVEL)
switch (player)
{
player_t *player = &players[displayplayers[playernum]];
if (player)
{
// make rgb rainbow vomit when invul or flash blue when grow
if ((cv_gamepadled[playernum].value == 2) && player->mo && player->mo->color)
return player->mo->color;
// take actual player skincolour when ingame
if (player->skincolor)
return player->skincolor;
}
case 0:
return cv_usejoystick.value;
break;
case 1:
return cv_usejoystick2.value;
break;
case 2:
return cv_usejoystick3.value;
break;
case 3:
return cv_usejoystick4.value;
break;
default:
return 0;
break;
}
}
inline UINT16 G_GetSkinColor(INT32 player)
{
// make rgb rainbow vomit when invul or flash blue when grow
if (cv_ledpowerup[player].value && gamestate == GS_LEVEL && players[displayplayers[player]].mo && (players[displayplayers[player]].kartstuff[k_invincibilitytimer] || players[displayplayers[player]].powers[pw_invulnerability] || players[displayplayers[player]].kartstuff[k_growshrinktimer]))
return players[displayplayers[player]].mo->color;
// take actual player skincolour when ingame
if (gamestate == GS_LEVEL && players[displayplayers[player]].skincolor)
return players[displayplayers[player]].skincolor;
// otherwise just fallback to whatever the cvar is
switch (playernum)
switch (player)
{
case 0:
return cv_playercolor.value;
break;
case 1:
return cv_playercolor2.value;
break;
case 2:
return cv_playercolor3.value;
break;
case 3:
return cv_playercolor4.value;
break;
default:
return 0;
break;
}
return 0;
}
void G_SetPlayerGamepadIndicatorColor(INT32 playernum, UINT16 color)
void G_SetPlayerGamepadIndicatorColor(INT32 player, UINT16 color)
{
INT32 device;
UINT16 skincolor;
byteColor_t byte_color;
I_Assert(playernum >= 0 && playernum < MAXSPLITSCREENPLAYERS);
I_Assert(player >= 0 && player < MAXSPLITSCREENPLAYERS);
if (cv_gamepadled[playernum].value == 0)
if (cv_gamepadled[player].value == 0)
return;
device = G_GetDeviceForPlayer(player);
if (device <= 0)
{
return;
}
skincolor = color ? color : G_GetSkinColor(playernum);
skincolor = color ? color : G_GetSkinColor(player);
byte_color = V_GetColor(colortranslations[skincolor][8]).s;
I_SetGamepadIndicatorColor(playernum, byte_color.red, byte_color.green, byte_color.blue);
I_SetGamepadIndicatorColor(device, byte_color.red, byte_color.green, byte_color.blue);
}
static void G_ResetPlayerGamepadIndicatorColor(INT32 playernum)
static void G_ResetPlayerGamepadIndicatorColor(INT32 player)
{
if (cv_gamepadled[playernum].value == 0)
if (cv_gamepadled[player].value == 0)
{
I_SetGamepadIndicatorColor(playernum, 0, 0, 255);
INT32 device = G_GetDeviceForPlayer(player);
if (device <= 0)
return;
I_SetGamepadIndicatorColor(device, 0, 0, 255);
}
else
G_SetPlayerGamepadIndicatorColor(playernum, 0);
G_SetPlayerGamepadIndicatorColor(player, 0);
}
static void G_ResetPlayerDeviceRumble(INT32 playernum)
static void G_ResetPlayerDeviceRumble(INT32 player)
{
I_GamepadRumble(playernum, 0, 0, 0);
INT32 device_id;
device_id = G_GetDeviceForPlayer(player);
if (device_id < 1)
{
return;
}
I_GamepadRumble(device_id, 0, 0, 0);
}
void G_ResetAllDeviceRumbles(void)
{
int i;
int devices;
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
devices = I_NumJoys();
for (i = 0; i < devices; i++)
{
I_GamepadRumble(i, 0, 0, 0);
INT32 device_id = G_GetDeviceForPlayer(i);
I_GamepadRumble(device_id, 0, 0, 0);
}
}
void G_PlayerDeviceRumble(INT32 playernum, UINT16 low_strength, UINT16 high_strength, UINT32 duration)
void G_PlayerDeviceRumble(INT32 player, UINT16 low_strength, UINT16 high_strength, UINT32 duration)
{
I_Assert(playernum >= 0 && playernum < MAXSPLITSCREENPLAYERS);
INT32 device_id;
if (cv_rumble[playernum].value == 0)
if (cv_rumble[player].value == 0)
{
return;
}
I_GamepadRumble(playernum, low_strength, high_strength, duration);
device_id = G_GetDeviceForPlayer(player);
if (device_id < 1)
{
return;
}
I_GamepadRumble(device_id, low_strength, high_strength, duration);
}
//
@@ -984,14 +1058,13 @@ void G_ClearControlKeys(INT32 (*setupcontrols)[2], INT32 control)
void G_ClearAllControlKeys(void)
{
INT32 i, k;
for (k = 0; k < MAXSPLITSCREENPLAYERS; k++)
INT32 i;
for (i = 0; i < num_gamecontrols; i++)
{
for (i = 0; i < num_gamecontrols; i++)
{
G_ClearControlKeys(gamecontrol[k], i);
}
G_ClearControlKeys(gamecontrol, i);
G_ClearControlKeys(gamecontrolbis, i);
G_ClearControlKeys(gamecontrol3, i);
G_ClearControlKeys(gamecontrol4, i);
}
}
@@ -1030,7 +1103,7 @@ INT32 G_KeyStringtoNum(const char *keystr)
if (!keystr[0])
return 0;
if (!keystr[0] || (!keystr[1] && keystr[0] > ' ' && keystr[0] <= 'z'))
if (!keystr[1] && keystr[0] > ' ' && keystr[0] <= 'z')
return keystr[0];
if (!strncmp(keystr, "KEY", 3) && keystr[3] >= '0' && keystr[3] <= '9')
@@ -1049,131 +1122,158 @@ void G_Controldefault(UINT8 player)
if (player == 0 || player == 1)
{
// Main controls
gamecontrol[0][gc_aimforward ][0] = KEY_UPARROW;
gamecontrol[0][gc_aimbackward][0] = KEY_DOWNARROW;
gamecontrol[0][gc_turnleft ][0] = KEY_LEFTARROW;
gamecontrol[0][gc_turnright ][0] = KEY_RIGHTARROW;
gamecontrol[0][gc_accelerate ][0] = 'a';
gamecontrol[0][gc_drift ][0] = 's';
gamecontrol[0][gc_brake ][0] = 'd';
gamecontrol[0][gc_fire ][0] = KEY_SPACE;
gamecontrol[0][gc_lookback ][0] = KEY_LSHIFT;
gamecontrol[gc_aimforward ][0] = KEY_UPARROW;
gamecontrol[gc_aimbackward][0] = KEY_DOWNARROW;
gamecontrol[gc_turnleft ][0] = KEY_LEFTARROW;
gamecontrol[gc_turnright ][0] = KEY_RIGHTARROW;
gamecontrol[gc_accelerate ][0] = 'a';
gamecontrol[gc_drift ][0] = 's';
gamecontrol[gc_brake ][0] = 'd';
gamecontrol[gc_fire ][0] = KEY_SPACE;
gamecontrol[gc_lookback ][0] = KEY_LSHIFT;
gamecontrol[0][gc_accelerate ][1] = KEY_JOY1+0; // A
gamecontrol[0][gc_lookback ][1] = KEY_JOY1+2; // X
gamecontrol[0][gc_brake ][1] = KEY_JOY1+1; // B
gamecontrol[0][gc_fire ][1] = KEY_JOY1+9; // LB
gamecontrol[0][gc_drift ][1] = KEY_JOY1+10; // RB
gamecontrol[gc_accelerate ][1] = KEY_JOY1+0; // A
gamecontrol[gc_lookback ][1] = KEY_JOY1+2; // X
gamecontrol[gc_brake ][1] = KEY_JOY1+1; // B
gamecontrol[gc_fire ][1] = KEY_JOY1+9; // LB
gamecontrol[gc_drift ][1] = KEY_JOY1+10; // RB
// Extra controls
gamecontrol[0][gc_pause ][0] = KEY_PAUSE;
gamecontrol[0][gc_console ][0] = KEY_CONSOLE;
gamecontrol[0][gc_screenshot ][0] = KEY_F8;
gamecontrol[0][gc_recordgif ][0] = KEY_F9;
gamecontrol[0][gc_viewpoint ][0] = KEY_F12;
gamecontrol[0][gc_talkkey ][0] = 't';
gamecontrol[gc_pause ][0] = KEY_PAUSE;
gamecontrol[gc_console ][0] = KEY_CONSOLE;
gamecontrol[gc_screenshot ][0] = KEY_F8;
gamecontrol[gc_recordgif ][0] = KEY_F9;
gamecontrol[gc_viewpoint ][0] = KEY_F12;
gamecontrol[gc_talkkey ][0] = 't';
//gamecontrol[gc_teamkey ][0] = 'y';
gamecontrol[0][gc_scores ][0] = KEY_TAB;
gamecontrol[0][gc_spectate ][0] = '\'';
gamecontrol[0][gc_lookup ][0] = KEY_PGUP;
gamecontrol[0][gc_lookdown ][0] = KEY_PGDN;
gamecontrol[0][gc_centerview ][0] = KEY_END;
gamecontrol[0][gc_camreset ][0] = KEY_HOME;
gamecontrol[0][gc_camtoggle ][0] = KEY_BACKSPACE;
gamecontrol[gc_scores ][0] = KEY_TAB;
gamecontrol[gc_spectate ][0] = '\'';
gamecontrol[gc_lookup ][0] = KEY_PGUP;
gamecontrol[gc_lookdown ][0] = KEY_PGDN;
gamecontrol[gc_centerview ][0] = KEY_END;
gamecontrol[gc_camreset ][0] = KEY_HOME;
gamecontrol[gc_camtoggle ][0] = KEY_BACKSPACE;
gamecontrol[0][gc_viewpoint ][1] = KEY_JOY1+3; // Y
gamecontrol[0][gc_pause ][1] = KEY_JOY1+4; // Back
gamecontrol[0][gc_systemmenu ][0] = KEY_JOY1+6; // Start
//gamecontrol[0][gc_camtoggle ][1] = KEY_HAT1+0; // D-Pad Up
//gamecontrol[0][gc_screenshot ][1] = KEY_HAT1+1; // D-Pad Down // absolutely fucking NOT
gamecontrol[0][gc_talkkey ][1] = KEY_HAT1+1; // D-Pad Down
gamecontrol[0][gc_scores ][1] = KEY_HAT1+0; // D-Pad Up
gamecontrol[gc_viewpoint ][1] = KEY_JOY1+3; // Y
gamecontrol[gc_pause ][1] = KEY_JOY1+4; // Back
gamecontrol[gc_systemmenu ][0] = KEY_JOY1+6; // Start
//gamecontrol[gc_camtoggle ][1] = KEY_HAT1+0; // D-Pad Up
//gamecontrol[gc_screenshot ][1] = KEY_HAT1+1; // D-Pad Down // absolutely fucking NOT
gamecontrol[gc_talkkey ][1] = KEY_HAT1+1; // D-Pad Down
gamecontrol[gc_scores ][1] = KEY_HAT1+0; // D-Pad Up
}
if (player == 0 || player == 2)
{
// Player 2 controls
gamecontrol[1][gc_accelerate ][0] = KEY_2JOY1+0; // A
gamecontrol[1][gc_lookback ][0] = KEY_2JOY1+2; // X
gamecontrol[1][gc_brake ][0] = KEY_2JOY1+1; // B
gamecontrol[1][gc_fire ][0] = KEY_2JOY1+9; // LB
gamecontrol[1][gc_drift ][0] = KEY_2JOY1+10; // RB
gamecontrolbis[gc_accelerate ][0] = KEY_2JOY1+0; // A
gamecontrolbis[gc_lookback ][0] = KEY_2JOY1+2; // X
gamecontrolbis[gc_brake ][0] = KEY_2JOY1+1; // B
gamecontrolbis[gc_fire ][0] = KEY_2JOY1+9; // LB
gamecontrolbis[gc_drift ][0] = KEY_2JOY1+10; // RB
}
if (player == 0 || player == 3)
{
// Player 3 controls
gamecontrol[2][gc_accelerate ][0] = KEY_3JOY1+0; // A
gamecontrol[2][gc_lookback ][0] = KEY_3JOY1+2; // X
gamecontrol[2][gc_brake ][0] = KEY_3JOY1+1; // B
gamecontrol[2][gc_fire ][0] = KEY_3JOY1+9; // LB
gamecontrol[2][gc_drift ][0] = KEY_3JOY1+10; // RB
gamecontrol3[gc_accelerate ][0] = KEY_3JOY1+0; // A
gamecontrol3[gc_lookback ][0] = KEY_3JOY1+2; // X
gamecontrol3[gc_brake ][0] = KEY_3JOY1+1; // B
gamecontrol3[gc_fire ][0] = KEY_3JOY1+9; // LB
gamecontrol3[gc_drift ][0] = KEY_3JOY1+10; // RB
}
if (player == 0 || player == 4)
{
// Player 4 controls
gamecontrol[3][gc_accelerate ][0] = KEY_4JOY1+0; // A
gamecontrol[3][gc_lookback ][0] = KEY_4JOY1+2; // X
gamecontrol[3][gc_brake ][0] = KEY_4JOY1+1; // B
gamecontrol[3][gc_fire ][0] = KEY_4JOY1+9; // LB
gamecontrol[3][gc_drift ][0] = KEY_4JOY1+10; // RB
gamecontrol4[gc_accelerate ][0] = KEY_4JOY1+0; // A
gamecontrol4[gc_lookback ][0] = KEY_4JOY1+2; // X
gamecontrol4[gc_brake ][0] = KEY_4JOY1+1; // B
gamecontrol4[gc_fire ][0] = KEY_4JOY1+9; // LB
gamecontrol4[gc_drift ][0] = KEY_4JOY1+10; // RB
}
}
void G_SaveKeySetting(FILE *f)
{
INT32 i, k;
INT32 i;
static const char *controltext[MAXSPLITSCREENPLAYERS] = {
"setcontrol",
"setcontrol2",
"setcontrol3",
"setcontrol4"
};
for (k = 0; k < MAXSPLITSCREENPLAYERS; k++)
for (i = 1; i < num_gamecontrols; i++)
{
for (i = 1; i < num_gamecontrols; i++)
{
fprintf(f, "%s \"%s\" \"%s\"", controltext[k], gamecontrolname[i],
G_KeynumToString(gamecontrol[k][i][0]));
fprintf(f, "setcontrol \"%s\" \"%s\"", gamecontrolname[i],
G_KeynumToString(gamecontrol[i][0]));
if (gamecontrol[k][i][1])
fprintf(f, " \"%s\"\n", G_KeynumToString(gamecontrol[k][i][1]));
else
fprintf(f, "\n");
}
if (gamecontrol[i][1])
fprintf(f, " \"%s\"\n", G_KeynumToString(gamecontrol[i][1]));
else
fprintf(f, "\n");
}
for (i = 1; i < num_gamecontrols; i++)
{
fprintf(f, "setcontrol2 \"%s\" \"%s\"", gamecontrolname[i],
G_KeynumToString(gamecontrolbis[i][0]));
if (gamecontrolbis[i][1])
fprintf(f, " \"%s\"\n", G_KeynumToString(gamecontrolbis[i][1]));
else
fprintf(f, "\n");
}
for (i = 1; i < num_gamecontrols; i++)
{
fprintf(f, "setcontrol3 \"%s\" \"%s\"", gamecontrolname[i],
G_KeynumToString(gamecontrol3[i][0]));
if (gamecontrol3[i][1])
fprintf(f, " \"%s\"\n", G_KeynumToString(gamecontrol3[i][1]));
else
fprintf(f, "\n");
}
for (i = 1; i < num_gamecontrols; i++)
{
fprintf(f, "setcontrol4 \"%s\" \"%s\"", gamecontrolname[i],
G_KeynumToString(gamecontrol4[i][0]));
if (gamecontrol4[i][1])
fprintf(f, " \"%s\"\n", G_KeynumToString(gamecontrol4[i][1]));
else
fprintf(f, "\n");
}
}
INT32 G_CheckDoubleUsage(INT32 keynum, boolean modify)
{
INT32 result = gc_null;
if (cv_controlperkey.value == 1)
{
INT32 i, j, k;
for (k = 0; k < MAXSPLITSCREENPLAYERS; k++)
INT32 i, j;
for (i = 0; i < num_gamecontrols; i++)
{
for (i = 0; i < num_gamecontrols; i++)
for (j = 0; j < 2; j++)
{
for (j = 0; j < 2; j++)
{
if (gamecontrol[k][i][j] == keynum)
{
result = i;
if (modify) gamecontrol[k][i][j] = KEY_NULL;
}
if (result && !modify)
return result;
if (gamecontrol[i][j] == keynum) {
result = i;
if (modify) gamecontrol[i][j] = KEY_NULL;
}
if (gamecontrolbis[i][j] == keynum) {
result = i;
if (modify) gamecontrolbis[i][j] = KEY_NULL;
}
if (gamecontrol3[i][j] == keynum) {
result = i;
if (modify) gamecontrol3[i][j] = KEY_NULL;
}
if (gamecontrol4[i][j] == keynum) {
result = i;
if (modify) gamecontrol4[i][j] = KEY_NULL;
}
if (result && !modify)
return result;
}
}
}
return result;
}
@@ -1327,11 +1427,11 @@ static void setcontrol(INT32 (*gc)[2])
INT32 player;
boolean nestedoverride = false;
if ((void*)gc == (void*)&gamecontrol[3])
if ((void*)gc == (void*)&gamecontrol4)
player = 3;
else if ((void*)gc == (void*)&gamecontrol[2])
else if ((void*)gc == (void*)&gamecontrol3)
player = 2;
else if ((void*)gc == (void*)&gamecontrol[1])
else if ((void*)gc == (void*)&gamecontrolbis)
player = 1;
else
player = 0;
@@ -1394,7 +1494,7 @@ void Command_Setcontrol_f(void)
return;
}
setcontrol(gamecontrol[0]);
setcontrol(gamecontrol);
}
void Command_Setcontrol2_f(void)
@@ -1409,7 +1509,7 @@ void Command_Setcontrol2_f(void)
return;
}
setcontrol(gamecontrol[1]);
setcontrol(gamecontrolbis);
}
void Command_Setcontrol3_f(void)
@@ -1424,7 +1524,7 @@ void Command_Setcontrol3_f(void)
return;
}
setcontrol(gamecontrol[2]);
setcontrol(gamecontrol3);
}
void Command_Setcontrol4_f(void)
@@ -1439,5 +1539,5 @@ void Command_Setcontrol4_f(void)
return;
}
setcontrol(gamecontrol[3]);
setcontrol(gamecontrol4);
}
+22 -18
View File
@@ -41,10 +41,12 @@ typedef enum
KEY_DBLJOY1 = KEY_DBLMOUSE1 + MOUSEBUTTONS,
KEY_DBLHAT1 = KEY_DBLJOY1 + JOYBUTTONS,
KEY_2JOY1 = KEY_DBLHAT1 + MOUSEBUTTONS,
KEY_2MOUSE1 = KEY_DBLHAT1 + JOYHATS*4,
KEY_2JOY1 = KEY_2MOUSE1 + MOUSEBUTTONS,
KEY_2HAT1 = KEY_2JOY1 + JOYBUTTONS,
KEY_DBL2JOY1 = KEY_2HAT1 + MOUSEBUTTONS,
KEY_DBL2MOUSE1 = KEY_2HAT1 + JOYHATS*4,
KEY_DBL2JOY1 = KEY_DBL2MOUSE1 + MOUSEBUTTONS,
KEY_DBL2HAT1 = KEY_DBL2JOY1 + JOYBUTTONS,
KEY_3JOY1 = KEY_DBL2HAT1 + JOYHATS*4,
@@ -61,8 +63,10 @@ typedef enum
KEY_MOUSEWHEELUP = KEY_DBL4HAT1 + JOYHATS*4,
KEY_MOUSEWHEELDOWN = KEY_MOUSEWHEELUP + 1,
KEY_2MOUSEWHEELUP = KEY_MOUSEWHEELDOWN + 1,
KEY_2MOUSEWHEELDOWN = KEY_2MOUSEWHEELUP + 1,
NUMINPUTS = KEY_MOUSEWHEELDOWN + 1,
NUMINPUTS = KEY_2MOUSEWHEELDOWN + 1,
} key_input_e;
typedef enum
@@ -96,22 +100,20 @@ typedef enum
gc_custom2, // Lua scriptable
gc_custom3, // Lua scriptable
gc_director,
gc_freecam, // Toggle for freecam while ingame
gc_camfloat, // alternative button for raising cam
gc_camsink, // alternative button for sinking
gc_strafeleft,
gc_straferight,
num_gamecontrols
} gamecontrols_e;
// mouse values are used once
extern consvar_t cv_mousesens, cv_mouseysens;
extern consvar_t cv_mousesens2, cv_mouseysens2;
extern consvar_t cv_controlperkey, cv_turnsmooth;
extern consvar_t cv_rumble[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_gamepadled[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_ledpowerup[MAXSPLITSCREENPLAYERS];
extern INT32 mousex, mousey;
extern INT32 mlooky; //mousey with mlookSensitivity
extern INT32 mouse2x, mouse2y, mlook2y;
extern INT32 joyxmove[JOYAXISSET], joyymove[JOYAXISSET], joy2xmove[JOYAXISSET], joy2ymove[JOYAXISSET],
joy3xmove[JOYAXISSET], joy3ymove[JOYAXISSET], joy4xmove[JOYAXISSET], joy4ymove[JOYAXISSET];
@@ -120,24 +122,26 @@ extern INT32 joyxmove[JOYAXISSET], joyymove[JOYAXISSET], joy2xmove[JOYAXISSET],
extern UINT8 gamekeydown[NUMINPUTS];
// two key codes (or virtual key) per game control
extern INT32 gamecontrol[MAXSPLITSCREENPLAYERS][num_gamecontrols][2];
#define PLAYER1INPUTDOWN(gc) (gamekeydown[gamecontrol[0][gc][0]] || gamekeydown[gamecontrol[0][gc][1]])
#define PLAYER2INPUTDOWN(gc) (gamekeydown[gamecontrol[1][gc][0]] || gamekeydown[gamecontrol[1][gc][1]])
#define PLAYER3INPUTDOWN(gc) (gamekeydown[gamecontrol[2][gc][0]] || gamekeydown[gamecontrol[2][gc][1]])
#define PLAYER4INPUTDOWN(gc) (gamekeydown[gamecontrol[3][gc][0]] || gamekeydown[gamecontrol[3][gc][1]])
extern INT32 gamecontrol[num_gamecontrols][2];
extern INT32 gamecontrolbis[num_gamecontrols][2]; // secondary splitscreen player
extern INT32 gamecontrol3[num_gamecontrols][2];
extern INT32 gamecontrol4[num_gamecontrols][2];
#define PLAYER1INPUTDOWN(gc) (gamekeydown[gamecontrol[gc][0]] || gamekeydown[gamecontrol[gc][1]])
#define PLAYER2INPUTDOWN(gc) (gamekeydown[gamecontrolbis[gc][0]] || gamekeydown[gamecontrolbis[gc][1]])
#define PLAYER3INPUTDOWN(gc) (gamekeydown[gamecontrol3[gc][0]] || gamekeydown[gamecontrol3[gc][1]])
#define PLAYER4INPUTDOWN(gc) (gamekeydown[gamecontrol4[gc][0]] || gamekeydown[gamecontrol4[gc][1]])
// peace to my little coder fingers!
// check a gamecontrol being active or not
UINT16 G_GetSkinColor(INT32 playernum);
void G_SetPlayerGamepadIndicatorColor(INT32 playernum, UINT16 color);
UINT16 G_GetSkinColor(INT32 player);
INT32 G_GetDeviceForPlayer(INT32 player);
void G_SetPlayerGamepadIndicatorColor(INT32 player, UINT16 color);
void G_PlayerDeviceRumble(INT32 player, UINT16 low_strength, UINT16 high_strength, UINT32 duration);
void G_ResetAllDeviceRumbles(void);
void G_PlayerDeviceRumble(INT32 playernum, UINT16 low_strength, UINT16 high_strength, UINT32 duration);
// remaps the input event to a game control.
void G_MapEventsToControls(event_t *ev);
void G_ResetControls(void);
// returns the name of a key
const char *G_KeynumToString(INT32 keynum);
+85
View File
@@ -0,0 +1,85 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// Copyright (C) 2001 by DooM Legacy Team.
//
// 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.
//
//-----------------------------------------------------------------------------
/// \file
/// \brief 3D sound import/export prototypes for low-level hardware interface
#ifndef __HW_3DS_DRV_H__
#define __HW_3DS_DRV_H__
// Use standart hardware API
#include "hw_dll.h"
#include "hws_data.h"
#if defined (HAVE_SDL) || !defined (HWD)
EXPORT void HWRAPI(Shutdown) (void);
#endif
// Use standart Init and Shutdown functions
EXPORT INT32 HWRAPI (Startup) (I_Error_t FatalErrorFunction, snddev_t *snd_dev);
EXPORT u_int HWRAPI (AddSfx) (sfx_data_t *sfx);
EXPORT INT32 HWRAPI (AddSource) (source3D_data_t *src, u_int sfxhandle);
EXPORT INT32 HWRAPI (StartSource) (INT32 handle);
EXPORT void HWRAPI (StopSource) (INT32 handle);
EXPORT INT32 HWRAPI (GetHW3DSVersion) (void);
EXPORT void HWRAPI (BeginFrameUpdate) (void);
EXPORT void HWRAPI (EndFrameUpdate) (void);
EXPORT INT32 HWRAPI (IsPlaying) (INT32 handle);
EXPORT void HWRAPI (UpdateListener) (listener_data_t *data, INT32 num);
EXPORT void HWRAPI (UpdateSourceParms) (INT32 handle, INT32 vol, INT32 sep);
EXPORT void HWRAPI (SetGlobalSfxVolume) (INT32 volume);
EXPORT INT32 HWRAPI (SetCone) (INT32 handle, cone_def_t *cone_def);
EXPORT void HWRAPI (Update3DSource) (INT32 handle, source3D_pos_t *data);
EXPORT INT32 HWRAPI (ReloadSource) (INT32 handle, u_int sfxhandle);
EXPORT void HWRAPI (KillSource) (INT32 handle);
EXPORT void HWRAPI (KillSfx) (u_int sfxhandle);
EXPORT void HWRAPI (GetHW3DSTitle) (char *buf, size_t size);
#if !defined (_CREATE_DLL_)
struct hardware3ds_s
{
Startup pfnStartup;
AddSfx pfnAddSfx;
AddSource pfnAddSource;
StartSource pfnStartSource;
StopSource pfnStopSource;
GetHW3DSVersion pfnGetHW3DSVersion;
BeginFrameUpdate pfnBeginFrameUpdate;
EndFrameUpdate pfnEndFrameUpdate;
IsPlaying pfnIsPlaying;
UpdateListener pfnUpdateListener;
UpdateSourceParms pfnUpdateSourceParms;
SetGlobalSfxVolume pfnSetGlobalSfxVolume;
SetCone pfnSetCone;
Update3DSource pfnUpdate3DSource;
ReloadSource pfnReloadSource;
KillSource pfnKillSource;
KillSfx pfnKillSfx;
Shutdown pfnShutdown;
GetHW3DSTitle pfnGetHW3DSTitle;
};
extern struct hardware3ds_s hw3ds_driver;
#define HW3DS hw3ds_driver
#endif // _CREATE_DLL_
#endif // __HW_3DS_DRV_H__
+996
View File
@@ -0,0 +1,996 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// Copyright (C) 2001 by DooM Legacy Team.
//
// 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.
//-----------------------------------------------------------------------------
/// \file
/// \brief Hardware 3D sound general code
#include "../doomdef.h"
#ifdef HW3SOUND
#include "../i_sound.h"
#include "../s_sound.h"
#include "../w_wad.h"
#include "../z_zone.h"
#include "../g_game.h"
#include "../tables.h"
#include "../sounds.h"
#include "../r_main.h"
#include "../r_things.h"
#include "../m_random.h"
#include "../p_local.h"
#include "hw3dsdrv.h"
#include "hw3sound.h"
#define ANGLE2DEG(x) (((double)(x)) / ((double)ANGLE_45/45))
#define NORM_PITCH 128
#define NORM_PRIORITY 64
#define NORM_SEP 128
#if 1
#define TPS(x) (x)
#else //Alam_GBC: MPS, not MPF!
#define TPS(x) ((float)(x)/(float)TICRATE)
#endif
struct hardware3ds_s hw3ds_driver;
typedef struct source_s
{
sfxinfo_t *sfxinfo;
const void *origin;
INT32 handle; // Internal source handle
channel_type_t type; // Sound type (attack, scream, etc)
} source_t;
typedef struct ambient_sdata_s
{
source3D_data_t left;
source3D_data_t right;
} ambient_sdata_t;
typedef struct ambient_source_s
{
source_t left;
source_t right;
} ambient_source_t;
// Static sources
// This sources always creates
static source_t p_attack_source; // Player attack source
static source_t p_attack_source2; // Player2 attack source
static source_t p_scream_source; // Player scream source
static source_t p_scream_source2; // Player2 scream source
static ambient_source_t ambient_source; // Ambinet sound sources
// abuse???
//static source3D_data_t p_attack_sdata; // ?? Now just holds precalculated player attack source data
//static source3D_data_t p_default_sdata;// ?? ---- // ---- // ---- // ---- player scream source data
static ambient_sdata_t ambient_sdata; // Precalculated datas of an ambient sound sources
// Stack of dynamic sources
static source_t *sources = NULL; // Much like original channels
static INT32 num_sources = 0;
// Current mode of 3D sound system
// Default is original (stereo) mode
INT32 hws_mode = HWS_DEFAULT_MODE;
//=============================================================================
void HW3S_SetSourcesNum(void)
{
INT32 i;
// Allocating the internal channels for mixing
// (the maximum number of sounds rendered
// simultaneously) within zone memory.
if (sources)
HW3S_StopSounds();
Z_Free(sources);
if (cv_numChannels.value <= STATIC_SOURCES_NUM)
I_Error("HW3S_SetSourcesNum: Number of sound sources cannot be less than %d\n", STATIC_SOURCES_NUM + 1);
num_sources = cv_numChannels.value - STATIC_SOURCES_NUM;
sources = (source_t *) Z_Malloc(num_sources * sizeof (*sources), PU_STATIC, 0);
// Free all channels for use
for (i = 0; i < num_sources; i++)
{
sources[i].sfxinfo = NULL;
sources[i].type = CT_NORMAL;
sources[i].handle = -1;
}
}
//=============================================================================
static void HW3S_KillSource(INT32 snum)
{
source_t * s = &sources[snum];
if (s->sfxinfo)
{
HW3DS.pfnStopSource(s->handle);
HW3DS.pfnKillSource(s->handle);
s->handle = -1;
s->sfxinfo->usefulness--;
s->origin = NULL;
s->sfxinfo = NULL;
}
}
//=============================================================================
/*
static void HW3S_StopSource(INT32 snum)
{
source_t * s = &sources[snum];
if (s->sfxinfo)
{
// stop the sound playing
HW3DS.pfnStopSource(s->handle);
}
}
*/
//=============================================================================
void HW3S_StopSound(void *origin)
{
INT32 snum;
for (snum = 0; snum < num_sources; snum++)
{
if (sources[snum].sfxinfo && sources[snum].origin == origin)
{
HW3S_KillSource(snum);
break;
}
}
}
void HW3S_StopSoundByID(void *origin, sfxenum_t sfx_id)
{
INT32 snum;
for (snum = 0; snum < num_sources; snum++)
{
if (sources[snum].sfxinfo == &S_sfx[sfx_id] && sources[snum].origin == origin)
{
HW3S_KillSource(snum);
break;
}
}
}
void HW3S_StopSoundByNum(sfxenum_t sfxnum)
{
INT32 snum;
for (snum = 0; snum < num_sources; snum++)
{
if (sources[snum].sfxinfo == &S_sfx[sfxnum])
{
HW3S_KillSource(snum);
break;
}
}
}
//=============================================================================
void HW3S_StopSounds(void)
{
INT32 snum;
// kill all playing sounds at start of level
// (trust me - a good idea)
for (snum = 0; snum < num_sources; snum++)
if (sources[snum].sfxinfo)
HW3S_KillSource(snum);
// Also stop all static sources
HW3DS.pfnStopSource(p_attack_source.handle);
HW3DS.pfnStopSource(p_attack_source2.handle);
HW3DS.pfnStopSource(p_scream_source.handle);
HW3DS.pfnStopSource(p_scream_source2.handle);
HW3DS.pfnStopSource(ambient_source.left.handle);
HW3DS.pfnStopSource(ambient_source.right.handle);
}
//=============================================================================
static INT32 HW3S_GetSource(const void *origin, sfxinfo_t *sfxinfo, boolean splitsound)
{
//
// If none available, return -1. Otherwise source #.
// source number to use
INT32 snum;
source_t * src;
INT32 sep = NORM_SEP, pitch = NORM_PITCH, volume = 255;
(void)splitsound;
// Find an open source
for (snum = 0, src = sources; snum < num_sources; src++, snum++)
{
if (!src->sfxinfo)
break;
#if 0
if (origin && src->origin == origin)
{
HW3S_KillSource(snum);
break;
}
#endif
}
#if 0
// Check to see if it is audible
if (origin && origin != listenmobj)
{
INT32 rc;
rc = S_AdjustSoundParams(listenmobj, origin, &volume, &sep, &pitch, sfxinfo);
if (!rc)
return -1;
}
#else
(void)origin;
(void)pitch;
(void)volume;
(void)sep;
#endif
// None available
if (snum == num_sources)
{
// Look for lower priority
for (snum = 0, src = sources; snum < num_sources; src++, snum++)
if (src->sfxinfo->priority <= sfxinfo->priority)
break;
if (snum == num_sources)
{
// No lower priority. Sorry, Charlie.
return -1;
}
else
{
// Otherwise, kick out lower priority
HW3S_KillSource(snum);
}
}
return snum;
}
//=============================================================================
static void HW3S_FillSourceParameters
(const mobj_t *origin,
source3D_data_t *data,
channel_type_t c_type)
{
fixed_t x = 0, y = 0, z = 0;
data->max_distance = MAX_DISTANCE;
data->min_distance = MIN_DISTANCE;
if (origin && origin != players[displayplayers[0]].mo)
{
data->head_relative = false;
data->pos.momx = TPS(FIXED_TO_FLOAT(origin->momx));
data->pos.momy = TPS(FIXED_TO_FLOAT(origin->momy));
data->pos.momz = TPS(FIXED_TO_FLOAT(origin->momz));
x = origin->x;
y = origin->y;
z = origin->z;
if (c_type == CT_ATTACK)
{
const angle_t an = origin->angle >> ANGLETOFINESHIFT;
x += FixedMul(16*FRACUNIT, FINECOSINE(an));
y += FixedMul(16*FRACUNIT, FINESINE(an));
z += origin->height >> 1;
}
else if (c_type == CT_SCREAM)
z += origin->height - (5 * FRACUNIT);
}
else
{
data->head_relative = true;
data->pos.momx = 0.0f;
data->pos.momy = 0.0f;
data->pos.momz = 0.0f;
}
data->pos.x = FIXED_TO_FLOAT(x);
data->pos.y = FIXED_TO_FLOAT(y);
data->pos.z = FIXED_TO_FLOAT(z);
}
#define HEADER_SIZE 8
//==============================================================
/*
static void make_outphase_sfx(void *dest, void *src, INT32 size)
{
SINT8 *s = (SINT8 *)src + HEADER_SIZE, *d = (SINT8 *)dest + HEADER_SIZE;
M_Memcpy(dest, src, HEADER_SIZE);
size -= HEADER_SIZE;
while (size--)
*d++ = -(*s++);
}
*/
//INT32 HW3S_Start3DSound(const void *origin, source3D_data_t *source_parm, cone_def_t *cone_parm, channel_type_t channel, INT32 sfx_id, INT32 vol, INT32 pitch);
//=============================================================================
INT32 HW3S_I_StartSound(const void *origin_p, source3D_data_t *source_parm, channel_type_t c_type, sfxenum_t sfx_id, INT32 volume, INT32 pitch, INT32 sep)
{
sfxinfo_t *sfx;
const mobj_t *origin = (const mobj_t *)origin_p;
source3D_data_t source3d_data;
INT32 s_num = 0;
source_t *source = NULL;
mobj_t *listenmobj = players[displayplayers[0]].mo; // TODO: Kart 4P does not support sounds properly here
mobj_t *listenmobj2 = NULL;
if (splitscreen) listenmobj2 = players[displayplayers[1]].mo;
if (sound_disabled)
return -1;
sfx = &S_sfx[sfx_id];
if (sfx->skinsound!=-1 && origin && origin->skin)
{
// it redirect player sound to the sound in the skin table
sfx_id = ((skin_t *)origin->skin)->soundsid[sfx->skinsound];
sfx = &S_sfx[sfx_id];
}
if (!sfx->data)
sfx->data = HW3S_GetSfx(sfx);
// judgecutor 08-16-2002
// Sound pitching for both Doom and Heretic
#if 0
if (cv_rndsoundpitch.value)
{
/*if (gamemode != heretic)
{
if (sfx_id >= sfx_sawup && sfx_id <= sfx_sawhit)
pitch += 8 - (M_RandomByte()&15);
else if (sfx_id != sfx_itemup && sfx_id != sfx_tink)
pitch += 16 - (M_RandomByte()&31);
}
else*/
pitch = 128 + (M_RandomByte() & 7) - (M_RandomByte() & 7);
}
#endif
if (pitch < 0)
pitch = NORMAL_PITCH;
if (pitch > 255)
pitch = 255;
if (sep < 0)
sep = 128;
if (splitscreen && listenmobj2) // Copy the sound for the split player
{
if (c_type != CT_NORMAL && origin && (origin == listenmobj2))
{
if (c_type == CT_ATTACK)
{
if (origin == listenmobj2)
source = &p_attack_source;
else
source = &p_attack_source2;
}
else
{
if (origin == listenmobj2)
source = &p_scream_source;
else
source = &p_scream_source2;
}
if (source->sfxinfo != sfx)
{
HW3DS.pfnStopSource(source->handle);
source->handle = HW3DS.pfnReloadSource(source->handle, sfx->volume);
//I_OutputMsg("PlayerSound data reloaded\n");
}
}
else if (c_type == CT_AMBIENT)
{
// sfx_data_t outphased_sfx;
if (ambient_source.left.sfxinfo != sfx)
{
HW3DS.pfnStopSource(ambient_source.left.handle);
HW3DS.pfnStopSource(ambient_source.right.handle);
// judgecutor:
// Outphased sfx's temporarily not used!!!
/*
outphased_sfx.data = Z_Malloc(sfx_data.length, PU_STATIC, 0);
make_outphase_sfx(outphased_sfx.data, sfx_data.data, sfx_data.length);
outphased_sfx.length = sfx_data.length;
outphased_sfx.id = sfx_data.id;
*/
ambient_source.left.handle = HW3DS.pfnReloadSource(ambient_source.left.handle, (u_int)sfx->length);
//ambient_source.right.handle = HW3DS.pfnReloadSource(ambient_source.right.handle, &outphased_sfx);
ambient_source.right.handle = HW3DS.pfnReloadSource(ambient_source.right.handle, (u_int)sfx->length);
ambient_source.left.sfxinfo = ambient_source.right.sfxinfo = sfx;
//Z_Free(outphased_sfx.data);
}
HW3DS.pfnUpdateSourceParms(ambient_source.left.handle, volume, -1);
HW3DS.pfnUpdateSourceParms(ambient_source.right.handle, volume, -1);
if (sfx->usefulness++ < 0)
sfx->usefulness = -1;
// Ambient sound is special case
HW3DS.pfnStartSource(ambient_source.left.handle);
HW3DS.pfnStartSource(ambient_source.right.handle);
}
else
{
s_num = HW3S_GetSource(origin, sfx, true);
if (s_num < 0)
{
//I_OutputMsg("No free source, aborting\n");
return -1;
}
source = &sources[s_num];
if (origin && c_type == CT_NORMAL)
{
if (!source_parm)
{
source_parm = &source3d_data;
source3d_data.permanent = 0;
HW3S_FillSourceParameters(origin, source_parm, c_type);
}
source->handle = HW3DS.pfnAddSource(source_parm, (u_int)sfx->length);
}
else
source->handle = HW3DS.pfnAddSource(NULL, (u_int)sfx->length);
}
// increase the usefulness
if (sfx->usefulness++ < 0)
sfx->usefulness = -1;
source->sfxinfo = sfx;
source->origin = origin;
HW3DS.pfnStartSource(source->handle);
}
if (c_type != CT_NORMAL && origin && (origin == listenmobj))
{
if (c_type == CT_ATTACK)
{
if (origin == listenmobj)
source = &p_attack_source;
else
source = &p_attack_source2;
}
else
{
if (origin == listenmobj)
source = &p_scream_source;
else
source = &p_scream_source2;
}
if (source->sfxinfo != sfx)
{
HW3DS.pfnStopSource(source->handle);
source->handle = HW3DS.pfnReloadSource(source->handle, sfx->volume);
//I_OutputMsg("PlayerSound data reloaded\n");
}
}
else if (c_type == CT_AMBIENT)
{
// sfx_data_t outphased_sfx;
if (ambient_source.left.sfxinfo != sfx)
{
HW3DS.pfnStopSource(ambient_source.left.handle);
HW3DS.pfnStopSource(ambient_source.right.handle);
// judgecutor:
// Outphased sfx's temporarily not used!!!
/*
outphased_sfx.data = Z_Malloc(sfx_data.length, PU_STATIC, 0);
make_outphase_sfx(outphased_sfx.data, sfx_data.data, sfx_data.length);
outphased_sfx.length = sfx_data.length;
outphased_sfx.id = sfx_data.id;
*/
ambient_source.left.handle = HW3DS.pfnReloadSource(ambient_source.left.handle, (u_int)sfx->length);
//ambient_source.right.handle = HW3DS.pfnReloadSource(ambient_source.right.handle, &outphased_sfx);
ambient_source.right.handle = HW3DS.pfnReloadSource(ambient_source.right.handle, (u_int)sfx->length);
ambient_source.left.sfxinfo = ambient_source.right.sfxinfo = sfx;
//Z_Free(outphased_sfx.data);
}
HW3DS.pfnUpdateSourceParms(ambient_source.left.handle, volume, -1);
HW3DS.pfnUpdateSourceParms(ambient_source.right.handle, volume, -1);
if (sfx->usefulness++ < 0)
sfx->usefulness = -1;
// Ambient sound is special case
HW3DS.pfnStartSource(ambient_source.left.handle);
HW3DS.pfnStartSource(ambient_source.right.handle);
return -1;
}
else
{
s_num = HW3S_GetSource(origin, sfx, false);
if (s_num < 0)
{
//I_OutputMsg("No free source, aborting\n");
return -1;
}
source = &sources[s_num];
if (origin && c_type == CT_NORMAL)
{
if (!source_parm)
{
source_parm = &source3d_data;
source3d_data.permanent = 0;
HW3S_FillSourceParameters(origin, source_parm, c_type);
}
source->handle = HW3DS.pfnAddSource(source_parm, (u_int)sfx->length);
}
else
source->handle = HW3DS.pfnAddSource(NULL, (u_int)sfx->length);
}
// increase the usefulness
if (sfx->usefulness++ < 0)
sfx->usefulness = -1;
source->sfxinfo = sfx;
source->origin = origin;
HW3DS.pfnStartSource(source->handle);
return s_num;
}
// Start normal sound
//=============================================================================
void HW3S_StartSound(const void *origin, sfxenum_t sfx_id)
{
HW3S_I_StartSound(origin, NULL, CT_NORMAL, sfx_id, 255, NORMAL_PITCH, NORMAL_SEP);
}
//=============================================================================
void S_StartAttackSound(const void *origin, sfxenum_t sfx_id)
{
if (hws_mode != HWS_DEFAULT_MODE)
HW3S_I_StartSound(origin, NULL, CT_ATTACK, sfx_id, 255, NORMAL_PITCH, NORMAL_SEP);
else
S_StartSound(origin, sfx_id);
}
void S_StartScreamSound(const void *origin, sfxenum_t sfx_id)
{
if (hws_mode != HWS_DEFAULT_MODE)
HW3S_I_StartSound(origin, NULL, CT_SCREAM, sfx_id, 255, NORMAL_PITCH, NORMAL_SEP);
else
S_StartSound(origin, sfx_id);
}
#if 0 /// NOTE: not used
void S_StartAmbientSound(sfxenum_t sfx_id, INT32 volume)
{
if (hws_mode != HWS_DEFAULT_MODE)
{
volume += 30;
if (volume > 255)
volume = 255;
HW3S_I_StartSound(NULL, NULL, CT_AMBIENT, sfx_id, volume, NORMAL_PITCH, NORMAL_SEP);
}
else
S_StartSoundAtVolume(NULL, sfx_id, volume);
}
#endif
FUNCMATH static inline float AmbientPos(angle_t an)
{
const fixed_t fm = FixedMul(FLOAT_TO_FIXED(MIN_DISTANCE), FINESINE(an>>ANGLETOFINESHIFT));
return FIXED_TO_FLOAT(fm);
}
//=============================================================================
INT32 HW3S_Init(I_Error_t FatalErrorFunction, snddev_t *snd_dev)
{
INT32 succ;
source3D_data_t source_data;
if (HW3DS.pfnStartup(FatalErrorFunction, snd_dev))
{
// Attack source
source_data.head_relative = 1;
source_data.pos.x = 0.0f;
source_data.pos.y = 16.0f;
source_data.pos.z = -FIXED_TO_FLOAT(mobjinfo[MT_PLAYER].height >> 1);
source_data.pos.momx = 0.0f;
source_data.pos.momy = 0.0f;
source_data.pos.momz = 0.0f;
source_data.min_distance = MIN_DISTANCE;
source_data.max_distance = MAX_DISTANCE;
source_data.permanent = 1;
p_attack_source.sfxinfo = NULL;
M_Memcpy(&p_attack_source2, &p_attack_source, sizeof (source_t));
p_attack_source.handle = HW3DS.pfnAddSource(&source_data, sfx_None);
p_attack_source2.handle = HW3DS.pfnAddSource(&source_data, sfx_None);
// Scream source
source_data.pos.y = 0;
source_data.pos.z = 0;
p_scream_source.sfxinfo = NULL;
M_Memcpy(&p_scream_source2, &p_scream_source, sizeof (source_t));
p_scream_source.handle = HW3DS.pfnAddSource(&source_data, sfx_None);
p_scream_source2.handle = HW3DS.pfnAddSource(&source_data, sfx_None);
//FIXED_TO_FLOAT(mobjinfo[MT_PLAYER].height - (5 * FRACUNIT));
// Ambient sources (left and right) at 210 and 330 degree
// relative to listener
memset(&ambient_sdata, 0, sizeof (ambient_sdata));
ambient_sdata.left.head_relative = 1;
ambient_sdata.left.pos.x = ambient_sdata.left.pos.y = AmbientPos(ANG210);
ambient_sdata.left.max_distance = MAX_DISTANCE;
ambient_sdata.left.min_distance = MIN_DISTANCE;
ambient_sdata.left.permanent = 1;
M_Memcpy(&ambient_sdata.right, &ambient_sdata.left, sizeof (source3D_data_t));
ambient_sdata.right.pos.x = -ambient_sdata.left.pos.x;
ambient_source.left.handle = HW3DS.pfnAddSource(&ambient_sdata.left, sfx_None);
ambient_source.right.handle = HW3DS.pfnAddSource(&ambient_sdata.right, sfx_None);
succ = p_attack_source.handle > -1 && p_scream_source.handle > -1 &&
p_attack_source2.handle > -1 && p_scream_source2.handle > -1 &&
ambient_source.left.handle > -1 && ambient_source.right.handle > -1;
//I_OutputMsg("Player handles: attack %d, default %d\n", p_attack_source.handle, p_scream_source.handle);
return succ;
}
return 0;
}
//=============================================================================
INT32 HW3S_GetVersion(void)
{
return HW3DS.pfnGetHW3DSVersion();
}
//=============================================================================
void HW3S_BeginFrameUpdate(void)
{
if (hws_mode != HWS_DEFAULT_MODE)
HW3DS.pfnBeginFrameUpdate();
}
//=============================================================================
void HW3S_EndFrameUpdate(void)
{
if (hws_mode != HWS_DEFAULT_MODE)
HW3DS.pfnEndFrameUpdate();
}
//=============================================================================
INT32 HW3S_SoundIsPlaying(INT32 handle)
{
return HW3DS.pfnIsPlaying(handle);
}
INT32 HW3S_OriginPlaying(void *origin)
{
INT32 snum;
if (!origin)
return 0;
for (snum = 0; snum < num_sources; snum++)
if (sources[snum].origin == origin)
return 1;
return 0;
}
INT32 HW3S_IdPlaying(sfxenum_t id)
{
INT32 snum;
for (snum = 0; snum < num_sources; snum++)
if ((size_t)(sources[snum].sfxinfo - S_sfx) == (size_t)id)
return 1;
return 0;
}
INT32 HW3S_SoundPlaying(void *origin, sfxenum_t id)
{
INT32 snum;
if (!origin)
return 0;
for (snum = 0; snum < num_sources; snum++)
{
if (sources[snum].origin == origin
&& (size_t)(sources[snum].sfxinfo - S_sfx) == (size_t)id)
return 1;
}
return 0;
}
//=============================================================================
static void HW3S_UpdateListener(mobj_t *listener)
{
listener_data_t data;
if (!listener || !listener->player)
return;
if (camera.chase)
{
data.x = FIXED_TO_FLOAT(camera.x);
data.y = FIXED_TO_FLOAT(camera.y);
data.z = FIXED_TO_FLOAT(camera.z + camera.height - (5 * FRACUNIT));
data.f_angle = ANGLE2DEG(camera.angle);
data.h_angle = ANGLE2DEG(camera.aiming);
data.momx = TPS(FIXED_TO_FLOAT(camera.momx));
data.momy = TPS(FIXED_TO_FLOAT(camera.momy));
data.momz = TPS(FIXED_TO_FLOAT(camera.momz));
}
else
{
data.x = FIXED_TO_FLOAT(listener->x);
data.y = FIXED_TO_FLOAT(listener->y);
data.z = FIXED_TO_FLOAT(listener->z + listener->height - (5 * FRACUNIT));
data.f_angle = ANGLE2DEG(listener->angle);
data.h_angle = ANGLE2DEG(listener->player->aiming);
data.momx = TPS(FIXED_TO_FLOAT(listener->momx));
data.momy = TPS(FIXED_TO_FLOAT(listener->momy));
data.momz = TPS(FIXED_TO_FLOAT(listener->momz));
}
HW3DS.pfnUpdateListener(&data, 1);
}
static void HW3S_UpdateListener2(mobj_t *listener)
{
listener_data_t data;
if (!listener || !listener->player)
{
HW3DS.pfnUpdateListener(NULL, 2);
return;
}
if (camera2.chase)
{
data.x = FIXED_TO_FLOAT(camera2.x);
data.y = FIXED_TO_FLOAT(camera2.y);
data.z = FIXED_TO_FLOAT(camera2.z + camera2.height - (5 * FRACUNIT));
data.f_angle = ANGLE2DEG(camera2.angle);
data.h_angle = ANGLE2DEG(camera2.aiming);
data.momx = TPS(FIXED_TO_FLOAT(camera2.momx));
data.momy = TPS(FIXED_TO_FLOAT(camera2.momy));
data.momz = TPS(FIXED_TO_FLOAT(camera2.momz));
}
else
{
data.x = FIXED_TO_FLOAT(listener->x);
data.y = FIXED_TO_FLOAT(listener->y);
data.z = FIXED_TO_FLOAT(listener->z + listener->height - (5 * FRACUNIT));
data.f_angle = ANGLE2DEG(listener->angle);
data.h_angle = ANGLE2DEG(listener->player->aiming);
data.momx = TPS(FIXED_TO_FLOAT(listener->momx));
data.momy = TPS(FIXED_TO_FLOAT(listener->momy));
data.momz = TPS(FIXED_TO_FLOAT(listener->momz));
}
HW3DS.pfnUpdateListener(&data, 2);
}
void HW3S_SetSfxVolume(INT32 volume)
{
HW3DS.pfnSetGlobalSfxVolume(volume);
}
static void HW3S_Update3DSource(source_t *src)
{
source3D_data_t data;
data.permanent = 0;
HW3S_FillSourceParameters(src->origin, &data, src->type);
HW3DS.pfnUpdate3DSource(src->handle, &data.pos);
}
void HW3S_UpdateSources(void)
{
mobj_t *listener = players[displayplayers[0]].mo;
mobj_t *listener2 = NULL;
source_t *src;
INT32 audible, snum, volume, sep, pitch;
if (splitscreen) listener2 = players[displayplayers[1]].mo;
HW3S_UpdateListener2(listener2);
HW3S_UpdateListener(listener);
for (snum = 0, src = sources; snum < num_sources; src++, snum++)
{
if (src->sfxinfo)
{
#if 0
if (HW3DS.pfnIsPlaying(src->handle))
{
if (src->origin)
{
// initialize parameters
volume = 255; // 8 bits internal volume precision
pitch = NORM_PITCH;
sep = NORM_SEP;
// check non-local sounds for distance clipping
// or modify their params
if (src->origin && listener != src->origin && !(listener2 && src->origin == listener2))
{
INT32 audible2;
INT32 volume2 = volume, sep2 = sep, pitch2 = pitch;
audible = S_AdjustSoundParams(listener, src->origin, &volume, &sep, &pitch,
src->sfxinfo);
if (listener2)
{
audible2 = S_AdjustSoundParams(listener2,
src->origin, &volume2, &sep2, &pitch2, src->sfxinfo);
if (audible2 && (!audible || (audible && volume2 > volume)))
{
audible = true;
volume = volume2;
sep = sep2;
pitch = pitch2;
}
}
if (audible)
HW3S_Update3DSource(src); // Update positional sources
else
HW3S_KillSource(snum); //Kill it!
}
}
}
else
{
// Source allocated but stopped. Kill.
HW3S_KillSource(snum);
}
#else
if (src->origin && listener != src->origin && !(listener2 && src->origin == listener2))
HW3S_Update3DSource(src); // Update positional sources
(void)pitch;
(void)sep;
(void)volume;
(void)audible;
#endif
}
}
}
void HW3S_Shutdown(void)
{
HW3DS.pfnShutdown();
}
void *HW3S_GetSfx(sfxinfo_t *sfx)
{
sfx_data_t sfx_data;
if (sfx->lumpnum == LUMPERROR)
sfx->lumpnum = S_GetSfxLumpNum (sfx);
sfx_data.length = W_LumpLength(sfx->lumpnum);
sfx_data.data = Z_Malloc(sfx_data.length, PU_SOUND, &sfx->data);
W_ReadLump(sfx->lumpnum, sfx_data.data);
sfx_data.priority = sfx->priority;
sfx->length = HW3DS.pfnAddSfx(&sfx_data);
Z_ChangeTag(sfx->data, PU_CACHE);
return sfx_data.data;
}
void HW3S_FreeSfx(sfxinfo_t *sfx)
{
INT32 snum;
for (snum = 0; snum < num_sources; snum++)
{
if (sources[snum].sfxinfo == sfx)
{
HW3S_KillSource(snum);
break;
}
}
if (sfx->length > 0)
HW3DS.pfnKillSfx((u_int)sfx->length);
sfx->length = 0;
sfx->lumpnum = LUMPERROR;
Z_Free(sfx->data);
sfx->data = NULL;
}
#endif
+106
View File
@@ -0,0 +1,106 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// Copyright (C) 2001 by DooM Legacy Team.
//
// 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.
//
//-----------------------------------------------------------------------------
/// \file
/// \brief High-level functions of hardware 3D sound
#ifndef __HW3_SOUND_H__
#define __HW3_SOUND_H__
#ifdef HW3SOUND
#include "hws_data.h"
//#include "../s_sound.h"
//#include "../p_mobj.h"
// Default sound mode (original stereo mode)
enum
{
HWS_DEFAULT_MODE = 0,
HWS_DS3D,
HWS_OTHER,
HWS_FMOD3D,
HWS_OPENAL,
};
typedef enum
{
CT_NORMAL = 0,
CT_ATTACK,
CT_SCREAM,
CT_AMBIENT,
} channel_type_t;
extern INT32 hws_mode; // Current sound mode
#if defined (HW3DS) || defined (DOXYGEN)
INT32 HW3S_Init(I_Error_t FatalErrorFunction, snddev_t *snd_dev);
#endif
void HW3S_Shutdown(void);
INT32 HW3S_GetVersion(void);
// Common case - start 3D or 2D source
void HW3S_StartSound(const void *origin, sfxenum_t sfx_id);
// Special cases of 3D sources
void S_StartAmbientSound(sfxenum_t sfx_id, INT32 volume);
void S_StartAttackSound(const void *origin, sfxenum_t sfx_id);
void S_StartScreamSound(const void *origin, sfxenum_t sfx_id);
// Starts 3D sound with specified parameters
// origin - for object movement tracking. NULL are possible value (no movement tracking)
// source_parm - 3D source parameters (position etc.)
// cone_parm - 3D source cone parameters. NULL are possible value (default cone will be used)
// channel -
// sfx_id - sfx id
// vol - sound volume
// pitch - sound pitching value
// Returns: - sound id
INT32 HW3S_I_StartSound(const void *origin, source3D_data_t *source_parm, channel_type_t channel, sfxenum_t sfx_id, INT32 vol, INT32 pitch, INT32 sep);
void HW3S_StopSoundByID(void *origin, sfxenum_t sfx_id);
void HW3S_StopSoundByNum(sfxenum_t sfxnum);
void HW3S_StopSound(void *origin);
void HW3S_StopSounds(void);
void HW3S_BeginFrameUpdate(void);
void HW3S_EndFrameUpdate(void);
void HW3S_UpdateSources(void);
void HW3S_SetSfxVolume(INT32 volume);
// Utility functions
INT32 HW3S_SoundIsPlaying(INT32 handle);
void HW3S_SetSourcesNum(void);
INT32 HW3S_OriginPlaying(void *origin);
INT32 HW3S_IdPlaying(sfxenum_t id);
INT32 HW3S_SoundPlaying(void *origin, sfxenum_t id);
void *HW3S_GetSfx(sfxinfo_t *sfx);
void HW3S_FreeSfx(sfxinfo_t *sfx);
#else // HW3SOUND
//#define S_StartAmbientSound(i,v) S_StartSoundAtVolume(NULL, i, v)
#define S_StartAttackSound S_StartSound
#define S_StartScreamSound S_StartSound
#endif // HW3SOUND
INT32 S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source,
INT32 *vol, INT32 *sep, INT32 *pitch, sfxinfo_t *sfxinfo);
#endif // __HW3_SOUND_H__
+64 -76
View File
@@ -15,10 +15,9 @@
#include "hw_main.h"
#include "../i_system.h"
#include "../doomdef.h"
#include "../qs22j.h"
// The texture for the next polygon given to HWR_ProcessPolygon.
// Set with HWR_SetCurrentTexture.
GLMipmap_t *current_texture = NULL;
@@ -47,12 +46,12 @@ int unsortedVertexArrayAllocSize = 65536;
// Call HWR_RenderBatches to render all the collected geometry.
void HWR_StartBatching(void)
{
if (currently_batching)
if (currently_batching)
{
I_Error("Repeat call to HWR_StartBatching without HWR_RenderBatches");
I_Error("Repeat call to HWR_StartBatching without HWR_RenderBatches");
}
// init arrays if that has not been done yet
// init arrays if that has not been done yet
if (!finalVertexArray)
{
finalVertexArray = malloc(finalVertexArrayAllocSize * sizeof(FOutVector));
@@ -62,22 +61,22 @@ void HWR_StartBatching(void)
unsortedVertexArray = malloc(unsortedVertexArrayAllocSize * sizeof(FOutVector));
}
currently_batching = true;
currently_batching = true;
}
// This replaces the direct calls to GL_SetTexture in cases where batching is available.
// This replaces the direct calls to pfnSetTexture in cases where batching is available.
// The texture selection is saved for the next HWR_ProcessPolygon call.
// Doing this was easier than getting a texture pointer to HWR_ProcessPolygon.
void HWR_SetCurrentTexture(GLMipmap_t *texture)
{
if (currently_batching)
{
current_texture = texture;
}
else
{
GL_SetTexture(texture);
}
if (currently_batching)
{
current_texture = texture;
}
else
{
HWD.pfnSetTexture(texture);
}
}
// If batching is enabled, this function collects the polygon data and the chosen texture
@@ -85,13 +84,10 @@ void HWR_SetCurrentTexture(GLMipmap_t *texture)
// render the polygon immediately.
void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags, int shader_target, boolean horizonSpecial)
{
if (currently_batching)
if (currently_batching)
{
if (!pSurf)
{
I_Error("Got a null FSurfaceInfo in batching");// nulls should not come in the stuff that batching currently applies to
}
if (polygonArraySize == polygonArrayAllocSize)
{
PolygonArrayEntry* new_array;
@@ -124,7 +120,7 @@ void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPt
polygonArray[polygonArraySize].numVerts = iNumPts;
polygonArray[polygonArraySize].polyFlags = PolyFlags;
polygonArray[polygonArraySize].texture = current_texture;
polygonArray[polygonArraySize].shader = (shader_target != SHADER_NONE) ? HWR_GetShaderFromTarget(shader_target) : shader_target;
polygonArray[polygonArraySize].shader = (shader_target != -1) ? HWR_GetShaderFromTarget(shader_target) : shader_target;
polygonArray[polygonArraySize].horizonSpecial = horizonSpecial;
polygonArraySize++;
@@ -133,8 +129,8 @@ void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPt
}
else
{
GL_SetShader((shader_target != SHADER_NONE) ? HWR_GetShaderFromTarget(shader_target) : shader_target);
GL_DrawPolygon(pSurf, pOutVerts, iNumPts, PolyFlags);
HWD.pfnSetShader((shader_target != SHADER_NONE) ? HWR_GetShaderFromTarget(shader_target) : shader_target);
HWD.pfnDrawPolygon(pSurf, pOutVerts, iNumPts, PolyFlags);
}
}
@@ -144,19 +140,27 @@ static int comparePolygons(const void *p1, const void *p2)
PolygonArrayEntry *poly2 = *(PolygonArrayEntry *const *)p2;
int diff;
INT64 diff64;
UINT32 downloaded1 = 0;
UINT32 downloaded2 = 0;
int shader1 = (poly1->polyFlags & PF_NoTexture || poly1->horizonSpecial) ? -1 : poly1->shader;
int shader2 = (poly2->polyFlags & PF_NoTexture || poly2->horizonSpecial) ? -1 : poly2->shader;
int shader1 = poly1->shader;
int shader2 = poly2->shader;
// make skywalls and horizon lines first in order
if (poly1->polyFlags & PF_NoTexture || poly1->horizonSpecial)
shader1 = -1;
if (poly2->polyFlags & PF_NoTexture || poly2->horizonSpecial)
shader2 = -1;
diff = shader1 - shader2;
if (diff != 0) return diff;
// skywalls and horizon lines must retain their order for horizon lines to work
if (shader1 == -1 && shader2 == -1)
return poly1 - poly2;
diff = shader1 - shader2;
if (diff != 0) return diff;
UINT32 downloaded1 = poly1->texture ? poly1->texture->downloaded : 0; // there should be a opengl texture name here, usable for comparisons
UINT32 downloaded2 = poly2->texture ? poly2->texture->downloaded : 0;
if (poly1->texture)
downloaded1 = poly1->texture->downloaded; // there should be a opengl texture name here, usable for comparisons
if (poly2->texture)
downloaded2 = poly2->texture->downloaded;
diff64 = downloaded1 - downloaded2;
if (diff64 != 0) return diff64;
@@ -175,10 +179,6 @@ static int comparePolygons(const void *p1, const void *p2)
diff = poly1->surf.LightInfo.fade_start - poly2->surf.LightInfo.fade_start;
if (diff != 0) return diff;
diff = poly1->surf.LightInfo.fade_end - poly2->surf.LightInfo.fade_end;
if (diff != 0) return diff;
diff = poly1->surf.LightInfo.directional - poly2->surf.LightInfo.directional;
return diff;
}
@@ -189,15 +189,21 @@ static int comparePolygonsNoShaders(const void *p1, const void *p2)
int diff;
INT64 diff64;
GLMipmap_t *texture1 = (poly1->polyFlags & PF_NoTexture || poly1->horizonSpecial) ? NULL : poly1->texture;
GLMipmap_t *texture2 = (poly2->polyFlags & PF_NoTexture || poly2->horizonSpecial) ? NULL : poly2->texture;
GLMipmap_t *texture1 = poly1->texture;
GLMipmap_t *texture2 = poly2->texture;
UINT32 downloaded1 = 0;
UINT32 downloaded2 = 0;
if (poly1->polyFlags & PF_NoTexture || poly1->horizonSpecial)
texture1 = NULL;
if (poly2->polyFlags & PF_NoTexture || poly2->horizonSpecial)
texture2 = NULL;
if (texture1)
downloaded1 = texture1->downloaded; // there should be a opengl texture name here, usable for comparisons
if (texture2)
downloaded2 = texture2->downloaded;
// skywalls and horizon lines must retain their order for horizon lines to work
if (!texture1 && !texture2)
return poly1 - poly2;
UINT32 downloaded1 = texture1 ? texture1->downloaded : 0; // there should be a opengl texture name here, usable for comparisons
UINT32 downloaded2 = texture2 ? texture2->downloaded : 0;
diff64 = downloaded1 - downloaded2;
if (diff64 != 0) return diff64;
@@ -214,14 +220,14 @@ static int comparePolygonsNoShaders(const void *p1, const void *p2)
// the rendering backend to draw them.
void HWR_RenderBatches(void)
{
int finalVertexWritePos = 0;// position in finalVertexArray
int finalVertexWritePos = 0;// position in finalVertexArray
int finalIndexWritePos = 0;// position in finalVertexIndexArray
int polygonReadPos = 0;// position in polygonArraySorted
int currentShader;
int nextShader = 0;
GLMipmap_t *currentTexture = NULL;
GLMipmap_t *currentTexture;
GLMipmap_t *nextTexture = NULL;
FBITFIELD currentPolyFlags = 0;
FBITFIELD nextPolyFlags = 0;
@@ -230,18 +236,14 @@ void HWR_RenderBatches(void)
int i;
if (!currently_batching)
{
if (!currently_batching)
I_Error("HWR_RenderBatches called without starting batching");
}
nextSurfaceInfo.LightInfo.fade_end = 0;
nextSurfaceInfo.LightInfo.fade_start = 0;
nextSurfaceInfo.LightInfo.light_level = 0;
nextSurfaceInfo.LightInfo.directional = false;
currently_batching = false;// no longer collecting batches
if (!polygonArraySize)
{
ps_hw_numpolys.value.i = ps_hw_numcalls.value.i = ps_hw_numshaders.value.i
@@ -249,13 +251,11 @@ void HWR_RenderBatches(void)
= ps_hw_numcolors.value.i = 0;
return;// nothing to draw
}
// init stats vars
ps_hw_numpolys.value.i = polygonArraySize;
ps_hw_numcalls.value.i = ps_hw_numverts.value.i = 0;
ps_hw_numshaders.value.i = ps_hw_numtextures.value.i
= ps_hw_numpolyflags.value.i = ps_hw_numcolors.value.i = 1;
// init polygonArraySorted
for (i = 0; i < polygonArraySize; i++)
{
@@ -264,12 +264,11 @@ void HWR_RenderBatches(void)
// sort polygons
PS_START_TIMING(ps_hw_batchsorttime);
if (cv_glshaders.value && gl_shadersavailable)
if (cv_grshaders.value && gr_shadersavailable)
qs22j(polygonArraySorted, polygonArraySize, sizeof(PolygonArrayEntry *), comparePolygons);
else
qs22j(polygonArraySorted, polygonArraySize, sizeof(PolygonArrayEntry *), comparePolygonsNoShaders);
PS_STOP_TIMING(ps_hw_batchsorttime);
// sort order
// 1. shader
// 2. texture
@@ -288,17 +287,17 @@ void HWR_RenderBatches(void)
// set state for first batch
if (cv_glshaders.value && gl_shadersavailable)
if (cv_grshaders.value && gr_shadersavailable)
{
GL_SetShader(currentShader);
HWD.pfnSetShader(currentShader);
}
if (currentPolyFlags & PF_NoTexture)
currentTexture = NULL;
else
GL_SetTexture(currentTexture);
else
HWD.pfnSetTexture(currentTexture);
while (1) // note: remember handling notexture polyflag as having texture number 0 (also in comparePolygons)
while (1)// note: remember handling notexture polyflag as having texture number 0 (also in comparePolygons)
{
int firstIndex;
int lastIndex;
@@ -368,37 +367,31 @@ void HWR_RenderBatches(void)
nextTexture = nextEntry->texture;
nextPolyFlags = nextEntry->polyFlags;
nextSurfaceInfo = nextEntry->surf;
if (nextPolyFlags & PF_NoTexture)
nextTexture = 0;
if (currentShader != nextShader && cv_glshaders.value && gl_shadersavailable)
if (currentShader != nextShader && cv_grshaders.value && gr_shadersavailable)
{
changeState = true;
changeShader = true;
}
if (currentTexture != nextTexture)
{
changeState = true;
changeTexture = true;
}
if (currentPolyFlags != nextPolyFlags)
{
changeState = true;
changePolyFlags = true;
}
if (cv_glshaders.value && gl_shadersavailable)
if (cv_grshaders.value && gr_shadersavailable)
{
if (currentSurfaceInfo.PolyColor.rgba != nextSurfaceInfo.PolyColor.rgba ||
currentSurfaceInfo.TintColor.rgba != nextSurfaceInfo.TintColor.rgba ||
currentSurfaceInfo.FadeColor.rgba != nextSurfaceInfo.FadeColor.rgba ||
currentSurfaceInfo.LightInfo.light_level != nextSurfaceInfo.LightInfo.light_level ||
currentSurfaceInfo.LightInfo.fade_start != nextSurfaceInfo.LightInfo.fade_start ||
currentSurfaceInfo.LightInfo.fade_end != nextSurfaceInfo.LightInfo.fade_end ||
currentSurfaceInfo.LightInfo.directional != nextSurfaceInfo.LightInfo.directional)
currentSurfaceInfo.LightInfo.fade_end != nextSurfaceInfo.LightInfo.fade_end)
{
changeState = true;
changeSurfaceInfo = true;
@@ -417,7 +410,7 @@ void HWR_RenderBatches(void)
if (changeState || stopFlag)
{
// execute draw call
GL_DrawIndexedTriangles(&currentSurfaceInfo, finalVertexArray, finalIndexWritePos, currentPolyFlags, finalVertexIndexArray);
HWD.pfnDrawIndexedTriangles(&currentSurfaceInfo, finalVertexArray, finalIndexWritePos, currentPolyFlags, finalVertexIndexArray);
// update stats
ps_hw_numcalls.value.i++;
ps_hw_numverts.value.i += finalIndexWritePos;
@@ -425,35 +418,31 @@ void HWR_RenderBatches(void)
finalVertexWritePos = 0;
finalIndexWritePos = 0;
}
else
continue;
else continue;
// if we're here then either its time to stop or time to change state
if (stopFlag)
break;
if (stopFlag) break;
// change state according to change bools and next vars, update current vars and reset bools
if (changeState)
{
if (changeShader)
{
GL_SetShader(nextShader);
HWD.pfnSetShader(nextShader);
currentShader = nextShader;
changeShader = false;
ps_hw_numshaders.value.i++;
}
if (changeTexture)
{
// texture should be already ready for use from calls to GL_SetTexture during batch collection
GL_SetTexture(nextTexture);
// texture should be already ready for use from calls to SetTexture during batch collection
HWD.pfnSetTexture(nextTexture);
currentTexture = nextTexture;
changeTexture = false;
ps_hw_numtextures.value.i++;
}
if (changePolyFlags)
{
currentPolyFlags = nextPolyFlags;
@@ -461,7 +450,6 @@ void HWR_RenderBatches(void)
ps_hw_numpolyflags.value.i++;
}
if (changeSurfaceInfo)
{
currentSurfaceInfo = nextSurfaceInfo;
@@ -469,7 +457,6 @@ void HWR_RenderBatches(void)
ps_hw_numcolors.value.i++;
}
// and that should be it?
}
}
// reset the arrays (set sizes to 0)
@@ -479,4 +466,5 @@ void HWR_RenderBatches(void)
PS_STOP_TIMING(ps_hw_batchdrawtime);
}
#endif // HWRENDER
+1 -3
View File
@@ -15,9 +15,7 @@
#include "hw_defs.h"
#include "hw_data.h"
#include "hw_gl.h"
extern boolean currently_batching;
#include "hw_drv.h"
typedef struct
{
+11 -11
View File
@@ -46,7 +46,7 @@ typedef struct
// when loading the map, this is set to true if portals are found.
// if no portals are found, the portal scanning phase can be skipped while rendering, saving a bit of time.
boolean gl_maphasportals = false;
boolean gr_maphasportals = false;
// ==========================================================================
// FLOOR & CEILING CONVEX POLYS GENERATION
@@ -369,18 +369,18 @@ static poly_t *CutOutSubsecPoly(seg_t *lseg, INT32 count, poly_t *poly)
{
//x,y,dx,dy (like a divline)
line_t *line = lseg->linedef;
// portal check
if (!gl_maphasportals && line->special == 40 && lseg->side == 0)
if (!gr_maphasportals && line->special == 40 && lseg->side == 0)
{
// Find the other side!
INT32 line2 = P_FindSpecialLineFromTag(40, line->tag, -1);
if (line == &lines[line2])
line2 = P_FindSpecialLineFromTag(40, line->tag, line2);
if (line2 >= 0) // found it!
gl_maphasportals = 1;
gr_maphasportals = 1;
}
p1.x = FIXED_TO_FLOAT(lseg->side ? line->v2->x : line->v1->x);
p1.y = FIXED_TO_FLOAT(lseg->side ? line->v2->y : line->v1->y);
p2.x = FIXED_TO_FLOAT(lseg->side ? line->v1->x : line->v2->x);
@@ -523,7 +523,7 @@ static void loading_status(void)
x = BASEVIDWIDTH/2;
y = BASEVIDHEIGHT/2;
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); // Black background to match fade in effect
//V_DrawPatchFill(W_CachePatchName("SRB2BACK", PU_PATCH)); // SRB2 background, ehhh too bright.
//V_DrawPatchFill(W_CachePatchName("SRB2BACK",PU_CACHE)); // SRB2 background, ehhh too bright.
M_DrawTextBox(x-58, y-8, 13, 1);
V_DrawString(x-50, y, V_YELLOWMAP, "Loading...");
V_DrawRightAlignedString(x+50, y, V_YELLOWMAP, s);
@@ -768,7 +768,7 @@ static INT32 SolveTProblem(void)
INT32 i;
size_t l;
if (cv_glsolvetjoin.value == 0)
if (cv_grsolvetjoin.value == 0)
return 0;
CONS_Debug(DBG_RENDER, "Solving T-joins. This may take a while. Please wait...\n");
@@ -905,7 +905,7 @@ void HWR_CreatePlanePolygons(INT32 bspnum)
#endif
// reset the portal flag
gl_maphasportals = 0;
gr_maphasportals = 0;
// find min/max boundaries of map
//CONS_Debug(DBG_RENDER, "Looking for boundaries of map...\n");
@@ -923,9 +923,9 @@ void HWR_CreatePlanePolygons(INT32 bspnum)
I_Error("couldn't malloc extrasubsectors totsubsectors %s\n", sizeu1(totsubsectors));
// allocate table for back to front drawing of subsectors
/*gl_drawsubsectors = (INT16 *)malloc(sizeof (*gl_drawsubsectors) * totsubsectors);
if (!gl_drawsubsectors)
I_Error("couldn't malloc gl_drawsubsectors\n");*/
/*gr_drawsubsectors = (INT16 *)malloc(sizeof (*gr_drawsubsectors) * totsubsectors);
if (!gr_drawsubsectors)
I_Error("couldn't malloc gr_drawsubsectors\n");*/
// number of the first new subsector that might be added
addsubsector = numsubsectors;
+300 -643
View File
File diff suppressed because it is too large. Load diff
+5 -3
View File
@@ -314,6 +314,8 @@ void gld_clipper_Clear(void)
cliphead = NULL;
}
#define RMUL (1.6f/1.333333f)
angle_t gld_FrustumAngle(angle_t tiltangle)
{
double clipfov;
@@ -331,11 +333,11 @@ angle_t gld_FrustumAngle(angle_t tiltangle)
// ok, this is a gross hack that barely works...
// but at least it doesn't overestimate too much...
clipfov = atan(1 / projMatrix[0]) * 360.0f / M_PIl;
clipfov = atan(1 / projMatrix[0]) * 360 / M_PI;
floatangle = 2.0f + (45.0f + (tilt / 1.9f)) * clipfov / 90.0f;
if (floatangle >= 180.0)
return 0xffffffff;
a1 = (angle_t)xs_CRoundToInt(ANG1 * floatangle);
a1 = (angle_t)(ANG1 * (int)floatangle);
return a1;
}
@@ -456,4 +458,4 @@ boolean gld_SphereInFrustum(float x, float y, float z, float radius)
}
return true;
}
#endif
#endif
+33 -29
View File
@@ -23,58 +23,62 @@
typedef enum GLTextureFormat_e
{
GL_TEXFMT_P_8 = 0x01, /* 8-bit palette */
GL_TEXFMT_AP_88 = 0x02, /* 8-bit alpha, 8-bit palette */
GL_TEXFMT_P_8 = 0x01, /* 8-bit palette */
GL_TEXFMT_AP_88 = 0x02, /* 8-bit alpha, 8-bit palette */
GL_TEXFMT_RGBA = 0x10, /* 32 bit RGBA! */
GL_TEXFMT_RGBA = 0x10, /* 32 bit RGBA! */
GL_TEXFMT_ALPHA_8 = 0x20, /* (0..0xFF) alpha */
GL_TEXFMT_INTENSITY_8 = 0x21, /* (0..0xFF) intensity */
GL_TEXFMT_ALPHA_INTENSITY_88 = 0x22,
GL_TEXFMT_ALPHA_8 = 0x20, /* (0..0xFF) alpha */
GL_TEXFMT_INTENSITY_8 = 0x21, /* (0..0xFF) intensity */
GL_TEXFMT_ALPHA_INTENSITY_88 = 0x22,
} GLTextureFormat_t;
// Colormap structure for mipmaps.
struct GLColormap_s
{
const UINT8 *source;
UINT8 data[256];
};
typedef struct GLColormap_s GLColormap_t;
// Texture information (misleadingly named "mipmap" all over the code.)
// The *data pointer holds the address of the graphics data cached in heap memory.
// NULL if the texture is not in SRB2's heap cache.
// data holds the address of the graphics data cached in heap memory
// NULL if the texture is not in Doom heap cache.
struct GLMipmap_s
{
// for UpdateTexture
GLTextureFormat_t format;
void *data;
GLTextureFormat_t format;
void *data;
UINT32 flags;
UINT16 width, height;
UINT32 downloaded; // The GPU has this texture.
UINT32 flags;
UINT16 width, height;
UINT32 downloaded; // tex_downloaded
struct GLMipmap_s *nextcolormap;
struct GLColormap_s *colormap;
struct GLMipmap_s *nextcolormap;
const UINT8 *colormap;
};
typedef struct GLMipmap_s GLMipmap_t;
//
// Level textures, as cached for hardware rendering.
// Doom texture info, as cached for hardware rendering
//
struct GLMapTexture_s
{
GLMipmap_t mipmap;
float scaleX; //used for scaling textures on walls
float scaleX; //used for scaling textures on walls
float scaleY;
};
typedef struct GLMapTexture_s GLMapTexture_t;
// Patch information for the hardware renderer.
// a cached patch as converted to hardware format, holding the original patch_t
// header so that the existing code can retrieve ->width, ->height as usual
// This is returned by W_CachePatchNum()/W_CachePatchName(), when rendermode
// is 'render_opengl'. Else it returns the normal patch_t data.
struct GLPatch_s
{
GLMipmap_t *mipmap;
// the 4 first fields come right away from the original patch_t
INT16 width;
INT16 height;
INT16 leftoffset; // pixels to the left of origin
INT16 topoffset; // pixels below the origin
//
float max_s,max_t;
UINT16 wadnum; // the software patch lump num for when the hardware patch
UINT16 lumpnum; // was flushed, and we need to re-create it
void *rawpatch; // :^)
GLMipmap_t *mipmap;
boolean notfound; // if the texture file was not found, mark it here (used in model texture loading)
};
typedef struct GLPatch_s GLPatch_t;
+44 -75
View File
@@ -121,33 +121,44 @@ typedef struct
poly_t *planepoly; // the generated convex polygon
} extrasubsector_t;
//here lies gr_vissprite
// Kart features
#define USE_FTRANSFORM_ANGLEZ
#define USE_FTRANSFORM_MIRROR
// Vanilla features
//#define USE_MODEL_NEXTFRAME
typedef struct
{
FLOAT x,y,z; // position
FLOAT anglex, angley, anglez; // aimingangle / viewangle
FLOAT scalex, scaley, scalez;
FLOAT fovangle;
#ifdef USE_FTRANSFORM_ANGLEZ
FLOAT anglex,angley,anglez; // aimingangle / viewangle
FLOAT anglex2,anglez2; // secondaries
#else
FLOAT anglex,angley; // aimingangle / viewangle
FLOAT anglex2; // secondaries
#endif
FLOAT scalex,scaley,scalez;
FLOAT spritexscale,spriteyscale;
FLOAT fovxangle, fovyangle;
UINT8 splitscreen;
boolean flip; // screenflip
boolean roll;
boolean rollmodel;
SINT8 rollflip;
FLOAT rollangle;
UINT8 rotaxis;
FLOAT centerx, centery;
FLOAT rollx, rollz;
UINT8 fliptype;
#ifdef USE_FTRANSFORM_MIRROR
boolean mirror; // SRB2Kart: Encore Mode
boolean mirrorflip; // Encore Mode with Flipcam
#endif
boolean shearing; // 14042019
float viewaiming; // 17052019
} FTransform;
enum
{
TRANSFORM_NONE = 0,
TRANSFORM_FLIP = 1 << 0, // screenflip
TRANSFORM_MIRROR = 1 << 1, // SRB2Kart: Encore Mode
TRANSFORM_MIRRORFLIP = TRANSFORM_FLIP|TRANSFORM_MIRROR // SRB2Kart: Encore Mode with Flipcam
};
// Transformed vector, as passed to HWR API
typedef struct
{
@@ -155,41 +166,6 @@ typedef struct
FLOAT s,t;
} FOutVector;
typedef struct vbo_vertex_s
{
float x, y, z;
float u, v;
unsigned char r, g, b, a;
} gl_skyvertex_t;
typedef enum gl_skyloopmode_e
{
HWD_SKYLOOP_FAN,
HWD_SKYLOOP_STRIP
} gl_skyloopmode_t;
typedef struct
{
gl_skyloopmode_t mode;
int vertexcount;
int vertexindex;
boolean use_texture;
} gl_skyloopdef_t;
typedef struct
{
unsigned int vbo;
int rows, columns;
int loopcount;
int detail, vertex_count;
int texture, width, height;
boolean rebuild; // VBO needs to be rebuilt
gl_skyloopdef_t *loops;
gl_skyvertex_t *data;
} gl_sky_t;
// Shader targets used to render specific types of geometry.
// A shader target is resolved to an actual shader with HWR_GetShaderFromTarget.
// The shader returned may be a base shader or a custom shader.
@@ -197,6 +173,7 @@ enum
{
SHADER_NONE = -1,
SHADER_FLOOR = 0,
SHADER_SHADOW,
SHADER_WALL,
SHADER_SPRITE,
SHADER_MODEL,
@@ -227,6 +204,7 @@ enum hwdshaderstage
typedef enum hwdshaderstage hwdshaderstage_t;
// ==========================================================================
// RENDER MODES
// ==========================================================================
@@ -237,22 +215,22 @@ enum EPolyFlags
{
// the first 5 are mutually exclusive
PF_Masked = 0x00000001, // Poly is alpha scaled and 0 alpha pixels are discarded (holes in texture)
PF_Masked = 0x00000001, // Poly is alpha scaled and 0 alpha pels are discarded (holes in texture)
PF_Translucent = 0x00000002, // Poly is transparent, alpha = level of transparency
PF_Environment = 0x00000004, // Poly should be drawn environment mapped. (Hurdler: used for text drawing)
PF_Additive = 0x00000008, // Source blending factor is additive.
PF_Subtractive = 0x00000010, // Subtractive color blending
PF_ReverseSubtract = 0x00000020, // Reverse subtract, used in wall splats (decals)
PF_Multiplicative = 0x00000040, // Multiplicative color blending
PF_Fog = 0x20000000, // Fog blocks
PF_NoAlphaTest = 0x40000000, // Disables alpha testing
PF_Blending = (PF_Masked|PF_Translucent|PF_Environment|PF_Additive|PF_Subtractive|PF_ReverseSubtract|PF_Multiplicative|PF_Fog) & ~PF_NoAlphaTest,
PF_Additive = 0x00000004, // Poly is added to the frame buffer
PF_Environment = 0x00000008, // Poly should be drawn environment mapped.
// Hurdler: used for text drawing
PF_Substractive = 0x00000010, // for splat
PF_NoAlphaTest = 0x00000020, // hiden param
PF_Fog = 0x00000040, // Fog blocks
PF_Blending = (PF_Environment|PF_Additive|PF_Translucent|PF_Masked|PF_Substractive|PF_Fog)&~PF_NoAlphaTest,
// other flag bits
PF_Occlude = 0x00000100, // Updates the depth buffer
PF_NoDepthTest = 0x00000200, // Disables the depth test mode
PF_Invisible = 0x00000400, // Disables write to color buffer
PF_Decal = 0x00000800, // Enables polygon offset
PF_Occlude = 0x00000100, // Update the depth buffer
PF_NoDepthTest = 0x00000200, // Disable the depth test mode
PF_Invisible = 0x00000400, // Disable write to color buffer
PF_Decal = 0x00000800, // Enable polygon offset
PF_Modulated = 0x00001000, // Modulation (multiply output with constant RGBA)
// When set, pass the color constant into the FSurfaceInfo -> FlatColor
PF_NoTexture = 0x00002000, // Disable texture
@@ -261,8 +239,7 @@ enum EPolyFlags
PF_RemoveYWrap = 0x00010000, // Force clamp texture on Y
PF_ForceWrapX = 0x00020000, // Force repeat texture on X
PF_ForceWrapY = 0x00040000, // Forces repeat texture on Y
PF_Ripple = 0x00100000, // Water ripple effect. The current backend doesn't use it for anything.
PF_Skydecal = 0x20000000 // Enables smaller polygon offset, to be used for skywalls only
PF_Ripple = 0x00100000 // Water ripple effect. The current backend doesn't use it for anything.
// 0x20000000
// 0x40000000
// 0x80000000
@@ -295,7 +272,6 @@ struct FLightInfo
FUINT light_level;
FUINT fade_start;
FUINT fade_end;
boolean directional;
};
typedef struct FLightInfo FLightInfo;
@@ -313,13 +289,14 @@ typedef struct FSurfaceInfo FSurfaceInfo;
enum hwdsetspecialstate
{
#ifdef USE_FBO_OGL
HWD_SET_FRAMEBUFFER,
#endif
HWD_SET_SHADERS,
HWD_SET_TEXTUREFILTERMODE,
HWD_SET_TEXTUREANISOTROPICMODE,
HWD_SET_WIREFRAME,
HWD_SET_MSAA,
HWD_SET_SCREEN_TEXTURES,
@@ -327,8 +304,6 @@ enum hwdsetspecialstate
HWD_SET_PORTAL_MODE,// new portal thing
HWD_SET_STENCIL_LEVEL,
HWD_SET_TEXTURE_FORMAT,
HWD_NUMSTATE
};
typedef enum hwdsetspecialstate hwdspecialstate_t;
@@ -338,11 +313,6 @@ typedef enum hwdsetspecialstate hwdspecialstate_t;
enum hwdshaderinfo
{
HWD_SHADERINFO_LEVELTIME = 1,
HWD_SHADERINFO_LIGHT_X,
HWD_SHADERINFO_LIGHT_Y,
HWD_SHADERINFO_LIGHT_Z,
HWD_SHADERINFO_LIGHT_CONTRAST,
HWD_SHADERINFO_LIGHT_BACKLIGHT,
};
typedef enum hwdshaderinfo hwdshaderinfo_t;
@@ -376,7 +346,6 @@ enum hwdscreentexture
HWD_SCREENTEXTURE_WIPE_END, // destination image for the wipe/fade effect
HWD_SCREENTEXTURE_GENERIC1, // underwater/heat effect, intermission background
HWD_SCREENTEXTURE_GENERIC2, // palette-based colormap fade, final screen texture
HWD_SCREENTEXTURE_VHS,
NUMSCREENTEXTURES, // (generic3 is unused if palette rendering is disabled)
};
typedef enum hwdscreentexture hwdscreentexture_t;
+170 -191
View File
@@ -18,10 +18,9 @@
#include "../doomdef.h"
#ifdef HWRENDER
#include "hw_main.h"
#include "hw_glob.h"
#include "hw_gl.h"
#include "hw_drv.h"
#include "../m_misc.h" //FIL_WriteFile()
#include "../r_draw.h" //viewborderlump
@@ -62,20 +61,16 @@ static UINT8 softwaretranstogl[11] = { 0, 25, 51, 76,102,127,153,178,204,229
static UINT8 softwaretranstogl_hi[11] = { 0, 51,102,153,204,255,255,255,255,255,255};
static UINT8 softwaretranstogl_lo[11] = { 0, 12, 24, 36, 48, 60, 71, 83, 95,111,127};
static const float FLOATBASEVIDWIDTH = (float)BASEVIDWIDTH;
static const float FLOATBASEVIDHEIGHT = (float)BASEVIDHEIGHT;
//
// -----------------+
// HWR_DrawPatch : Draw a 'tile' graphic
// Notes : x,y : positions relative to the original Doom resolution
// : textes(console+score) + menus + status bar
// -----------------+
void HWR_DrawPatch(patch_t *gpatch, INT32 x, INT32 y, INT32 option)
void HWR_DrawPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option)
{
FOutVector v[4];
FBITFIELD flags;
GLPatch_t *hwrPatch;
// 3--2
// | /|
@@ -88,7 +83,6 @@ void HWR_DrawPatch(patch_t *gpatch, INT32 x, INT32 y, INT32 option)
// make patch ready in hardware cache
HWR_GetPatch(gpatch);
hwrPatch = ((GLPatch_t *)gpatch->hardware);
switch (option & V_SCALEPATCHMASK)
{
@@ -108,17 +102,17 @@ void HWR_DrawPatch(patch_t *gpatch, INT32 x, INT32 y, INT32 option)
if (option & V_NOSCALESTART)
sdupx = sdupy = 2.0f;
v[0].x = v[3].x = (x*sdupx-gpatch->leftoffset*pdupx)/vid.width - 1;
v[2].x = v[1].x = (x*sdupx+(gpatch->width - gpatch->leftoffset)*pdupx)/vid.width - 1;
v[0].y = v[1].y = 1-(y*sdupy-gpatch->topoffset*pdupy)/vid.height;
v[2].y = v[3].y = 1-(y*sdupy+(gpatch->height - gpatch->topoffset)*pdupy)/vid.height;
v[0].x = v[3].x = (x*sdupx-SHORT(gpatch->leftoffset)*pdupx)/vid.width - 1;
v[2].x = v[1].x = (x*sdupx+(SHORT(gpatch->width)-SHORT(gpatch->leftoffset))*pdupx)/vid.width - 1;
v[0].y = v[1].y = 1-(y*sdupy-SHORT(gpatch->topoffset)*pdupy)/vid.height;
v[2].y = v[3].y = 1-(y*sdupy+(SHORT(gpatch->height)-SHORT(gpatch->topoffset))*pdupy)/vid.height;
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
v[0].s = v[3].s = 0.0f;
v[2].s = v[1].s = hwrPatch->max_s;
v[2].s = v[1].s = gpatch->max_s;
v[0].t = v[1].t = 0.0f;
v[2].t = v[3].t = hwrPatch->max_t;
v[2].t = v[3].t = gpatch->max_t;
flags = PF_Translucent|PF_NoDepthTest;
@@ -128,18 +122,16 @@ void HWR_DrawPatch(patch_t *gpatch, INT32 x, INT32 y, INT32 option)
flags |= PF_ForceWrapY;
// clip it since it is used for bunny scroll in doom I
GL_DrawPolygon(NULL, v, 4, flags);
HWD.pfnDrawPolygon(NULL, v, 4, flags);
}
void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, INT32 option, const UINT8 *colormap, INT32 bflags)
void HWR_DrawStretchyFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, INT32 option, const UINT8 *colormap)
{
FOutVector v[4];
FBITFIELD flags;
float cx = FIXED_TO_FLOAT(x);
float cy = FIXED_TO_FLOAT(y);
UINT8 alphalevel = ((option & V_ALPHAMASK) >> V_ALPHASHIFT);
UINT8 blendmode = ((bflags & V_BLENDMASK) >> V_BLENDSHIFT);
GLPatch_t *hwrPatch;
// 3--2
// | /|
@@ -150,17 +142,12 @@ void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t p
if (alphalevel >= 10 && alphalevel < 13)
return;
const float fvw = (float)vid.width;
const float fvh = (float)vid.height;
// make patch ready in hardware cache
if (!colormap)
HWR_GetPatch(gpatch);
else
HWR_GetMappedPatch(gpatch, colormap);
hwrPatch = ((GLPatch_t *)gpatch->hardware);
dupx = (float)vid.dupx;
dupy = (float)vid.dupy;
@@ -191,13 +178,13 @@ void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t p
// left offset
if (option & V_FLIP)
offsetx = (float)(gpatch->width - gpatch->leftoffset) * fscalew;
offsetx = (float)(SHORT(gpatch->width) - SHORT(gpatch->leftoffset)) * fscalew;
else
offsetx = (float)(gpatch->leftoffset) * fscalew;
offsetx = (float)SHORT(gpatch->leftoffset) * fscalew;
// top offset
// TODO: make some kind of vertical version of V_FLIP, maybe by deprecating V_OFFSET in future?!?
offsety = (float)(gpatch->topoffset) * fscaleh;
offsety = (float)SHORT(gpatch->topoffset) * fscaleh;
if ((option & (V_NOSCALESTART|V_OFFSET)) == (V_NOSCALESTART|V_OFFSET)) // Multiply by dupx/dupy for crosshairs
{
@@ -225,46 +212,56 @@ void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t p
// if it's meant to cover the whole screen, black out the rest
// cx and cy are possibly *slightly* off from float maths
// This is done before here compared to software because we directly alter cx and cy to centre
if (cx >= -0.1f && cx <= 0.1f && gpatch->width == BASEVIDWIDTH && cy >= -0.1f && cy <= 0.1f && gpatch->height == BASEVIDHEIGHT)
if (cx >= -0.1f && cx <= 0.1f && SHORT(gpatch->width) == BASEVIDWIDTH && cy >= -0.1f && cy <= 0.1f && SHORT(gpatch->height) == BASEVIDHEIGHT)
{
const column_t *column = (const column_t *)((const UINT8 *)(gpatch->columns) + (gpatch->columnofs[0]));
// Need to temporarily cache the real patch to get the colour of the top left pixel
patch_t *realpatch = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC);
const column_t *column = (const column_t *)((const UINT8 *)(realpatch) + LONG((realpatch)->columnofs[0]));
if (!column->topdelta)
{
const UINT8 *source = (const UINT8 *)(column) + 3;
HWR_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0]));
}
Z_Free(realpatch);
}
// centre screen
if (fabsf(fvw - FLOATBASEVIDWIDTH * dupx) > 1.0E-36f)
if (fabsf((float)vid.width - (float)BASEVIDWIDTH * dupx) > 1.0E-36f)
{
if (option & V_SNAPTORIGHT)
cx += (fvw - (FLOATBASEVIDWIDTH * dupx));
cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx));
else if (!(option & V_SNAPTOLEFT))
cx += (fvw - (FLOATBASEVIDWIDTH * dupx))/2;
cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx))/2;
}
if (fabsf(fvh - FLOATBASEVIDHEIGHT * dupy) > 1.0E-36f)
if (fabsf((float)vid.height - (float)BASEVIDHEIGHT * dupy) > 1.0E-36f)
{
if ((option & (V_SPLITSCREEN|V_SNAPTOTOP)) == (V_SPLITSCREEN|V_SNAPTOTOP))
cy += (fvh/2 - (FLOATBASEVIDHEIGHT/2 * dupy));
cy += ((float)vid.height/2 - ((float)BASEVIDHEIGHT/2 * dupy));
else if (option & V_SNAPTOBOTTOM)
cy += (fvh - (FLOATBASEVIDHEIGHT * dupy));
cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy));
else if (!(option & V_SNAPTOTOP))
cy += (fvh - (FLOATBASEVIDHEIGHT * dupy))/2;
cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy))/2;
}
}
}
fwidth = (float)(gpatch->width) * fscalew * dupx;
fheight = (float)(gpatch->height) * fscaleh * dupy;
if (pscale != FRACUNIT)
{
fwidth = (float)SHORT(gpatch->width) * fscalew * dupx;
fheight = (float)SHORT(gpatch->height) * fscaleh * dupy;
}
else
{
fwidth = (float)SHORT(gpatch->width) * dupx;
fheight = (float)SHORT(gpatch->height) * dupy;
}
// positions of the cx, cy, are between 0 and vid.width/vid.height now, we need them to be between -1 and 1
cx = -1.0f + (cx / (fvw / 2.0f));
cy = 1.0f - (cy / (fvh / 2.0f));
cx = -1 + (cx / (vid.width/2));
cy = 1 - (cy / (vid.height/2));
// fwidth and fheight are similar
fwidth /= fvw / 2.0f;
fheight /= fvh / 2.0f;
fwidth /= vid.width / 2;
fheight /= vid.height / 2;
// set the polygon vertices to the right positions
v[0].x = v[3].x = cx;
@@ -277,54 +274,48 @@ void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t p
if (option & V_FLIP)
{
v[0].s = v[3].s = hwrPatch->max_s;
v[0].s = v[3].s = gpatch->max_s;
v[2].s = v[1].s = 0.0f;
}
else
{
v[0].s = v[3].s = 0.0f;
v[2].s = v[1].s = hwrPatch->max_s;
v[2].s = v[1].s = gpatch->max_s;
}
v[0].t = v[1].t = 0.0f;
v[2].t = v[3].t = hwrPatch->max_t;
v[2].t = v[3].t = gpatch->max_t;
// clip it since it is used for bunny scroll in doom I
if (blendmode)
flags = HWR_GetBlendModeFlag(blendmode+1)|PF_NoDepthTest;
else
flags = PF_Translucent|PF_NoDepthTest;
flags = PF_Translucent|PF_NoDepthTest;
if (option & V_WRAPX)
flags |= PF_ForceWrapX;
if (option & V_WRAPY)
flags |= PF_ForceWrapY;
// clip it since it is used for bunny scroll in doom I
if (alphalevel)
{
FSurfaceInfo Surf;
Surf.PolyColor.s.red = Surf.PolyColor.s.green = Surf.PolyColor.s.blue = 0xff;
if (alphalevel == 13) Surf.PolyColor.s.alpha = softwaretranstogl_lo[hudtrans];
else if (alphalevel == 14) Surf.PolyColor.s.alpha = softwaretranstogl[hudtrans];
else if (alphalevel == 15) Surf.PolyColor.s.alpha = softwaretranstogl_hi[hudtrans];
else Surf.PolyColor.s.alpha = softwaretranstogl[10-alphalevel];
flags |= PF_Modulated;
GL_DrawPolygon(&Surf, v, 4, flags);
HWD.pfnDrawPolygon(&Surf, v, 4, flags);
}
else
GL_DrawPolygon(NULL, v, 4, flags);
HWD.pfnDrawPolygon(NULL, v, 4, flags);
}
void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, INT32 option, fixed_t sx, fixed_t sy, fixed_t w, fixed_t h)
void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, INT32 option, fixed_t sx, fixed_t sy, fixed_t w, fixed_t h)
{
FOutVector v[4];
FBITFIELD flags;
float cx = FIXED_TO_FLOAT(x);
float cy = FIXED_TO_FLOAT(y);
UINT8 alphalevel = ((option & V_ALPHAMASK) >> V_ALPHASHIFT);
GLPatch_t *hwrPatch;
// 3--2
// | /|
@@ -335,12 +326,8 @@ void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
if (alphalevel >= 10 && alphalevel < 13)
return;
const float fvw = (float)vid.width;
const float fvh = (float)vid.height;
// make patch ready in hardware cache
HWR_GetPatch(gpatch);
hwrPatch = ((GLPatch_t *)gpatch->hardware);
dupx = (float)vid.dupx;
dupy = (float)vid.dupy;
@@ -363,8 +350,8 @@ void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
dupx = dupy = (dupx < dupy ? dupx : dupy);
fscale = FIXED_TO_FLOAT(pscale);
cy -= (float)(gpatch->topoffset) * fscale;
cx -= (float)(gpatch->leftoffset) * fscale;
cy -= (float)SHORT(gpatch->topoffset) * fscale;
cx -= (float)SHORT(gpatch->leftoffset) * fscale;
if (!(option & V_NOSCALESTART))
{
@@ -376,32 +363,34 @@ void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
// if it's meant to cover the whole screen, black out the rest
// cx and cy are possibly *slightly* off from float maths
// This is done before here compared to software because we directly alter cx and cy to centre
if (cx >= -0.1f && cx <= 0.1f && gpatch->width == BASEVIDWIDTH && cy >= -0.1f && cy <= 0.1f && gpatch->height == BASEVIDHEIGHT)
if (cx >= -0.1f && cx <= 0.1f && SHORT(gpatch->width) == BASEVIDWIDTH && cy >= -0.1f && cy <= 0.1f && SHORT(gpatch->height) == BASEVIDHEIGHT)
{
const column_t *column = (const column_t *)((const UINT8 *)(gpatch->columns) + (gpatch->columnofs[0]));
// Need to temporarily cache the real patch to get the colour of the top left pixel
patch_t *realpatch = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC);
const column_t *column = (const column_t *)((const UINT8 *)(realpatch) + LONG((realpatch)->columnofs[0]));
if (!column->topdelta)
{
const UINT8 *source = (const UINT8 *)(column) + 3;
HWR_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0]));
}
Z_Free(realpatch);
}
// centre screen
if (fabsf(fvw - FLOATBASEVIDWIDTH * dupx) > 1.0E-36f)
if (fabsf((float)vid.width - (float)BASEVIDWIDTH * dupx) > 1.0E-36f)
{
if (option & V_SNAPTORIGHT)
cx += (fvw - (FLOATBASEVIDWIDTH * dupx));
cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx));
else if (!(option & V_SNAPTOLEFT))
cx += (fvw - (FLOATBASEVIDWIDTH * dupx))/2;
cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx))/2;
}
if (fabsf(fvh - FLOATBASEVIDHEIGHT * dupy) > 1.0E-36f)
if (fabsf((float)vid.height - (float)BASEVIDHEIGHT * dupy) > 1.0E-36f)
{
if ((option & (V_SPLITSCREEN|V_SNAPTOTOP)) == (V_SPLITSCREEN|V_SNAPTOTOP))
cy += (fvh/2 - (FLOATBASEVIDHEIGHT/2 * dupy));
cy += ((float)vid.height/2 - ((float)BASEVIDHEIGHT/2 * dupy));
else if (option & V_SNAPTOBOTTOM)
cy += (fvh - (FLOATBASEVIDHEIGHT * dupy));
cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy));
else if (!(option & V_SNAPTOTOP))
cy += (fvh - (FLOATBASEVIDHEIGHT * dupy))/2;
cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy))/2;
}
}
}
@@ -415,11 +404,11 @@ void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
if (fheight > h - sy)
fheight = h - sy;
if (fwidth > gpatch->width)
fwidth = gpatch->width;
if (fwidth > SHORT(gpatch->width))
fwidth = SHORT(gpatch->width);
if (fheight > gpatch->height)
fheight = gpatch->height;
if (fheight > SHORT(gpatch->height))
fheight = SHORT(gpatch->height);
if (pscale != FRACUNIT)
{
@@ -433,12 +422,12 @@ void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
}
// positions of the cx, cy, are between 0 and vid.width/vid.height now, we need them to be between -1 and 1
cx = -1.0f + (cx / (fvw / 2.0f));
cy = 1.0f - (cy / (fvh / 2.0f));
cx = -1 + (cx / (vid.width/2));
cy = 1 - (cy / (vid.height/2));
// fwidth and fheight are similar
fwidth /= fvw / 2.0f;
fheight /= fvh / 2.0f;
fwidth /= vid.width / 2;
fheight /= vid.height / 2;
// set the polygon vertices to the right positions
v[0].x = v[3].x = cx;
@@ -449,10 +438,10 @@ void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
v[0].s = v[3].s = ((sx)/(float)(gpatch->width) )*hwrPatch->max_s;
v[2].s = v[1].s = ((w )/(float)(gpatch->width) )*hwrPatch->max_s;
v[0].t = v[1].t = ((sy)/(float)(gpatch->height))*hwrPatch->max_t;
v[2].t = v[3].t = ((h )/(float)(gpatch->height))*hwrPatch->max_t;
v[0].s = v[3].s = ((sx)/(float)SHORT(gpatch->width) )*gpatch->max_s;
v[2].s = v[1].s = ((w )/(float)SHORT(gpatch->width) )*gpatch->max_s;
v[0].t = v[1].t = ((sy)/(float)SHORT(gpatch->height))*gpatch->max_t;
v[2].t = v[3].t = ((h )/(float)SHORT(gpatch->height))*gpatch->max_t;
flags = PF_Translucent|PF_NoDepthTest;
@@ -466,17 +455,15 @@ void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
{
FSurfaceInfo Surf;
Surf.PolyColor.s.red = Surf.PolyColor.s.green = Surf.PolyColor.s.blue = 0xff;
if (alphalevel == 13) Surf.PolyColor.s.alpha = softwaretranstogl_lo[cv_translucenthud.value];
else if (alphalevel == 14) Surf.PolyColor.s.alpha = softwaretranstogl[cv_translucenthud.value];
else if (alphalevel == 15) Surf.PolyColor.s.alpha = softwaretranstogl_hi[cv_translucenthud.value];
else Surf.PolyColor.s.alpha = softwaretranstogl[10-alphalevel];
flags |= PF_Modulated;
GL_DrawPolygon(&Surf, v, 4, flags);
HWD.pfnDrawPolygon(&Surf, v, 4, flags);
}
else
GL_DrawPolygon(NULL, v, 4, flags);
HWD.pfnDrawPolygon(NULL, v, 4, flags);
}
// ==========================================================================
@@ -552,7 +539,7 @@ void HWR_DrawFlatFill (INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatlumpnum
// BTW, I see we put 0 for PFs, and If I'm right, that
// means we take the previous PFs as default
// how can we be sure they are ok?
GL_DrawPolygon(NULL, v, 4, PF_NoDepthTest); //PF_Translucent);
HWD.pfnDrawPolygon(NULL, v, 4, PF_NoDepthTest); //PF_Translucent);
}
@@ -565,33 +552,33 @@ void HWR_DrawFlatFill (INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatlumpnum
// 0--1
void HWR_FadeScreenMenuBack(UINT16 color, UINT8 strength)
{
FOutVector v[4];
FSurfaceInfo Surf;
FOutVector v[4];
FSurfaceInfo Surf;
FBITFIELD poly_flags = PF_NoTexture|PF_Modulated|PF_NoDepthTest;
v[0].x = v[3].x = -1.0f;
v[2].x = v[1].x = 1.0f;
v[0].y = v[1].y = -1.0f;
v[2].y = v[3].y = 1.0f;
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
v[0].x = v[3].x = -1.0f;
v[2].x = v[1].x = 1.0f;
v[0].y = v[1].y = -1.0f;
v[2].y = v[3].y = 1.0f;
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
v[0].s = v[3].s = 0.0f;
v[2].s = v[1].s = 1.0f;
v[0].t = v[1].t = 1.0f;
v[2].t = v[3].t = 0.0f;
v[0].s = v[3].s = 0.0f;
v[2].s = v[1].s = 1.0f;
v[0].t = v[1].t = 1.0f;
v[2].t = v[3].t = 0.0f;
if (color & 0xFF00) // Do COLORMAP fade.
{
if (HWR_ShouldUsePaletteRendering() && cv_glscreentextures.value)
if (color & 0xFF00) // Do COLORMAP fade.
{
if (HWR_ShouldUsePaletteRendering() && cv_grscreentextures.value)
{
const hwdscreentexture_t scr_tex = HWD_SCREENTEXTURE_GENERIC2;
Surf.LightTableId = HWR_GetLightTableID(NULL);
Surf.LightInfo.light_level = strength;
GL_MakeScreenTexture(scr_tex);
GL_SetShader(HWR_GetShaderFromTarget(SHADER_UI_COLORMAP_FADE));
GL_DrawScreenTexture(scr_tex, &Surf, PF_ColorMapped|PF_NoDepthTest);
GL_UnSetShader();
HWD.pfnMakeScreenTexture(scr_tex);
HWD.pfnSetShader(HWR_GetShaderFromTarget(SHADER_UI_COLORMAP_FADE));
HWD.pfnDrawScreenTexture(scr_tex, &Surf, PF_ColorMapped|PF_NoDepthTest);
HWD.pfnUnSetShader();
return;
}
@@ -601,21 +588,21 @@ void HWR_FadeScreenMenuBack(UINT16 color, UINT8 strength)
Surf.PolyColor.s.alpha = (strength*8);
poly_flags |= PF_Translucent;
}
}
else // Do TRANSMAP** fade.
{
}
else // Do TRANSMAP** fade.
{
RGBA_t *palette = HWR_GetTexturePalette();
Surf.PolyColor.rgba = palette[color&0xFF].rgba;
if (HWR_ShouldUsePaletteRendering())
if (HWR_ShouldUsePaletteRendering())
Surf.PolyColor.s.alpha = softwaretranstogl[strength];
else
Surf.PolyColor.s.alpha = (UINT8)(strength*25.5f);
poly_flags |= PF_Translucent;
}
}
GL_DrawPolygon(&Surf, v, 4, poly_flags);
HWD.pfnDrawPolygon(&Surf, v, 4, poly_flags);
}
// Draw the console background with translucency support
@@ -642,7 +629,7 @@ void HWR_DrawConsoleBack(UINT32 color, INT32 height)
Surf.PolyColor.rgba = UINT2RGBA(color);
Surf.PolyColor.s.alpha = 0x80;
GL_DrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest);
HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest);
}
@@ -663,19 +650,19 @@ void HWR_DrawViewBorder(INT32 clearlines)
INT32 top, side;
INT32 baseviewwidth, baseviewheight;
INT32 basewindowx, basewindowy;
patch_t *patch;
GLPatch_t *patch;
// if (gl_viewwidth == vid.width)
// if (gr_viewwidth == vid.width)
// return;
if (!clearlines)
clearlines = BASEVIDHEIGHT; // refresh all
// calc view size based on original game resolution
baseviewwidth = FixedInt(FixedDiv(FLOAT_TO_FIXED(gl_viewwidth), vid.fdupx)); //(cv_viewsize.value * BASEVIDWIDTH/10)&~7;
baseviewheight = FixedInt(FixedDiv(FLOAT_TO_FIXED(gl_viewheight), vid.fdupy));
top = FixedInt(FixedDiv(FLOAT_TO_FIXED(gl_baseviewwindowy), vid.fdupy));
side = FixedInt(FixedDiv(FLOAT_TO_FIXED(gl_baseviewwindowx), vid.fdupx));
baseviewwidth = FixedInt(FixedDiv(FLOAT_TO_FIXED(gr_viewwidth), vid.fdupx)); //(cv_viewsize.value * BASEVIDWIDTH/10)&~7;
baseviewheight = FixedInt(FixedDiv(FLOAT_TO_FIXED(gr_viewheight), vid.fdupy));
top = FixedInt(FixedDiv(FLOAT_TO_FIXED(gr_baseviewwindowy), vid.fdupy));
side = FixedInt(FixedDiv(FLOAT_TO_FIXED(gr_baseviewwindowx), vid.fdupx));
// top
HWR_DrawFlatFill(0, 0,
@@ -712,7 +699,7 @@ void HWR_DrawViewBorder(INT32 clearlines)
// top edge
if (clearlines > basewindowy - 8)
{
patch = W_CachePatchNum(viewborderlump[BRDR_T], PU_PATCH);
patch = W_CachePatchNum(viewborderlump[BRDR_T], PU_CACHE);
for (x = 0; x < baseviewwidth; x += 8)
HWR_DrawPatch(patch, basewindowx + x, basewindowy - 8,
0);
@@ -721,7 +708,7 @@ void HWR_DrawViewBorder(INT32 clearlines)
// bottom edge
if (clearlines > basewindowy + baseviewheight)
{
patch = W_CachePatchNum(viewborderlump[BRDR_B], PU_PATCH);
patch = W_CachePatchNum(viewborderlump[BRDR_B], PU_CACHE);
for (x = 0; x < baseviewwidth; x += 8)
HWR_DrawPatch(patch, basewindowx + x,
basewindowy + baseviewheight, 0);
@@ -730,7 +717,7 @@ void HWR_DrawViewBorder(INT32 clearlines)
// left edge
if (clearlines > basewindowy)
{
patch = W_CachePatchNum(viewborderlump[BRDR_L], PU_PATCH);
patch = W_CachePatchNum(viewborderlump[BRDR_L], PU_CACHE);
for (y = 0; y < baseviewheight && basewindowy + y < clearlines;
y += 8)
{
@@ -742,7 +729,7 @@ void HWR_DrawViewBorder(INT32 clearlines)
// right edge
if (clearlines > basewindowy)
{
patch = W_CachePatchNum(viewborderlump[BRDR_R], PU_PATCH);
patch = W_CachePatchNum(viewborderlump[BRDR_R], PU_CACHE);
for (y = 0; y < baseviewheight && basewindowy+y < clearlines;
y += 8)
{
@@ -754,22 +741,22 @@ void HWR_DrawViewBorder(INT32 clearlines)
// Draw beveled corners.
if (clearlines > basewindowy - 8)
HWR_DrawPatch(W_CachePatchNum(viewborderlump[BRDR_TL],
PU_PATCH),
PU_CACHE),
basewindowx - 8, basewindowy - 8, 0);
if (clearlines > basewindowy - 8)
HWR_DrawPatch(W_CachePatchNum(viewborderlump[BRDR_TR],
PU_PATCH),
PU_CACHE),
basewindowx + baseviewwidth, basewindowy - 8, 0);
if (clearlines > basewindowy+baseviewheight)
HWR_DrawPatch(W_CachePatchNum(viewborderlump[BRDR_BL],
PU_PATCH),
PU_CACHE),
basewindowx - 8, basewindowy + baseviewheight, 0);
if (clearlines > basewindowy + baseviewheight)
HWR_DrawPatch(W_CachePatchNum(viewborderlump[BRDR_BR],
PU_PATCH),
PU_CACHE),
basewindowx + baseviewwidth,
basewindowy + baseviewheight, 0);
}
@@ -789,16 +776,16 @@ void HWR_drawAMline(const fline_t *fl, INT32 color)
F2DCoord v1, v2;
RGBA_t color_rgba;
RGBA_t *palette = HWR_GetTexturePalette();
color_rgba = palette[color&0xFF];
v1.x = ((float)fl->a.x-(vid.width/2.0f))*(2.0f/vid.width);
v1.y = ((float)fl->a.y-(vid.height/2.0f))*(2.0f/vid.height);
v2.x = ((float)fl->b.x-(vid.width/2.0f))*(2.0f/vid.width);
v2.y = ((float)fl->b.y-(vid.height/2.0f))*(2.0f/vid.height);
GL_Draw2DLine(&v1, &v2, color_rgba);
HWD.pfnDraw2DLine(&v1, &v2, color_rgba);
}
// -----------------+
@@ -823,9 +810,6 @@ void HWR_DrawDiag(INT32 x, INT32 y, INT32 wh, INT32 color)
fy = (float)y;
fw = fh = (float)wh;
const float fvw = (float)vid.width;
const float fvh = (float)vid.height;
if (!(color & V_NOSCALESTART))
{
float dupx = (float)vid.dupx, dupy = (float)vid.dupy;
@@ -835,20 +819,20 @@ void HWR_DrawDiag(INT32 x, INT32 y, INT32 wh, INT32 color)
fw *= dupx;
fh *= dupy;
if (fabsf(fvw - (FLOATBASEVIDWIDTH * dupx)) > 1.0E-36f)
if (fabsf((float)vid.width - ((float)BASEVIDWIDTH * dupx)) > 1.0E-36f)
{
if (color & V_SNAPTORIGHT)
fx += (fvw - (FLOATBASEVIDWIDTH * dupx));
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx));
else if (!(color & V_SNAPTOLEFT))
fx += (fvw - (FLOATBASEVIDWIDTH * dupx)) / 2;
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 2;
}
if (fabsf(fvh - (FLOATBASEVIDHEIGHT * dupy)) > 1.0E-36f)
if (fabsf((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) > 1.0E-36f)
{
// same thing here
if (color & V_SNAPTOBOTTOM)
fy += (fvh - (FLOATBASEVIDHEIGHT * dupy));
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy));
else if (!(color & V_SNAPTOTOP))
fy += (fvh - (FLOATBASEVIDHEIGHT * dupy)) / 2;
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 2;
}
}
@@ -869,16 +853,16 @@ void HWR_DrawDiag(INT32 x, INT32 y, INT32 wh, INT32 color)
return;
if (fx + fw > vid.width)
{
fwait = fw - (fvw- fx);
fw = fvw - fx;
fwait = fw - ((float)vid.width - fx);
fw = (float)vid.width - fx;
}
if (fy + fh > vid.height)
fh = fvh - fy;
fh = (float)vid.height - fy;
fx = -1.0f + fx / (fvw / 2.0f);
fy = 1.0f - fy / (fvh / 2.0f);
fw = fw / (fvw / 2.0f);
fh = fh / (fvh / 2.0f);
fx = -1 + fx / (vid.width / 2);
fy = 1 - fy / (vid.height / 2);
fw = fw / (vid.width / 2);
fh = fh / (vid.height / 2);
v[0].x = v[3].x = fx;
v[2].x = v[1].x = fx + fw;
@@ -895,7 +879,7 @@ void HWR_DrawDiag(INT32 x, INT32 y, INT32 wh, INT32 color)
Surf.PolyColor = palette[color&0xFF];
GL_DrawPolygon(&Surf, v, 4,
HWD.pfnDrawPolygon(&Surf, v, 4,
PF_Modulated|PF_NoTexture|PF_NoDepthTest);
}
@@ -922,9 +906,6 @@ void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, UINT32 color, INT32
fw = (float)w;
fh = (float)h;
const float fvw = (float)vid.width;
const float fvh = (float)vid.height;
if (!(options & V_NOSCALESTART))
{
float dupx = (float)vid.dupx, dupy = (float)vid.dupy;
@@ -937,7 +918,7 @@ void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, UINT32 color, INT32
clearColour.green = (float)rgbaColour.s.green / 255;
clearColour.blue = (float)rgbaColour.s.blue / 255;
clearColour.alpha = 1;
GL_ClearBuffer(true, false, false, &clearColour);
HWD.pfnClearBuffer(true, false, false, &clearColour);
return;
}
@@ -946,25 +927,25 @@ void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, UINT32 color, INT32
fw *= dupx;
fh *= dupy;
if (fabsf(fvw - (FLOATBASEVIDWIDTH * dupx)) > 1.0E-36f)
if (fabsf((float)vid.width - ((float)BASEVIDWIDTH * dupx)) > 1.0E-36f)
{
if (options & V_SNAPTORIGHT)
fx += (fvw - (FLOATBASEVIDWIDTH * dupx));
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx));
else if (!(options & V_SNAPTOLEFT))
fx += (fvw - (FLOATBASEVIDWIDTH * dupx)) / 2;
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 2;
}
if (fabsf(fvh - (FLOATBASEVIDHEIGHT * dupy)) > 1.0E-36f)
if (fabsf((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) > 1.0E-36f)
{
// same thing here
if (options & V_SNAPTOBOTTOM)
fy += (fvh - (FLOATBASEVIDHEIGHT * dupy));
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy));
else if (!(options & V_SNAPTOTOP))
fy += (fvh - (FLOATBASEVIDHEIGHT * dupy)) / 2;
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 2;
}
if (options & V_SPLITSCREEN)
fy += (FLOATBASEVIDHEIGHT * dupy)/2;
fy += ((float)BASEVIDHEIGHT * dupy)/2;
if (options & V_HORZSCREEN)
fx += (FLOATBASEVIDWIDTH * dupx)/2;
fx += ((float)BASEVIDWIDTH * dupx)/2;
}
@@ -984,14 +965,14 @@ void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, UINT32 color, INT32
if (fw <= 0 || fh <= 0)
return;
if (fx + fw > vid.width)
fw = fvw - fx;
fw = (float)vid.width - fx;
if (fy + fh > vid.height)
fh = fvh - fy;
fh = (float)vid.height - fy;
fx = -1.0f + fx / (fvw / 2.0f);
fy = 1.0f - fy / (fvh / 2.0f);
fw = fw / (fvw / 2.0f);
fh = fh / (fvh / 2.0f);
fx = -1 + fx / (vid.width / 2);
fy = 1 - fy / (vid.height / 2);
fw = fw / (vid.width / 2);
fh = fh / (vid.height / 2);
v[0].x = v[3].x = fx;
v[2].x = v[1].x = fx + fw;
@@ -1008,7 +989,7 @@ void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, UINT32 color, INT32
Surf.PolyColor.rgba = UINT2RGBA(color);
Surf.PolyColor.s.alpha = 0x80;
GL_DrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest);
HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest);
}
// -----------------+
@@ -1036,9 +1017,6 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color)
fw = (float)w;
fh = (float)h;
const float fvw = (float)vid.width;
const float fvh = (float)vid.height;
if (!(color & V_NOSCALESTART))
{
float dupx = (float)vid.dupx, dupy = (float)vid.dupy;
@@ -1051,7 +1029,7 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color)
clearColour.green = (float)rgbaColour.s.green / 255;
clearColour.blue = (float)rgbaColour.s.blue / 255;
clearColour.alpha = 1;
GL_ClearBuffer(true, false, false, &clearColour);
HWD.pfnClearBuffer(true, false, false, &clearColour);
return;
}
@@ -1060,25 +1038,26 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color)
fw *= dupx;
fh *= dupy;
if (fabsf(fvw - FLOATBASEVIDWIDTH * dupx) > 1.0E-36f)
if (fabsf((float)vid.width - (float)BASEVIDWIDTH * dupx) > 1.0E-36f)
{
if (color & V_SNAPTORIGHT)
fx += (fvw - (FLOATBASEVIDWIDTH * dupx));
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx));
else if (!(color & V_SNAPTOLEFT))
fx += (fvw - (FLOATBASEVIDWIDTH * dupx)) / 2;
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 2;
}
if (fabsf(fvh - FLOATBASEVIDHEIGHT * dupy) > 1.0E-36f)
if (fabsf((float)vid.height - (float)BASEVIDHEIGHT * dupy) > 1.0E-36f)
{
// same thing here
if (color & V_SNAPTOBOTTOM)
fy += (fvh - (FLOATBASEVIDHEIGHT * dupy));
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy));
else if (!(color & V_SNAPTOTOP))
fy += (fvh - (FLOATBASEVIDHEIGHT * dupy)) / 2;
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 2;
}
if (color & V_SPLITSCREEN)
fy += (FLOATBASEVIDHEIGHT * dupy)/2;
fy += ((float)BASEVIDHEIGHT * dupy)/2;
if (color & V_HORZSCREEN)
fx += (FLOATBASEVIDWIDTH * dupx)/2;
fx += ((float)BASEVIDWIDTH * dupx)/2;
}
if (fx >= vid.width || fy >= vid.height)
@@ -1097,14 +1076,14 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color)
if (fw <= 0 || fh <= 0)
return;
if (fx + fw > vid.width)
fw = fvw - fx;
fw = (float)vid.width - fx;
if (fy + fh > vid.height)
fh = fvh - fy;
fh = (float)vid.height - fy;
fx = -1.0f + fx / (fvw / 2.0f);
fy = 1.0f - fy / (fvh / 2.0f);
fw = fw / (fvw / 2.0f);
fh = fh / (fvh / 2.0f);
fx = -1 + fx / (vid.width / 2);
fy = 1 - fy / (vid.height / 2);
fw = fw / (vid.width / 2);
fh = fh / (vid.height / 2);
v[0].x = v[3].x = fx;
v[2].x = v[1].x = fx + fw;
@@ -1128,7 +1107,7 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color)
else Surf.PolyColor.s.alpha = softwaretranstogl[10-alphalevel];
}
GL_DrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest);
HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest);
}
#ifdef HAVE_PNG
@@ -1147,7 +1126,7 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color)
#define _FILE_OFFSET_BITS 0
#endif
#include "png.h"
#include "png.h"
#ifdef PNG_WRITE_SUPPORTED
#define USE_PNG // PNG is only used if write is supported (see ../m_misc.c)
#endif
@@ -1212,7 +1191,7 @@ UINT8 *HWR_GetScreenshot(void)
return NULL;
// returns 24bit 888 RGB
GL_ReadScreenTexture(HWD_SCREENTEXTURE_GENERIC2, (void *)buf);
HWD.pfnReadScreenTexture(HWD_SCREENTEXTURE_GENERIC2, (void *)buf);
return buf;
}
@@ -1228,7 +1207,7 @@ boolean HWR_Screenshot(const char *pathname)
}
// returns 24bit 888 RGB
GL_ReadScreenTexture(HWD_SCREENTEXTURE_GENERIC2, (void *)buf);
HWD.pfnReadScreenTexture(HWD_SCREENTEXTURE_GENERIC2, (void *)buf);
#ifdef USE_PNG
ret = M_SavePNG(pathname, buf, vid.width, vid.height, NULL);
+142
View File
@@ -0,0 +1,142 @@
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2019 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file
/// \brief imports/exports for the GPU hardware low-level interface API
#ifndef __HWR_DRV_H__
#define __HWR_DRV_H__
// this must be here 19991024 by Kin
#include "../screen.h"
#include "hw_data.h"
#include "hw_defs.h"
#include "hw_md2.h"
#include "hw_dll.h"
#include "../doomdef.h"
// ==========================================================================
// STANDARD DLL EXPORTS
// ==========================================================================
EXPORT boolean HWRAPI(Init) (void);
EXPORT void HWRAPI(SetupGLInfo) (void);
EXPORT void HWRAPI(SetTexturePalette) (RGBA_t *ppal);
EXPORT void HWRAPI(FinishUpdate) (INT32 waitvbl);
EXPORT void HWRAPI(Draw2DLine) (F2DCoord *v1, F2DCoord *v2, RGBA_t Color);
EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags);
EXPORT void HWRAPI(DrawIndexedTriangles) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags, unsigned int *IndexArray);
EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags);
EXPORT void HWRAPI(ClearBuffer) (FBOOLEAN ColorMask, FBOOLEAN DepthMask, FBOOLEAN StencilMask, FRGBAFloat *ClearColor);
EXPORT void HWRAPI(SetTexture) (GLMipmap_t *TexInfo);
EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *TexInfo);
EXPORT void HWRAPI(DeleteTexture) (GLMipmap_t *TexInfo);
EXPORT void HWRAPI(ReadScreenTexture) (int tex, UINT16 *dst_data);
EXPORT void HWRAPI(GClipRect) (INT32 minx, INT32 miny, INT32 maxx, INT32 maxy, float nearclip, float farclip);
EXPORT void HWRAPI(ClearMipMapCache) (void);
//Hurdler: added for backward compatibility
EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value);
//Hurdler: added for new development
EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, float duration, float tics, INT32 nextFrameIndex, FTransform *pos, float hscale, float vscale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface);
EXPORT void HWRAPI(CreateModelVBOs) (model_t *model);
EXPORT void HWRAPI(SetTransform) (FTransform *stransform);
EXPORT INT32 HWRAPI(GetTextureUsed) (void);
EXPORT void HWRAPI(RenderSkyDome) (INT32 tex, INT32 texture_width, INT32 texture_height, FTransform transform);
EXPORT void HWRAPI(FlushScreenTextures) (void);
EXPORT void HWRAPI(DoScreenWipe) (int wipeStart, int wipeEnd);
EXPORT void HWRAPI(DrawScreenTexture) (int tex, FSurfaceInfo *surf, FBITFIELD polyflags);
EXPORT void HWRAPI(MakeScreenTexture) (int tex);
EXPORT void HWRAPI(DrawScreenFinalTexture) (int tex, INT32 width, INT32 height);
EXPORT void HWRAPI(RenderVhsEffect) (fixed_t upbary, fixed_t downbary, UINT8 updistort, UINT8 downdistort, UINT8 barsize);
#define SCREENVERTS 10
EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]);
// jimita
EXPORT boolean HWRAPI(InitShaders) (void);
EXPORT void HWRAPI(LoadShader) (int slot, char *code, hwdshaderstage_t stage);
EXPORT boolean HWRAPI(CompileShader) (int slot);
EXPORT void HWRAPI(SetShader) (int slot);
EXPORT void HWRAPI(UnSetShader) (void);
EXPORT void HWRAPI(SetShaderInfo) (hwdshaderinfo_t info, INT32 value);
EXPORT void HWRAPI(SetPaletteLookup)(UINT8 *lut);
EXPORT UINT32 HWRAPI(CreateLightTable)(RGBA_t *hw_lighttable);
EXPORT void HWRAPI(ClearLightTables)(void);
EXPORT void HWRAPI(SetScreenPalette)(RGBA_t *palette);
// ==========================================================================
// HWR DRIVER OBJECT, FOR CLIENT PROGRAM
// ==========================================================================
#if !defined (_CREATE_DLL_)
struct hwdriver_s
{
Init pfnInit;
SetupGLInfo pfnSetupGLInfo;
SetTexturePalette pfnSetTexturePalette;
FinishUpdate pfnFinishUpdate;
Draw2DLine pfnDraw2DLine;
DrawPolygon pfnDrawPolygon;
DrawIndexedTriangles pfnDrawIndexedTriangles;
SetBlend pfnSetBlend;
ClearBuffer pfnClearBuffer;
SetTexture pfnSetTexture;
UpdateTexture pfnUpdateTexture;
DeleteTexture pfnDeleteTexture;
ReadScreenTexture pfnReadScreenTexture;
GClipRect pfnGClipRect;
ClearMipMapCache pfnClearMipMapCache;
SetSpecialState pfnSetSpecialState;
DrawModel pfnDrawModel;
CreateModelVBOs pfnCreateModelVBOs;
SetTransform pfnSetTransform;
GetTextureUsed pfnGetTextureUsed;
PostImgRedraw pfnPostImgRedraw;
FlushScreenTextures pfnFlushScreenTextures;
DoScreenWipe pfnDoScreenWipe;
DrawScreenTexture pfnDrawScreenTexture;
MakeScreenTexture pfnMakeScreenTexture;
RenderVhsEffect pfnRenderVhsEffect;
DrawScreenFinalTexture pfnDrawScreenFinalTexture;
RenderSkyDome pfnRenderSkyDome;
InitShaders pfnInitShaders;
LoadShader pfnLoadShader;
CompileShader pfnCompileShader;
SetShader pfnSetShader;
UnSetShader pfnUnSetShader;
SetShaderInfo pfnSetShaderInfo;
SetPaletteLookup pfnSetPaletteLookup;
CreateLightTable pfnCreateLightTable;
ClearLightTables pfnClearLightTables;
SetScreenPalette pfnSetScreenPalette;
};
extern struct hwdriver_s hwdriver;
#define HWD hwdriver
#endif //not defined _CREATE_DLL_
#endif //__HWR_DRV_H__
-79
View File
@@ -1,79 +0,0 @@
// SONIC ROBO BLAST 2 Kart
//-----------------------------------------------------------------------------
// Copyright (C) 2020 by Jaime "Lactozilla" Passos.
// Copyright (C) 2020 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file hw_gl.h
/// \brief OpenGL low-level interface API
#ifndef __HWR_GL_H__
#define __HWR_GL_H__
#include "../screen.h"
#include "hw_data.h"
#include "hw_defs.h"
#include "hw_md2.h"
#define SCREENVERTS 10
boolean GL_Init(void);
void SetupGLInfo(void);
void GL_SetSpecialState(hwdspecialstate_t IdState, INT32 Value);
void GL_SetTransform(FTransform *stransform);
void GL_SetBlend(FBITFIELD PolyFlags);
void GL_SetPalette(RGBA_t *palette);
void GL_ClearBuffer(FBOOLEAN ColorMask, FBOOLEAN DepthMask, FBOOLEAN StencilMask, FRGBAFloat * ClearColor);
void GL_DrawPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags);
void GL_DrawIndexedTriangles(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags, unsigned int *IndexArray);
void GL_Draw2DLine(F2DCoord *v1, F2DCoord *v2, RGBA_t Color);
void GL_DrawModelEx(model_t *model, INT32 frameIndex, float duration, float tics, INT32 nextFrameIndex, FTransform *pos, float hscale, float vscale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface);
#define GL_DrawModel(model, frameIndex, duration, tics, nextFrameIndex, pos, hscale, vscale, flipped, hflipped, Surface) GL_DrawModelEx(model, frameIndex, duration, tics, nextFrameIndex, pos, hscale, vscale, flipped, hflipped, Surface)
void GL_RenderSkyDome(gl_sky_t *sky);
void GL_UpdateTexture(GLMipmap_t *pTexInfo);
void GL_SetTexture(GLMipmap_t *pTexInfo);
void GL_DeleteTexture(GLMipmap_t *pTexInfo);
void GL_Flush(void);
#define GL_ClearMipMapCache GL_Flush
INT32 GL_GetTextureUsed(void);
void GL_CreateModelVBOs(model_t *model);
void GL_ReadScreenTexture(int tex, UINT16 *dst_data);
void GL_GClipRect(INT32 minx, INT32 miny, INT32 maxx, INT32 maxy, float nearclip, float farclip);
void GL_MakeScreenTexture(int tex);
void GL_FlushScreenTextures(void);
void GL_DrawScreenTexture(int tex, FSurfaceInfo *surf, FBITFIELD polyflags);
void GL_DoScreenWipe(int wipeStart, int wipeEnd);
void GL_RenderVhsEffect(fixed_t upbary, fixed_t downbary, UINT8 updistort, UINT8 downdistort, UINT8 barsize);
void GL_DrawScreenFinalTexture(int tex, INT32 width, INT32 height, boolean useshader);
void GL_PostImgRedraw(float points[SCREENVERTS][SCREENVERTS][2]);
boolean GL_InitShaders(void);
void GL_LoadShader(int slot, char *code, hwdshaderstage_t stage);
boolean GL_CompileShader(int slot);
void GL_SetShader(int slot);
void GL_UnSetShader(void);
void GL_SetShaderInfo(hwdshaderinfo_t info, INT32 value);
void GL_SetPaletteLookup(UINT8 *lut);
UINT32 GL_CreateLightTable(RGBA_t *hw_lighttable);
void GL_ClearLightTables(void);
void GL_SetScreenPalette(RGBA_t *palette);
#endif // __HWR_GL_H__
+23 -29
View File
@@ -23,7 +23,7 @@
// needed for sprite rendering
// equivalent of the software renderer's vissprites
typedef struct gl_vissprite_s
typedef struct gr_vissprite_s
{
float x1, x2;
float z1, z2;
@@ -32,7 +32,7 @@ typedef struct gl_vissprite_s
float scale;
float spritexscale, spriteyscale;
float spritexoffset, spriteyoffset;
patch_t *gpatch;
GLPatch_t *gpatch;
boolean flip;
UINT8 translucency; //alpha level 0-255
mobj_t *mobj;
@@ -41,9 +41,7 @@ typedef struct gl_vissprite_s
//Hurdler: 25/04/2000: now support colormap in hardware mode
UINT8 *colormap;
INT32 dispoffset; // copy of info->dispoffset, affects ordering but not drawing
} gl_vissprite_t;
void HWR_ObjectLightLevelPost(gl_vissprite_t *spr, const sector_t *sector, INT32 *lightlevel, boolean model);
} gr_vissprite_t;
// --------
// hw_bsp.c
@@ -51,43 +49,31 @@ void HWR_ObjectLightLevelPost(gl_vissprite_t *spr, const sector_t *sector, INT32
extern extrasubsector_t *extrasubsectors;
extern size_t addsubsector;
void HWR_FreeExtraSubsectors(void);
// --------
// hw_cache.c
// --------
void HWR_InitMapTextures(void);
void HWR_LoadMapTextures(size_t pnumtextures);
void HWR_FreeMapTextures(void);
void HWR_InitTextureCache(void);
void HWR_FreeTextureCache(void);
void HWR_FreeMipmapCache(void);
void HWR_FreeExtraSubsectors(void);
patch_t *HWR_GetCachedGLPatchPwad(UINT16 wad, UINT16 lump);
patch_t *HWR_GetCachedGLPatch(lumpnum_t lumpnum);
void HWR_GetPatch(patch_t *gpatch);
void HWR_GetMappedPatch(patch_t *gpatch, const UINT8 *colormap);
void HWR_MakePatch(const patch_t *patch, GLPatch_t *glPatch, GLMipmap_t *glMipmap, boolean makebitmap);
void HWR_GetFadeMask(lumpnum_t fademasklumpnum);
void HWR_PrecacheLevel(void);
GLMapTexture_t *HWR_GetTexture(INT32 tex, boolean noencore);
void HWR_GetFlat(lumpnum_t flatlumpnum, boolean noencoremap);
// ^ some flats must NOT be remapped to encore, since we remap them as we cache them for ease, adding a toggle here seems wise.
void HWR_FreeTexture(patch_t *patch);
void HWR_FreeTextureData(patch_t *patch);
void HWR_FreeTextureColormaps(patch_t *patch);
void HWR_ClearAllTextures(void);
void HWR_FreeColormapCache(void);
GLMapTexture_t *HWR_GetTexture(INT32 tex, boolean noencore);
void HWR_GetPatch(GLPatch_t *gpatch);
void HWR_GetMappedPatch(GLPatch_t *gpatch, const UINT8 *colormap);
void HWR_MakePatch(patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipmap, boolean makebitmap);
void HWR_UnlockCachedPatch(GLPatch_t *gpatch);
RGBA_t *HWR_GetTexturePalette(void);
void HWR_SetPalette(RGBA_t *palette);
void HWR_SetMapPalette(void);
UINT32 HWR_CreateLightTable(UINT8 *lighttable);
UINT32 HWR_GetLightTableID(extracolormap_t *colormap);
void HWR_ClearLightTables(void);
GLPatch_t *HWR_GetCachedGLPatchPwad(UINT16 wad, UINT16 lump);
GLPatch_t *HWR_GetCachedGLPatch(lumpnum_t lumpnum);
void HWR_GetFadeMask(lumpnum_t fademasklumpnum);
// --------
// hw_draw.c
@@ -95,6 +81,14 @@ void HWR_ClearLightTables(void);
extern INT32 patchformat;
extern INT32 textureformat;
// --------
// hw_main.c // originally hw_drawnodes.c from HWPortal branch
// --------
void HWR_AddTransparentWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, INT32 texnum, boolean noencore, FBITFIELD blend, boolean fogwall, INT32 lightlevel, extracolormap_t *wallcolormap);
void HWR_AddTransparentFloor(lumpnum_t lumpnum, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, extracolormap_t *planecolormap);
void HWR_AddTransparentPolyobjectFloor(lumpnum_t lumpnum, polyobj_t *polysector, boolean isceiling, fixed_t fixedheight,
INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, extracolormap_t *planecolormap);
// --------
// hw_shaders.c
// --------
+1898 -2058
View File
File diff suppressed because it is too large. Load diff
+72 -126
View File
@@ -20,17 +20,14 @@
#ifndef __HWR_MAIN_H__
#define __HWR_MAIN_H__
#include "hw_gl.h"
#include "hw_glob.h"
#include "hw_data.h"
#include "hw_defs.h"
#include "hw_portal.h"
#include "../am_map.h"
#include "../d_player.h"
#include "../r_defs.h"
#include "../m_perfstats.h"
#include "../v_video.h"
#define GLENCORE
@@ -38,32 +35,15 @@
void HWR_Startup(void);
void HWR_Shutdown(void);
extern float gl_viewwidth, gl_viewheight, gl_baseviewwindowx, gl_baseviewwindowy;
extern float gr_viewwidth, gr_viewheight, gr_baseviewwindowx, gr_baseviewwindowy;
extern float gl_basewindowcenterx, gl_basewindowcentery;
extern float gr_basewindowcenterx, gr_basewindowcentery;
extern unsigned msaa;
extern boolean a2c;
extern FTransform atransform;
extern float gl_viewsin, gl_viewcos;
extern boolean gl_drawing_stencil;
extern seg_t *gl_curline;
extern side_t *gl_sidedef;
extern line_t *gl_linedef;
extern sector_t *gl_frontsector;
extern sector_t *gl_backsector;
enum
{
HWR_STENCIL_NORMAL,
HWR_STENCIL_BEGIN,
HWR_STENCIL_REVERSE,
HWR_STENCIL_DEPTH,
HWR_STENCIL_SKY
};
extern float gr_viewsin, gr_viewcos;
// Performance stats
extern ps_metric_t ps_hw_nodesorttime;
@@ -82,12 +62,12 @@ extern ps_metric_t ps_hw_numcolors;
extern ps_metric_t ps_hw_batchsorttime;
extern ps_metric_t ps_hw_batchdrawtime;
extern boolean gl_shadersavailable;
extern boolean gr_shadersavailable;
// hw_draw.c
void HWR_DrawPatch(patch_t *gpatch, INT32 x, INT32 y, INT32 option);
void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, INT32 option, const UINT8 *colormap, INT32 bflags);
void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, INT32 option, fixed_t sx, fixed_t sy, fixed_t w, fixed_t h);
void HWR_DrawPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option);
void HWR_DrawStretchyFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, INT32 option, const UINT8 *colormap);
void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, INT32 option, fixed_t sx, fixed_t sy, fixed_t w, fixed_t h);
void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color);
void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, UINT32 color, INT32 options); // Lat: separate flags from color since color needs to be an uint to work right.
void HWR_DrawDiag(INT32 x, INT32 y, INT32 wh, INT32 color);
@@ -101,131 +81,97 @@ UINT8 *HWR_GetScreenshot(void);
boolean HWR_Screenshot(const char *lbmname);
// hw_main.c
void HWR_RenderFrame(INT32 viewnumber, player_t *player, boolean skybox);
void HWR_RenderPlayerView(INT32 viewnumber, player_t *player);
void HWR_SetViewSize(void);
void HWR_AddCommands(void);
void HWR_RenderPlayerView(void);
void HWR_RenderViewpoint(gl_portal_t *rootportal, const float fpov, player_t *player, int stencil_level, boolean allow_portals);
void HWR_ClearSkyDome(void);
void HWR_BuildSkyDome(void);
void HWR_SetTransform(float fpov);
void HWR_SetTransform(float fpov, player_t *player);
void HWR_ClearClipper(void);
void HWR_SetStencilState(int state, int level);
boolean HWR_UseShader(void);
boolean HWR_ShouldUsePaletteRendering(void);
boolean HWR_PalRenderFlashpal(void);
void HWR_TogglePaletteRendering(void);
// My original intention was to split hw_main.c
// into files like hw_bsp.c, hw_sprites.c...
// hw_main.c: Lighting and fog
void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *colormap, const boolean directional);
void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *colormap);
UINT8 HWR_FogBlockAlpha(INT32 light, extracolormap_t *colormap); // Let's see if this can work
UINT8 HWR_GetTranstableAlpha(INT32 transtablenum);
FBITFIELD HWR_GetBlendModeFlag(INT32 ast);
FBITFIELD HWR_SurfaceBlend(INT32 style, INT32 transtablenum, FSurfaceInfo *pSurf);
FBITFIELD HWR_TranstableToAlpha(INT32 transtablenum, FSurfaceInfo *pSurf);
// Get amount of memory used by gpu textures in bytes;
FUNCINLINE static ATTRINLINE INT32 HWR_GetTextureUsed(void)
{
return GL_GetTextureUsed();
}
// Get amount of memory used by gpu textures in bytes
INT32 HWR_GetTextureUsed(void);
// hw_main.c: Post-rendering
void HWR_DoPostProcessor(player_t *player);
void HWR_StartScreenWipe(void);
void HWR_EndScreenWipe(void);
void HWR_DrawIntermissionBG(void);
void HWR_DoWipe(UINT8 wipenum, UINT8 scrnnum);
void HWR_RenderVhsEffect(fixed_t upbary, fixed_t downbary, UINT8 updistort, UINT8 downdistort, UINT8 barsize);
void HWR_MakeScreenFinalTexture(void);
void HWR_DrawScreenFinalTexture(INT32 width, INT32 height);
FUNCINLINE static ATTRINLINE void HWR_StartScreenWipe(void)
{
GL_MakeScreenTexture(HWD_SCREENTEXTURE_WIPE_START);
}
// hw_main.c: Planes
//void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, FBITFIELD PolyFlags, INT32 lightlevel, lumpnum_t lumpnum, sector_t *FOFsector, UINT8 alpha, extracolormap_t *planecolormap);
void HWR_AddTransparentFloor(lumpnum_t lumpnum, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, extracolormap_t *planecolormap);
FUNCINLINE static ATTRINLINE void HWR_EndScreenWipe(void)
{
GL_MakeScreenTexture(HWD_SCREENTEXTURE_WIPE_END);
}
FUNCINLINE static ATTRINLINE void HWR_DrawIntermissionBG(void)
{
GL_DrawScreenTexture(HWD_SCREENTEXTURE_GENERIC1, NULL, 0);
}
FUNCINLINE static ATTRINLINE void HWR_RenderVhsEffect(fixed_t upbary, fixed_t downbary, UINT8 updistort, UINT8 downdistort, UINT8 barsize)
{
GL_RenderVhsEffect(upbary, downbary, updistort, downdistort, barsize);
}
FUNCINLINE static ATTRINLINE void HWR_MakeScreenFinalTexture(void)
{
GL_MakeScreenTexture(HWD_SCREENTEXTURE_GENERIC2);
}
FUNCINLINE static ATTRINLINE void HWR_DrawScreenFinalTexture(INT32 width, INT32 height, boolean useshader)
{
GL_DrawScreenFinalTexture(HWD_SCREENTEXTURE_GENERIC2, width, height, useshader);
}
void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, FBITFIELD blendmode, UINT8 lightlevel, lumpnum_t lumpnum, sector_t *FOFsector, UINT8 alpha, extracolormap_t *planecolormap);
void HWR_AddTransparentPolyobjectFloor(lumpnum_t lumpnum, polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, extracolormap_t *planecolormap);
// hw_main.c: Segs
void HWR_ProcessSeg(void); // Sort of like GLWall::Process in GZDoom
void HWR_RenderWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blend, boolean fogwall, INT32 lightlevel, extracolormap_t *wallcolormap);
void HWR_ProjectWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blendmode, INT32 lightlevel, extracolormap_t *wallcolormap);
void HWR_AddTransparentWall(FOutVector *wallVerts, FSurfaceInfo * pSurf, INT32 texnum, boolean noencore, FBITFIELD blend, boolean fogwall, INT32 lightlevel, extracolormap_t *wallcolormap);
// moved HWR_SplitWall to hw_main.c
void HWR_DrawSkyWall(FOutVector *wallVerts, FSurfaceInfo *Surf);
void HWR_DrawSkyBackground(float fpov);
// hw_bsp.c
void HWR_CreatePlanePolygons(INT32 bspnum);
extern boolean gl_maphasportals;
extern boolean gr_maphasportals;
// hw_cache.c
void HWR_LoadTextures(size_t pnumtextures);
RGBA_t *HWR_GetTexturePalette(void);
void HWR_SetShaderState(void);
// Console variables
extern CV_PossibleValue_t glanisotropicmode_cons_t[];
extern consvar_t cv_gltexturedepth;
extern consvar_t cv_glscreentextures;
extern consvar_t cv_grshaders;
#ifdef USE_FBO_OGL
extern consvar_t cv_glframebuffer;
extern consvar_t cv_grframebuffer;
#endif
extern consvar_t cv_grshearing;
extern consvar_t cv_grfov;
extern consvar_t cv_grmdls;
extern consvar_t cv_grfog;
extern consvar_t cv_grfogdensity;
extern consvar_t cv_grfiltermode;
extern consvar_t cv_granisotropicmode;
extern consvar_t cv_grcorrecttricks;
extern consvar_t cv_grfovchange;
extern consvar_t cv_grsolvetjoin;
extern consvar_t cv_grspritebillboarding;
extern consvar_t cv_grfakecontrast;
extern consvar_t cv_grslopecontrast;
extern consvar_t cv_grhorizonlines;
extern consvar_t cv_grfallbackplayermodel;
extern consvar_t cv_grbatching;
extern consvar_t cv_grrenderdistance;
extern consvar_t cv_grpaletterendering;
extern consvar_t cv_grpalettedepth;
extern consvar_t cv_grflashpal;
extern consvar_t cv_lightdither;
extern consvar_t cv_grscreentextures;
extern consvar_t cv_grportals;
extern consvar_t cv_nostencil;
extern consvar_t cv_secbright;
extern consvar_t cv_glmdls;
extern consvar_t cv_glfallbackplayermodel;
extern consvar_t cv_glspritebillboarding;
extern consvar_t cv_glshearing;
extern consvar_t cv_glfakecontrast;
extern consvar_t cv_glslopecontrast;
extern consvar_t cv_glshaders;
extern consvar_t cv_gllightdither;
extern consvar_t cv_glsecbright;
extern consvar_t cv_glfiltermode;
extern consvar_t cv_glanisotropicmode;
extern consvar_t cv_glsolvetjoin;
extern consvar_t cv_glbatching;
extern consvar_t cv_glwireframe;
extern consvar_t cv_glrenderdistance;
extern consvar_t cv_glhorizonlines;
extern consvar_t cv_glportals;
extern consvar_t cv_glpaletterendering;
extern consvar_t cv_glpalettedepth;
extern consvar_t cv_glflashpal;
FUNCINLINE static ATTRINLINE boolean HWR_UseShader(void)
{
return (cv_glshaders.value && gl_shadersavailable);
}
FUNCINLINE static ATTRINLINE boolean HWR_ShouldUsePaletteRendering(void)
{
return (cv_glpaletterendering.value && (pLocalPalette != NULL) && HWR_UseShader());
}
FUNCINLINE static ATTRINLINE boolean HWR_PalRenderFlashpal(void)
{
return (cv_glflashpal.value && HWR_ShouldUsePaletteRendering());
}
extern CV_PossibleValue_t granisotropicmode_cons_t[];
#endif
+232 -237
View File
@@ -25,14 +25,12 @@
#include "../doomstat.h"
#ifdef HWRENDER
#include "hw_gl.h"
#include "hw_drv.h"
#include "hw_md2.h"
#include "../d_main.h"
#include "../r_bsp.h"
#include "../r_fps.h"
#include "../r_main.h"
#include "../p_setup.h"
#include "../m_misc.h"
#include "../w_wad.h"
#include "../z_zone.h"
@@ -45,8 +43,8 @@
#include "hw_main.h"
#include "../v_video.h"
#ifdef HAVE_PNG
#ifndef _MSC_VER
#ifndef _LARGEFILE64_SOURCE
#define _LARGEFILE64_SOURCE
@@ -149,7 +147,7 @@ static void PNG_warn(png_structp PNG, png_const_charp pngtext)
CONS_Debug(DBG_RENDER, "libpng warning at %p: %s", PNG, pngtext);
}
static GLTextureFormat_t PNG_Load(const char *filename, int *w, int *h, GLPatch_t *glpatch)
static GLTextureFormat_t PNG_Load(const char *filename, int *w, int *h, GLPatch_t *grpatch)
{
png_structp png_ptr;
png_infop png_info_ptr;
@@ -203,7 +201,7 @@ static GLTextureFormat_t PNG_Load(const char *filename, int *w, int *h, GLPatch_
//CONS_Debug(DBG_RENDER, "libpng load error on %s\n", filename);
png_destroy_read_struct(&png_ptr, &png_info_ptr, NULL);
fclose(png_FILE);
Z_Free(glpatch->mipmap->data);
Z_Free(grpatch->mipmap->data);
return 0;
}
#ifdef USE_FAR_KEYWORD
@@ -244,7 +242,7 @@ static GLTextureFormat_t PNG_Load(const char *filename, int *w, int *h, GLPatch_
{
png_uint_32 i, pitch = png_get_rowbytes(png_ptr, png_info_ptr);
png_bytep PNG_image = Z_Malloc(pitch*height, PU_HWRMODELTEXTURE, &glpatch->mipmap->data);
png_bytep PNG_image = Z_Malloc(pitch*height, PU_HWRCACHE, &grpatch->mipmap->data);
png_bytepp row_pointers = png_malloc(png_ptr, height * sizeof (png_bytep));
for (i = 0; i < height; i++)
row_pointers[i] = PNG_image + i*pitch;
@@ -284,7 +282,7 @@ typedef struct
} PcxHeader;
static GLTextureFormat_t PCX_Load(const char *filename, int *w, int *h,
GLPatch_t *glpatch)
GLPatch_t *grpatch)
{
PcxHeader header;
#define PALSIZE 768
@@ -324,7 +322,7 @@ static GLTextureFormat_t PCX_Load(const char *filename, int *w, int *h,
pw = *w = header.xmax - header.xmin + 1;
ph = *h = header.ymax - header.ymin + 1;
image = Z_Malloc(pw*ph*4, PU_HWRMODELTEXTURE, &glpatch->mipmap->data);
image = Z_Malloc(pw*ph*4, PU_HWRCACHE, &grpatch->mipmap->data);
if (fread(palette, sizeof (UINT8), PALSIZE, file) != PALSIZE)
{
@@ -366,56 +364,51 @@ static GLTextureFormat_t PCX_Load(const char *filename, int *w, int *h,
// -----------------+
static void md2_loadTexture(md2_t *model)
{
patch_t *patch;
GLPatch_t *glPatch = NULL;
GLPatch_t *grpatch;
const char *filename = model->filename;
if (model->glpatch)
if (model->grpatch)
{
patch = model->glpatch;
glPatch = (GLPatch_t *)(patch->hardware);
if (glPatch)
Z_Free(glPatch->mipmap->data);
grpatch = model->grpatch;
Z_Free(grpatch->mipmap->data);
}
else
model->glpatch = patch = Patch_Create(NULL, 0, NULL);
{
grpatch = Z_Calloc(sizeof *grpatch, PU_HWRPATCHINFO,
&(model->grpatch));
grpatch->mipmap = Z_Calloc(sizeof (GLMipmap_t), PU_HWRPATCHINFO, NULL);
}
if (!patch->hardware)
Patch_AllocateHardwarePatch(patch);
if (glPatch == NULL)
glPatch = (GLPatch_t *)(patch->hardware);
if (!glPatch->mipmap->downloaded && !glPatch->mipmap->data)
if (!grpatch->mipmap->downloaded && !grpatch->mipmap->data)
{
int w = 0, h = 0;
#ifdef HAVE_PNG
glPatch->mipmap->format = PNG_Load(filename, &w, &h, glPatch);
if (glPatch->mipmap->format == 0)
grpatch->mipmap->format = PNG_Load(filename, &w, &h, grpatch);
if (grpatch->mipmap->format == 0)
#endif
glPatch->mipmap->format = PCX_Load(filename, &w, &h, glPatch);
if (glPatch->mipmap->format == 0)
grpatch->mipmap->format = PCX_Load(filename, &w, &h, grpatch);
if (grpatch->mipmap->format == 0)
{
model->notexturefile = true; // mark it so its not searched for again repeatedly
grpatch->notfound = true;// mark it so its not searched for again repeatedly
return;
}
glPatch->mipmap->downloaded = 0;
glPatch->mipmap->flags = 0;
patch->width = (INT16)w;
patch->height = (INT16)h;
glPatch->mipmap->width = (UINT16)w;
glPatch->mipmap->height = (UINT16)h;
grpatch->mipmap->downloaded = 0;
grpatch->mipmap->flags = 0;
grpatch->width = (INT16)w;
grpatch->height = (INT16)h;
grpatch->mipmap->width = (UINT16)w;
grpatch->mipmap->height = (UINT16)h;
// for palette rendering, color cube is applied in post-processing instead of here
if (!HWR_ShouldUsePaletteRendering())
{
UINT32 size;
RGBA_t *image;
// Lactozilla: Apply colour cube
image = glPatch->mipmap->data;
image = grpatch->mipmap->data;
size = w*h;
while (size--)
{
@@ -424,8 +417,8 @@ static void md2_loadTexture(md2_t *model)
}
}
}
GL_SetTexture(glPatch->mipmap);
HWR_UnlockCachedPatch(glPatch);
HWD.pfnSetTexture(grpatch->mipmap);
HWR_UnlockCachedPatch(grpatch);
}
// -----------------+
@@ -433,56 +426,49 @@ static void md2_loadTexture(md2_t *model)
// -----------------+
static void md2_loadBlendTexture(md2_t *model)
{
patch_t *patch;
GLPatch_t *glPatch = NULL;
GLPatch_t *grpatch;
char *filename = Z_Malloc(strlen(model->filename)+7, PU_STATIC, NULL);
strcpy(filename, model->filename);
FIL_ForceExtension(filename, "_blend.png");
if (model->blendglpatch)
if (model->blendgrpatch)
{
patch = model->blendglpatch;
glPatch = (GLPatch_t *)(patch->hardware);
if (glPatch)
Z_Free(glPatch->mipmap->data);
grpatch = model->blendgrpatch;
Z_Free(grpatch->mipmap->data);
}
else
model->blendglpatch = patch = Patch_Create(NULL, 0, NULL);
{
grpatch = Z_Calloc(sizeof *grpatch, PU_HWRPATCHINFO,
&(model->blendgrpatch));
grpatch->mipmap = Z_Calloc(sizeof (GLMipmap_t), PU_HWRPATCHINFO, NULL);
}
if (!patch->hardware)
Patch_AllocateHardwarePatch(patch);
if (glPatch == NULL)
glPatch = (GLPatch_t *)(patch->hardware);
if (!glPatch->mipmap->downloaded && !glPatch->mipmap->data)
if (!grpatch->mipmap->downloaded && !grpatch->mipmap->data)
{
int w = 0, h = 0;
#ifdef HAVE_PNG
glPatch->mipmap->format = PNG_Load(filename, &w, &h, glPatch);
if (glPatch->mipmap->format == 0)
grpatch->mipmap->format = PNG_Load(filename, &w, &h, grpatch);
if (grpatch->mipmap->format == 0)
#endif
glPatch->mipmap->format = PCX_Load(filename, &w, &h, glPatch);
if (glPatch->mipmap->format == 0)
grpatch->mipmap->format = PCX_Load(filename, &w, &h, grpatch);
if (grpatch->mipmap->format == 0)
{
model->noblendfile = true; // mark it so its not searched for again repeatedly
grpatch->notfound = true;// mark it so its not searched for again repeatedly
Z_Free(filename);
return;
}
glPatch->mipmap->downloaded = 0;
glPatch->mipmap->flags = 0;
grpatch->mipmap->downloaded = 0;
grpatch->mipmap->flags = 0;
patch->width = (INT16)w;
patch->height = (INT16)h;
glPatch->mipmap->width = (UINT16)w;
glPatch->mipmap->height = (UINT16)h;
grpatch->width = (INT16)w;
grpatch->height = (INT16)h;
grpatch->mipmap->width = (UINT16)w;
grpatch->mipmap->height = (UINT16)h;
}
GL_SetTexture(glPatch->mipmap); // We do need to do this so that it can be cleared and knows to recreate it when necessary
HWR_UnlockCachedPatch(glPatch);
HWD.pfnSetTexture(grpatch->mipmap); // We do need to do this so that it can be cleared and knows to recreate it when necessary
HWR_UnlockCachedPatch(grpatch);
Z_Free(filename);
}
@@ -503,10 +489,8 @@ void HWR_InitMD2(void)
{
md2_playermodels[s].scale = -1.0f;
md2_playermodels[s].model = NULL;
md2_playermodels[s].glpatch = NULL;
md2_playermodels[s].grpatch = NULL;
md2_playermodels[s].skin = -1;
md2_playermodels[s].notexturefile = false;
md2_playermodels[s].noblendfile = false;
md2_playermodels[s].notfound = true;
md2_playermodels[s].error = false;
}
@@ -514,10 +498,8 @@ void HWR_InitMD2(void)
{
md2_localplayermodels[s].scale = -1.0f;
md2_localplayermodels[s].model = NULL;
md2_localplayermodels[s].glpatch = NULL;
md2_localplayermodels[s].grpatch = NULL;
md2_localplayermodels[s].skin = -1;
md2_localplayermodels[s].notexturefile = false;
md2_localplayermodels[s].noblendfile = false;
md2_localplayermodels[s].notfound = true;
md2_localplayermodels[s].error = false;
}
@@ -525,10 +507,8 @@ void HWR_InitMD2(void)
{
md2_models[i].scale = -1.0f;
md2_models[i].model = NULL;
md2_models[i].glpatch = NULL;
md2_models[i].grpatch = NULL;
md2_models[i].skin = -1;
md2_models[s].notexturefile = false;
md2_models[s].noblendfile = false;
md2_models[i].notfound = true;
md2_models[i].error = false;
}
@@ -549,10 +529,21 @@ void HWR_InitMD2(void)
}
while (fscanf(f, "%19s %31s %f %f", name, filename, &scale, &offset) == 4)
{
/*if (stricmp(name, "PLAY") == 0)
{
CONS_Printf("MD2 for sprite PLAY detected in mdls.dat, use a player skin instead!\n");
continue;
}*/
// 8/1/19: Allow PLAY to load for default MD2.
for (i = 0; i < NUMSPRITES; i++)
{
if (stricmp(name, sprnames[i]) == 0)
{
//if (stricmp(name, "PLAY") == 0)
//continue;
//CONS_Debug(DBG_RENDER, " Found: %s %s %f %f\n", name, filename, scale, offset);
md2_models[i].scale = scale;
md2_models[i].offset = offset;
md2_models[i].notfound = false;
@@ -565,6 +556,7 @@ void HWR_InitMD2(void)
{
if (stricmp(name, skins[s].name) == 0)
{
//CONS_Printf(" Found: %s %s %f %f\n", name, filename, scale, offset);
md2_playermodels[s].skin = s;
md2_playermodels[s].scale = scale;
md2_playermodels[s].offset = offset;
@@ -613,7 +605,7 @@ void HWR_AddPlayerMD2(int skin, boolean local) // For MD2's that were added afte
// Check for any MD2s that match the names of player skins!
while (fscanf(f, "%19s %31s %f %f", name, filename, &scale, &offset) == 4)
{
if (stricmp(name, K_GetSkinArray(local)[skin].name) == 0)
if (stricmp(name, ( (local) ? localskins : skins )[skin].name) == 0)
{
md2s[skin].skin = skin;
md2s[skin].scale = scale;
@@ -688,10 +680,8 @@ spritemd2found:
#define SETBRIGHTNESS(brightness,r,g,b) \
brightness = (UINT8)(((1063*(UINT32)(r))/5000) + ((3576*(UINT32)(g))/5000) + ((361*(UINT32)(b))/5000))
static void HWR_CreateBlendedTexture(patch_t *gpatch, patch_t *blendgpatch, GLMipmap_t *glMipmap, INT32 skinnum, skincolors_t color)
static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, GLMipmap_t *grmip, INT32 skinnum, skincolors_t color)
{
GLPatch_t *hwrPatch = gpatch->hardware;
GLPatch_t *hwrBlendPatch = blendgpatch->hardware;
UINT16 w = gpatch->width, h = gpatch->height;
UINT32 size = w*h;
RGBA_t *image, *blendimage, *cur, blendcolor;
@@ -706,28 +696,28 @@ static void HWR_CreateBlendedTexture(patch_t *gpatch, patch_t *blendgpatch, GLMi
memset(translation, 0, sizeof(translation));
memset(cutoff, 0, sizeof(cutoff));
if (glMipmap->width == 0)
if (grmip->width == 0)
{
glMipmap->width = gpatch->width;
glMipmap->height = gpatch->height;
grmip->width = gpatch->width;
grmip->height = gpatch->height;
// no wrap around, no chroma key
glMipmap->flags = 0;
grmip->flags = 0;
// setup the texture info
glMipmap->format = GL_TEXFMT_RGBA;
grmip->format = GL_TEXFMT_RGBA;
}
if (glMipmap->data)
if (grmip->data)
{
Z_Free(glMipmap->data);
glMipmap->data = NULL;
Z_Free(grmip->data);
grmip->data = NULL;
}
cur = Z_Malloc(size*4, PU_HWRMODELTEXTURE, &glMipmap->data);
cur = Z_Malloc(size*4, PU_HWRCACHE, &grmip->data);
memset(cur, 0x00, size*4);
image = hwrPatch->mipmap->data;
blendimage = hwrBlendPatch->mipmap->data;
image = gpatch->mipmap->data;
blendimage = blendgpatch->mipmap->data;
// TC_METALSONIC includes an actual skincolor translation, on top of its flashing.
if (skinnum == TC_METALSONIC)
@@ -804,10 +794,11 @@ static void HWR_CreateBlendedTexture(patch_t *gpatch, patch_t *blendgpatch, GLMi
}
}
}
colorbrightnesses[translen] = colorbrightnesses[translen-1];
}
if (translen > 0)
colorbrightnesses[translen] = colorbrightnesses[translen-1];
while (size--)
{
if (skinnum == TC_BOSS)
@@ -1050,40 +1041,29 @@ skippixel:
#undef SETBRIGHTNESS
static void HWR_GetBlendedTexture(patch_t *patch, patch_t *blendgpatch, INT32 skinnum, const UINT8 *colormap, skincolors_t color)
static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, INT32 skinnum, const UINT8 *colormap, skincolors_t color)
{
// mostly copied from HWR_GetMappedPatch, hence the similarities and comment
GLPatch_t *glPatch = patch->hardware;
GLMipmap_t *glMipmap, *newMipmap;
GLMipmap_t *grmip, *newmip;
if (blendgpatch == NULL || colormap == colormaps || colormap == NULL)
if (colormap == colormaps || colormap == NULL)
{
// Don't do any blending
GL_SetTexture(glPatch->mipmap);
HWD.pfnSetTexture(gpatch->mipmap);
return;
}
// search for the Mipmap
// search for the mimmap
// skip the first (no colormap translated)
for (glMipmap = glPatch->mipmap; glMipmap->nextcolormap; )
for (grmip = gpatch->mipmap; grmip->nextcolormap; )
{
glMipmap = glMipmap->nextcolormap;
if (glMipmap->colormap && glMipmap->colormap->source == colormap)
grmip = grmip->nextcolormap;
if (grmip->colormap == colormap)
{
if (glMipmap->downloaded && glMipmap->data)
if (grmip->downloaded && grmip->data)
{
if (memcmp(glMipmap->colormap->data, colormap, 256 * sizeof(UINT8)))
{
M_Memcpy(glMipmap->colormap->data, colormap, 256 * sizeof(UINT8));
HWR_CreateBlendedTexture(patch, blendgpatch, glMipmap, skinnum, color);
GL_UpdateTexture(glMipmap);
}
else
GL_SetTexture(glMipmap); // found the colormap, set it to the correct texture
Z_ChangeTag(glMipmap->data, PU_HWRMODELTEXTURE_UNLOCKED);
HWD.pfnSetTexture(grmip); // found the colormap, set it to the correct texture
Z_ChangeTag(grmip->data, PU_HWRCACHE_UNLOCKED);
return;
}
}
@@ -1096,28 +1076,26 @@ static void HWR_GetBlendedTexture(patch_t *patch, patch_t *blendgpatch, INT32 sk
// (it have a liste of mipmap)
// this malloc is cleared in HWR_FreeTextureCache
// (...) unfortunately z_malloc fragment alot the memory :(so malloc is better
newMipmap = calloc(1, sizeof (*newMipmap));
if (newMipmap == NULL)
I_Error("%s: Out of memory", "HWR_GetBlendedTexture");
glMipmap->nextcolormap = newMipmap;
newmip = calloc(1, sizeof (*newmip));
if (newmip == NULL)
I_Error("%s: Out of memory", "HWR_GetMappedPatch");
grmip->nextcolormap = newmip;
newmip->colormap = colormap;
newMipmap->colormap = Z_Calloc(sizeof(*newMipmap->colormap), PU_HWRPATCHCOLMIPMAP, NULL);
newMipmap->colormap->source = colormap;
M_Memcpy(newMipmap->colormap->data, colormap, 256 * sizeof(UINT8));
HWR_CreateBlendedTexture(gpatch, blendgpatch, newmip, skinnum, color);
HWR_CreateBlendedTexture(patch, blendgpatch, newMipmap, skinnum, color);
GL_SetTexture(newMipmap);
Z_ChangeTag(newMipmap->data, PU_HWRMODELTEXTURE_UNLOCKED);
HWD.pfnSetTexture(newmip);
Z_ChangeTag(newmip->data, PU_HWRCACHE_UNLOCKED);
}
// -----------------+
// HWR_DrawMD2 : Draw MD2
// :
// Returns :
// -----------------+
void HWR_DrawMD2(gl_vissprite_t *spr)
void HWR_DrawMD2(gr_vissprite_t *spr)
{
md2_t *md2;
@@ -1127,7 +1105,7 @@ void HWR_DrawMD2(gl_vissprite_t *spr)
FTransform p;
FSurfaceInfo Surf;
if (!cv_glmdls.value)
if (!cv_grmdls.value)
return;
if (spr->precip)
@@ -1141,7 +1119,7 @@ void HWR_DrawMD2(gl_vissprite_t *spr)
{
sector_t *sector = spr->mobj->subsector->sector;
extracolormap_t *colormap = sector->extra_colormap;
INT32 lightlevel = 255;
UINT8 lightlevel = 255;
if (sector->numlights)
{
@@ -1164,9 +1142,7 @@ void HWR_DrawMD2(gl_vissprite_t *spr)
colormap = sector->extra_colormap;
}
HWR_ObjectLightLevelPost(spr, sector, &lightlevel, true);
HWR_Lighting(&Surf, lightlevel, colormap, P_SectorUsesDirectionalLighting(sector) && !(spr->mobj->frame & FF_FULLBRIGHT));
HWR_Lighting(&Surf, lightlevel, colormap);
}
else
{
@@ -1175,8 +1151,7 @@ void HWR_DrawMD2(gl_vissprite_t *spr)
// Look at HWR_ProjectSprite for more
{
patch_t *gpatch, *blendgpatch;
GLPatch_t *hwrPatch = NULL, *hwrBlendPatch = NULL;
GLPatch_t *gpatch;
INT32 durs = spr->mobj->state->tics;
INT32 tics = spr->mobj->tics;
//mdlframe_t *next = NULL;
@@ -1185,9 +1160,11 @@ void HWR_DrawMD2(gl_vissprite_t *spr)
spritedef_t *sprdef;
spriteframe_t *sprframe;
spriteinfo_t *sprinfo;
INT32 rollfactor = 0;
angle_t ang;
interpmobjstate_t interp;
if (R_UsingFrameInterpolation() && !paused && (!cv_maxinterpdist.value || R_QuickCamDist(spr->mobj->x, spr->mobj->y) < cv_maxinterpdist.value))
if (R_UsingFrameInterpolation() && !paused && (!cv_grmaxinterpdist.value || R_QuickCamDist(spr->mobj->x, spr->mobj->y) < cv_grmaxinterpdist.value))
{
R_InterpolateMobjState(spr->mobj, rendertimefrac, &interp);
}
@@ -1202,34 +1179,16 @@ void HWR_DrawMD2(gl_vissprite_t *spr)
//if (tics > durs)
//durs = tics;
INT32 blendmode;
if (spr->mobj->frame & FF_BLENDMASK)
blendmode = ((spr->mobj->frame & FF_BLENDMASK) >> FF_BLENDSHIFT) + 1;
else
blendmode = spr->mobj->blendmode;
blendmode = min(AST_MODULATE, blendmode);
if (spr->mobj->flags2 & MF2_SHADOW)
{
Surf.PolyColor.s.alpha = 0x40;
Surf.PolyFlags = HWR_GetBlendModeFlag(blendmode);
}
else if (spr->mobj->frame & FF_TRANSMASK)
{
HWR_TranstableToAlpha((spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &Surf);
Surf.PolyFlags = HWR_SurfaceBlend(blendmode, (spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &Surf);
}
else
{
// this hack is dumb, but the blendmodes refuse to work otherwise
Surf.PolyColor.s.alpha = (blendmode == AST_TRANSLUCENT) ? 0xFF : 0xFE;
Surf.PolyFlags = HWR_GetBlendModeFlag(blendmode);
}
Surf.PolyColor.s.alpha = 0xFF;
// dont forget to enabled the depth test because we can't do this like
// before: polygons models are not sorted
/* fuck you */
if (spr->mobj->localskin)
{
@@ -1275,7 +1234,7 @@ void HWR_DrawMD2(gl_vissprite_t *spr)
if (md2->model)
{
md2_printModelInfo(md2->model);
GL_CreateModelVBOs(md2->model);
HWD.pfnCreateModelVBOs(md2->model);
}
else
{
@@ -1285,39 +1244,22 @@ void HWR_DrawMD2(gl_vissprite_t *spr)
}
}
//Hurdler: arf, I don't like that implementation at all... too much crappy
gpatch = md2->glpatch;
if (gpatch)
hwrPatch = ((GLPatch_t *)gpatch->hardware);
if (!gpatch || !hwrPatch
|| ((!hwrPatch->mipmap->format || !hwrPatch->mipmap->downloaded) && !md2->notexturefile))
gpatch = md2->grpatch;
if (!gpatch || ((!gpatch->mipmap->format || !gpatch->mipmap->downloaded) && !gpatch->notfound))
md2_loadTexture(md2);
gpatch = md2->grpatch; // Load it again, because it isn't being loaded into gpatch after md2_loadtexture...
// Load it again, because it isn't being loaded into gpatch after md2_loadtexture...
gpatch = md2->glpatch;
if (gpatch)
hwrPatch = ((GLPatch_t *)gpatch->hardware);
// Load blend texture
blendgpatch = md2->blendglpatch;
if (blendgpatch)
hwrBlendPatch = ((GLPatch_t *)blendgpatch->hardware);
if ((gpatch && hwrPatch && hwrPatch->mipmap->format) // don't load the blend texture if the base texture isn't available
&& (!blendgpatch || !hwrBlendPatch
|| ((!hwrBlendPatch->mipmap->format || !hwrBlendPatch->mipmap->downloaded) && !md2->noblendfile)))
if ((gpatch && gpatch->mipmap->format) // don't load the blend texture if the base texture isn't available
&& (!md2->blendgrpatch
|| ((!((GLPatch_t *)md2->blendgrpatch)->mipmap->format || !((GLPatch_t *)md2->blendgrpatch)->mipmap->downloaded)
&& !((GLPatch_t *)md2->blendgrpatch)->notfound)))
md2_loadBlendTexture(md2);
// Load it again, because it isn't being loaded into blendgpatch after md2_loadblendtexture...
blendgpatch = md2->blendglpatch;
if (blendgpatch)
hwrBlendPatch = ((GLPatch_t *)blendgpatch->hardware);
if (gpatch && hwrPatch && hwrPatch->mipmap->format) // else if meant that if a texture couldn't be loaded, it would just end up using something else's texture
if (gpatch && gpatch->mipmap->format) // else if meant that if a texture couldn't be loaded, it would just end up using something else's texture
{
if ((skincolors_t)spr->mobj->color != SKINCOLOR_NONE &&
blendgpatch && hwrBlendPatch->mipmap->format
&& gpatch->width == blendgpatch->width && gpatch->height == blendgpatch->height)
md2->blendgrpatch && ((GLPatch_t *)md2->blendgrpatch)->mipmap->format
&& gpatch->width == ((GLPatch_t *)md2->blendgrpatch)->width && gpatch->height == ((GLPatch_t *)md2->blendgrpatch)->height)
{
INT32 tcskinnum = TC_DEFAULT;
if ((spr->mobj->flags & MF_BOSS) && (spr->mobj->flags2 & MF2_FRET) && (leveltime & 1)) // Bosses "flash"
@@ -1337,24 +1279,24 @@ void HWR_DrawMD2(gl_vissprite_t *spr)
tcskinnum = TC_RAINBOW;
else
{
tcskinnum = (INT32)(K_GetMobjSkinNum(K_GetMobjSkin(spr->mobj), spr->mobj->skinlocal));
tcskinnum = (INT32)((skin_t*)( (spr->mobj->localskin) ? spr->mobj->localskin : spr->mobj->skin ) - ( (spr->mobj->skinlocal) ? localskins : skins ));
}
}
else tcskinnum = TC_DEFAULT;
}
HWR_GetBlendedTexture(gpatch, blendgpatch, tcskinnum, spr->colormap, (skincolors_t)spr->mobj->color);
HWR_GetBlendedTexture(gpatch, (GLPatch_t *)md2->blendgrpatch, tcskinnum, spr->colormap, (skincolors_t)spr->mobj->color);
}
else
{
// This is safe, since we know the texture has been downloaded
GL_SetTexture(hwrPatch->mipmap);
HWD.pfnSetTexture(gpatch->mipmap);
}
}
else
{
// Sprite
HWR_GetMappedPatch(spr->gpatch, spr->colormap);
gpatch = spr->gpatch; //gpatch = W_CachePatchNum(spr->patchlumpnum, PU_CACHE);
HWR_GetMappedPatch(gpatch, spr->colormap);
}
if (spr->mobj->frame & FF_ANIMATE)
@@ -1371,7 +1313,7 @@ void HWR_DrawMD2(gl_vissprite_t *spr)
// Interpolate the model interpolation. (lol)
tics -= FixedToFloat(rendertimefrac);
if (cv_glmdls.value == 1 && tics <= durs)
if (cv_grmdls.value == 1 && tics <= durs)
{
// frames are handled differently for states with FF_ANIMATE, so get the next frame differently for the interpolation
if (spr->mobj->frame & FF_ANIMATE)
@@ -1398,13 +1340,13 @@ void HWR_DrawMD2(gl_vissprite_t *spr)
p.x = FIXED_TO_FLOAT(interp.x);
p.y = FIXED_TO_FLOAT(interp.y)+md2->offset;
if (flip)
if (spr->mobj->eflags & MFE_VERTICALFLIP)
p.z = FIXED_TO_FLOAT(interp.z + spr->mobj->height);
else
p.z = FIXED_TO_FLOAT(interp.z);
if ((spr->mobj->skin || spr->mobj->localskin) && spr->mobj->sprite == SPR_PLAY)
sprdef = &K_GetMobjSkin(spr->mobj)->spritedef;
if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY)
sprdef = &((skin_t *)( (spr->mobj->localskin) ? spr->mobj->localskin : spr->mobj->skin ))->spritedef;
else
sprdef = &sprites[spr->mobj->sprite];
@@ -1421,59 +1363,112 @@ void HWR_DrawMD2(gl_vissprite_t *spr)
const fixed_t anglef = AngleFixed((R_PointToAngle(interp.x, interp.y))-ANGLE_180);
p.angley = FIXED_TO_FLOAT(anglef);
}
p.rollangle = 0.0f;
p.rollflip = 1;
p.rotaxis = 0;
p.spritexscale = FIXED_TO_FLOAT(spr->mobj->spritexscale);
p.spriteyscale = FIXED_TO_FLOAT(spr->mobj->spriteyscale);
angle_t sliptideroll = 0;
const angle_t sliptideroll = ((cv_sliptideroll.value && spr->mobj->player) ? spr->mobj->player->sliproll : 0);
const SINT8 flipfactor = flip ? -1 : 1;
if (spr->mobj->player)
sliptideroll = ((cv_sloperoll.value && cv_sliptideroll.value) ? spr->mobj->player->sliproll : 0);
if (spr->mobj->rollangle || sliptideroll)
if ((spr->mobj->rollangle)||(sliptideroll && cv_sliptideroll.value))
{
angle_t rollang = sliptideroll
? (spr->mobj->rollangle) + (sliptideroll * spr->mobj->player->kartstuff[k_aizdriftstrat])
: (spr->mobj->rollangle);
rollang *= flipfactor;
angle_t rollang = 0;
rollfactor = ((spr->mobj->rollmodel == true) ? 1 : 0);
rollang = (spr->mobj->player && sliptideroll && cv_sliptideroll.value)
? (spr->mobj->rollangle * rollfactor) + (sliptideroll * spr->mobj->player->sliptidemem)
: (spr->mobj->rollangle * rollfactor);
fixed_t anglef = AngleFixed(rollang);
p.rollangle = FIXED_TO_FLOAT(anglef);
p.rollmodel = (spr->mobj->rollmodel);
p.roll = true;
p.rollangle = 0.0f;
// rotation pivot
p.centerx = FIXED_TO_FLOAT(spr->mobj->radius/2)*(p.spritexscale);
p.centery = FIXED_TO_FLOAT(spr->mobj->height/2)*(p.spriteyscale);
if (anglef)
{
fixed_t camAngleDiff = AngleFixed(viewangle) - FLOAT_TO_FIXED(p.angley); // dumb reconversion back, I know
// rotation axis
if (sprinfo->available)
p.rotaxis = (UINT8)(sprinfo->pivot[(spr->mobj->frame & FF_FRAMEMASK)].rotaxis);
p.rollangle = FIXED_TO_FLOAT(anglef);
p.roll = true;
// rotation pivot
if (sprinfo->available)
{
p.centerx = FIXED_TO_FLOAT(sprinfo->pivot[frame].x);
p.centery = FIXED_TO_FLOAT(sprinfo->pivot[frame].y);
}
else
{
p.centerx = FIXED_TO_FLOAT(spr->mobj->radius/2);
p.centery = FIXED_TO_FLOAT(spr->mobj->height/2);
}
// rotation axes relative to camera
p.rollx = FIXED_TO_FLOAT(FINECOSINE(FixedAngle(camAngleDiff) >> ANGLETOFINESHIFT));
p.rollz = FIXED_TO_FLOAT(FINESINE(FixedAngle(camAngleDiff) >> ANGLETOFINESHIFT));
}
// for NiGHTS specifically but should work everywhere else
ang = R_PointToAngle (spr->mobj->x, spr->mobj->y) - (spr->mobj->player ? spr->mobj->player->frameangle : spr->mobj->angle);
if ((sprframe->rotate & SRF_RIGHT) && (ang < ANGLE_180)) // See from right
p.rollflip = 1;
else if ((sprframe->rotate & SRF_LEFT) && (ang >= ANGLE_180)) // See from left
p.rollflip = -1;
}
// slope pitch and roll
p.anglex += flipfactor*FIXED_TO_FLOAT(AngleFixed(interp.sloperoll));
p.anglez -= flipfactor*FIXED_TO_FLOAT(AngleFixed(interp.slopepitch));
p.anglex = 0.0f;
p.anglex2 = 0.0f;
#ifdef USE_FTRANSFORM_ANGLEZ
// Slope rotation from Kart
p.anglez = 0.0f;
p.anglez2 = 0.0f;
// use secondary angles for the slope rotation
if (spr->mobj->standingslope)
{
fixed_t tempz = spr->mobj->standingslope->normal.z;
fixed_t tempy = spr->mobj->standingslope->normal.y;
fixed_t tempx = spr->mobj->standingslope->normal.x;
fixed_t tempangle = AngleFixed(R_PointToAngle2(0, 0, FixedSqrt(FixedMul(tempy, tempy) + FixedMul(tempz, tempz)), tempx));
p.anglez2 = FIXED_TO_FLOAT(tempangle);
tempangle = -AngleFixed(R_PointToAngle2(0, 0, tempz, tempy));
p.anglex2 = FIXED_TO_FLOAT(tempangle);
}
else if ((spr->mobj->sloperoll || spr->mobj->slopepitch) && (!P_IsObjectOnGround(spr->mobj)) && (!paused))
{
SINT8 flipfactor = flip ? -1 : 1;
angle_t camang = R_PointToAngle(interp.x, interp.y);
angle_t mobjang;
if (spr->mobj->flags & (MF_NOTHINK|MF_SCENERY))
mobjang = spr->mobj->angle;
else
mobjang = interp.angle;
angle_t fmoang;
fmoang = camang - mobjang;
// slopepitch
p.anglex += flipfactor*FIXED_TO_FLOAT( AngleFixed(FixedMul(FINESINE((camang-fmoang) >> ANGLETOFINESHIFT), interp.slopepitch)) );
p.anglez -= flipfactor*FIXED_TO_FLOAT( AngleFixed(FixedMul(FINECOSINE((camang-fmoang) >> ANGLETOFINESHIFT), interp.slopepitch)) );
// sloperoll
p.anglex += flipfactor*FIXED_TO_FLOAT( AngleFixed(FixedMul(FINECOSINE((camang-fmoang) >> ANGLETOFINESHIFT), interp.sloperoll)) );
p.anglez += flipfactor*FIXED_TO_FLOAT( AngleFixed(FixedMul(FINESINE((camang-fmoang) >> ANGLETOFINESHIFT), interp.sloperoll)) );
p.roll = true;
}
// pitch and roll
p.anglex += flipfactor*FIXED_TO_FLOAT(AngleFixed(interp.roll));
p.anglez -= flipfactor*FIXED_TO_FLOAT(AngleFixed(interp.pitch));
p.fliptype = atransform.fliptype;
GL_SetShader(SHADER_MODEL); // model shader
if (interp.roll || interp.pitch)
{
SINT8 flipfactor = flip ? -1 : 1;
p.anglex += flipfactor*FIXED_TO_FLOAT(AngleFixed(interp.roll));
p.anglez -= flipfactor*FIXED_TO_FLOAT(AngleFixed(interp.pitch));
p.roll = true;
}
#endif
p.flip = atransform.flip;
#ifdef USE_FTRANSFORM_MIRROR
p.mirror = atransform.mirror; // from Kart
#endif
HWD.pfnSetShader(SHADER_MODEL); // model shader
{
SINT8 flipfactor = flip ? -1 : 1;
float this_scale = FIXED_TO_FLOAT(interp.scale);
float xs = this_scale * FIXED_TO_FLOAT(interp.spritexscale);
@@ -1483,11 +1478,11 @@ void HWR_DrawMD2(gl_vissprite_t *spr)
float oy = ys * flipfactor*FIXED_TO_FLOAT(interp.spriteyoffset);
// offset perpendicular to the camera angle
p.x -= ox * gl_viewsin;
p.y += ox * gl_viewcos;
p.x -= ox * gr_viewsin;
p.y += ox * gr_viewcos;
p.z += oy;
GL_DrawModel(md2->model, frame, durs, tics, nextFrame, &p, md2->scale * xs, md2->scale * ys, flip, hflip, &Surf);
HWD.pfnDrawModel(md2->model, frame, durs, tics, nextFrame, &p, md2->scale * xs, md2->scale * ys, flip, hflip, &Surf);
}
}
}
+3 -5
View File
@@ -28,10 +28,8 @@ typedef struct
float scale;
float offset;
model_t *model;
void *glpatch;
boolean notexturefile; // true if texture file was not found
void *blendglpatch;
boolean noblendfile; // true if blend texture file was not found
void *grpatch;
void *blendgrpatch;
boolean notfound;
INT32 skin;
boolean error;
@@ -42,7 +40,7 @@ extern md2_t md2_playermodels[MAXSKINS];
extern md2_t md2_localplayermodels[MAXLOCALSKINS];
void HWR_InitMD2(void);
void HWR_DrawMD2(gl_vissprite_t *spr);
void HWR_DrawMD2(gr_vissprite_t *spr);
void HWR_AddPlayerMD2(INT32 skin, boolean local);
void HWR_AddSpriteMD2(size_t spritenum);
-231
View File
@@ -1,231 +0,0 @@
// SONIC ROBO BLAST 2 KART
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Kart Krew.
// Copyright (C) 2020 by Sonic Team Junior.
// Copyright (C) 2000 by DooM Legacy Team.
// Copyright (C) 1996 by id Software, Inc.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file hw_portal.c
/// \brief OpenGL renderer portals.
// ==========================================================================
// Visual portals (attr. Hannu Hanhi)
// ==========================================================================
#ifdef HWRENDER
#include "../r_portal.h"
#include "../z_zone.h"
#include "hw_clip.h"
#include "hw_gl.h"
#include "hw_defs.h"
#include "hw_main.h"
#include "hw_portal.h"
SINT8 gl_portal_state = GLPORTAL_OFF;
gl_portallist_t *currentportallist;
// clip the area outside the portal destination window
void HWR_PortalClipping(gl_portal_t *portal)
{
gld_clipper_SafeAddClipRange(portal->angle1, portal->angle2);
}
static gl_portal_t* HWR_Portal_Add (seg_t *seg)
{
gl_portal_t *portal = Z_Malloc(sizeof(gl_portal_t), PU_STATIC, NULL);
// Linked list.
if (!currentportallist->base)
{
currentportallist->base = portal;
currentportallist->cap = portal;
}
else
{
currentportallist->cap->next = portal;
currentportallist->cap = portal;
}
portal->next = NULL;
portal->seg = seg;
return portal;
}
void HWR_FreePortalList(gl_portallist_t freelist)
{
portalcullsector = NULL;
// free memory from portal list allocated by calls to Add2Lines
gl_portal_t *gl_portal_temp = freelist.base;
while (gl_portal_temp)
{
gl_portal_t *nextportal = gl_portal_temp->next;
Z_Free(gl_portal_temp);
gl_portal_temp = nextportal;
}
}
void HWR_Portal_Add2Lines(const INT32 line1, const INT32 line2, seg_t *seg)
{
gl_portal_t *portal = HWR_Portal_Add(seg);
// Offset the portal view by the linedef centers
line_t* start = &lines[line1];
line_t* dest = &lines[line2];
angle_t dangle = R_PointToAngle2(0, 0, dest->dx, dest->dy) - R_PointToAngle2(start->dx, start->dy, 0, 0);
fixed_t disttopoint;
angle_t angtopoint;
vertex_t dest_c, start_c;
// looking glass center
start_c.x = start->v1->x/2 + start->v2->x/2;
start_c.y = start->v1->y/2 + start->v2->y/2;
// other side center
dest_c.x = dest->v1->x/2 + dest->v2->x/2;
dest_c.y = dest->v1->y/2 + dest->v2->y/2;
disttopoint = R_PointToDist2(start_c.x, start_c.y, viewx, viewy);
angtopoint = R_PointToAngle2(start_c.x, start_c.y, viewx, viewy);
angtopoint += dangle;
portal->viewx = dest_c.x + FixedMul(FINECOSINE(angtopoint>>ANGLETOFINESHIFT), disttopoint);
portal->viewy = dest_c.y + FixedMul(FINESINE(angtopoint>>ANGLETOFINESHIFT), disttopoint);
portal->viewz = viewz + dest->frontsector->floorheight - start->frontsector->floorheight;
portal->viewangle = viewangle + dangle;
portal->angle1 = R_PointToAngle64(seg->v1->x, seg->v1->y) + dangle;
portal->angle2 = R_PointToAngle64(seg->v2->x, seg->v2->y) + dangle;
portal->clipline = line2;
}
void HWR_PortalFrame(gl_portal_t* portal)
{
viewx = portal->viewx;
viewy = portal->viewy;
viewz = portal->viewz;
viewangle = portal->viewangle;
//viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT);
//viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT);
if (portal->clipline != -1)
{
portalclipline = &lines[portal->clipline];
portalcullsector = portalclipline->frontsector;
viewsector = portalclipline->frontsector;
}
else
{
portalclipline = NULL;
portalcullsector = NULL;
viewsector = R_PointInSubsector(viewx, viewy)->sector;
}
}
// Renders a portal segment.
static void HWR_RenderPortalSeg(gl_portal_t* portal, SINT8 state)
{
gl_drawing_stencil = true; // do not draw outside of the stencil buffer, idiot.
// set our portal state and prepare to render the seg
HWR_SetPortalState(state);
gl_curline = portal->seg;
gl_frontsector = portal->seg->frontsector;
gl_backsector = portal->seg->backsector;
HWR_ProcessSeg();
gl_drawing_stencil = false;
// need to work around the r_opengl PF_Invisible bug with this call
// similarly as in the linkdraw hack in HWR_DrawSprites
GL_SetBlend(PF_Translucent|PF_Occlude|PF_Masked);
}
// Renders a single portal from the current viewpoint.
void HWR_RenderPortal(gl_portal_t* portal, gl_portal_t* rootportal, const float fpov, player_t *player, int stencil_level)
{
// draw portal seg to stencil buffer with increment
HWR_SetTransform(fpov);
HWR_ClearClipper();
HWR_SetStencilState(HWR_STENCIL_BEGIN, stencil_level);
HWR_RenderPortalSeg(portal, GLPORTAL_STENCIL);
// go to portal frame lmao
HWR_PortalFrame(portal);
// call HWR_RenderViewpoint
HWR_RenderViewpoint(portal, fpov, player, stencil_level + 1, true);
// return to current frame
if (rootportal)
HWR_PortalFrame(rootportal);
else // current frame is not a portal frame but the main view!
{
R_SetupFrame(viewssnum, false);
portalclipline = NULL;
}
// remove portal seg from stencil buffer
HWR_SetTransform(fpov);
HWR_ClearClipper();
HWR_SetStencilState(HWR_STENCIL_REVERSE, stencil_level);
HWR_RenderPortalSeg(portal, GLPORTAL_STENCIL);
// draw portal seg to depth buffer
HWR_ClearClipper();
HWR_SetStencilState(HWR_STENCIL_DEPTH, stencil_level);
HWR_RenderPortalSeg(portal, GLPORTAL_DEPTH);
}
// returns true if the point is on the correct (viewable) side of the
// portal destination line
boolean HWR_PortalCheckPointSide(fixed_t x, fixed_t y)
{
// we are checking if the point is on the viewable side of the portal exit.
// being exactly on the portal exit line is not enough to pass the test.
// P_PointOnLineSide could behave differently from this expectation on this case,
// so first check if the point is precisely on the line, and then if not, check the side.
vertex_t closest_point;
P_ClosestPointOnLine(x, y, portalclipline, &closest_point);
if (closest_point.x != x || closest_point.y != y)
{
if (P_PointOnLineSide(x, y, portalclipline) != 1)
return true;
}
return false;
}
boolean HWR_PortalCheckBBox(const fixed_t *bspcoord)
{
if (!portalclipline)
return true;
if (HWR_PortalCheckPointSide(bspcoord[BOXLEFT], bspcoord[BOXTOP]) ||
HWR_PortalCheckPointSide(bspcoord[BOXLEFT], bspcoord[BOXBOTTOM]) ||
HWR_PortalCheckPointSide(bspcoord[BOXRIGHT], bspcoord[BOXTOP]) ||
HWR_PortalCheckPointSide(bspcoord[BOXRIGHT], bspcoord[BOXBOTTOM]))
{
return true;
}
// we did not find any reason to pass the check, so return failure
return false;
}
#endif
-81
View File
@@ -1,81 +0,0 @@
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2018 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file hw_portal.h
/// \brief OpenGL renderer portal struct, functions, linked list extern.
#ifndef __HW_PORTAL__
#define __HW_PORTAL__
#ifdef HWRENDER
#include "../doomstat.h"
#include "../r_data.h"
#include "../r_bsp.h"
/** Portal structure.
*/
enum
{
GLPORTAL_OFF,
GLPORTAL_SEARCH,
GLPORTAL_STENCIL,
GLPORTAL_DEPTH,
GLPORTAL_INSIDE,
};
typedef struct gl_portal_s
{
struct gl_portal_s *next;
// Viewport.
fixed_t viewx;
fixed_t viewy;
fixed_t viewz;
angle_t viewangle;
seg_t *seg; // seg that is used for drawing to the stencil buffer
INT32 clipline; // Optional clipline for line-based portals
// angles for the left and right edges of the portal
// relative to the viewpoint
angle_t angle1;
angle_t angle2;
} gl_portal_t;
typedef struct gl_portallist_s
{
gl_portal_t *base;
gl_portal_t *cap;
} gl_portallist_t;
extern SINT8 gl_portal_state;
// new thing
extern gl_portallist_t *currentportallist;
static inline void HWR_SetPortalState (SINT8 state)
{
gl_portal_state = state;
}
// Adds an entry to the clipper for portal rendering
void HWR_PortalClipping(gl_portal_t *portal);
void HWR_Portal_Add2Lines(const INT32 line1, const INT32 line2, seg_t *seg);
void HWR_PortalFrame(gl_portal_t* portal);
void HWR_RenderPortal(gl_portal_t* portal, gl_portal_t* rootportal, const float fpov, player_t *player, int stencil_level);
void HWR_FreePortalList(gl_portallist_t portallist);
boolean HWR_PortalCheckPointSide(fixed_t x, fixed_t y);
boolean HWR_PortalCheckBBox(const fixed_t *bspcoord);
#endif
#endif
+29 -26
View File
@@ -13,7 +13,7 @@
#include "hw_main.h"
#include "hw_glob.h"
#include "hw_gl.h"
#include "hw_drv.h"
#include "hw_shaders.h"
#include "../z_zone.h"
@@ -25,10 +25,13 @@ static struct {
const char *vertex;
const char *fragment;
} const gl_shadersources[] = {
// Floor shader
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_FLOOR_FRAGMENT_SHADER},
// Shadow shader
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_SHADOW_FRAGMENT_SHADER},
// Wall shader
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_WALL_FRAGMENT_SHADER},
@@ -36,7 +39,7 @@ static struct {
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_WALL_FRAGMENT_SHADER},
// Model shader
{GLSL_MODEL_LIGHTING_VERTEX_SHADER, GLSL_WALL_FRAGMENT_SHADER},
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_WALL_FRAGMENT_SHADER},
// Water shader
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_WATER_FRAGMENT_SHADER},
@@ -49,7 +52,7 @@ static struct {
// Palette postprocess shader
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_PALETTE_POSTPROCESS_FRAGMENT_SHADER},
// UI colormap fade shader
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_UI_COLORMAP_FADE_FRAGMENT_SHADER},
@@ -87,7 +90,7 @@ boolean HWR_InitShaders(void)
{
int i;
if (!GL_InitShaders())
if (!HWD.pfnInitShaders())
return false;
for (i = 0; i < NUMSHADERTARGETS; i++)
@@ -276,11 +279,11 @@ static char *HWR_PreprocessShader(char *original)
// Calculate length of modified shader.
new_len = original_len;
if (cv_glpaletterendering.value)
if (cv_grpaletterendering.value)
ADD_TO_LEN(PALETTE_RENDERING_DEFINE)
if (cv_gllightdither.value)
if (cv_lightdither.value)
ADD_TO_LEN(LIGHT_DITHERING_DEFINE)
#undef ADD_TO_LEN
@@ -321,10 +324,10 @@ static char *HWR_PreprocessShader(char *original)
}
// Write the defines.
if (cv_glpaletterendering.value)
if (cv_grpaletterendering.value)
WRITE_DEFINE(PALETTE_RENDERING_DEFINE)
if (cv_gllightdither.value)
if (cv_lightdither.value)
WRITE_DEFINE(LIGHT_DITHERING_DEFINE)
#undef WRITE_DEFINE
@@ -366,16 +369,16 @@ static void HWR_CompileShader(int index)
{
char *preprocessed = HWR_PreprocessShader(vertex_source);
if (!preprocessed) return;
GL_LoadShader(index, preprocessed, HWD_SHADERSTAGE_VERTEX);
HWD.pfnLoadShader(index, preprocessed, HWD_SHADERSTAGE_VERTEX);
}
if (fragment_source)
{
char *preprocessed = HWR_PreprocessShader(fragment_source);
if (!preprocessed) return;
GL_LoadShader(index, preprocessed, HWD_SHADERSTAGE_FRAGMENT);
HWD.pfnLoadShader(index, preprocessed, HWD_SHADERSTAGE_FRAGMENT);
}
gl_shaders[index].compiled = GL_CompileShader(index);
gl_shaders[index].compiled = HWD.pfnCompileShader(index);
}
// compile or recompile shaders
@@ -400,18 +403,17 @@ void HWR_CompileShaders(void)
int HWR_GetShaderFromTarget(int shader_target)
{
if (cv_glshaders.value == 1)
{
int custom_shader = gl_shadertargets[shader_target].custom_shader;
// use custom shader if following are true
// - custom shader exists
// - custom shader has been compiled successfully
// - custom shaders are enabled
if (custom_shader != -1 && gl_shaders[custom_shader].compiled)
return custom_shader;
}
return gl_shadertargets[shader_target].base_shader;
int custom_shader = gl_shadertargets[shader_target].custom_shader;
// use custom shader if following are true
// - custom shader exists
// - custom shader has been compiled successfully
// - custom shaders are enabled
// - custom shaders are allowed by the server
if (custom_shader != -1 && gl_shaders[custom_shader].compiled &&
cv_grshaders.value == 1)
return custom_shader;
else
return gl_shadertargets[shader_target].base_shader;
}
static inline UINT16 HWR_FindShaderDefs(UINT16 wadnum)
@@ -430,6 +432,7 @@ static inline UINT16 HWR_FindShaderDefs(UINT16 wadnum)
customshaderxlat_t shaderxlat[] =
{
{"Flat", SHADER_FLOOR},
{"Shadow", SHADER_SHADOW},
{"WallTexture", SHADER_WALL},
{"Sprite", SHADER_SPRITE},
{"Model", SHADER_MODEL},
@@ -562,7 +565,7 @@ void HWR_LoadCustomShadersFromFile(UINT16 wadnum, boolean PK3)
int i;
boolean modified_shaders[NUMSHADERTARGETS] = {0};
if (!gl_shadersavailable)
if (!gr_shadersavailable)
return;
lump = HWR_FindShaderDefs(wadnum);
+7 -38
View File
@@ -31,31 +31,6 @@
"gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;\n" \
"}\0"
// reinterpretation of sprite lighting for models
// it's a combination of how it works for normal sprites & papersprites
#define GLSL_MODEL_LIGHTING_VERTEX_SHADER \
"uniform float lighting;\n" \
"uniform vec3 light_dir;\n" \
"uniform float light_contrast;\n" \
"uniform float light_backlight;\n" \
"void main()\n" \
"{\n" \
"gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;\n" \
"float light = lighting;\n" \
"if (length(light_dir) > 0.000001) {\n" \
"mat4 m4 = gl_ProjectionMatrix * gl_ModelViewMatrix;\n" \
"mat3 m3 = mat3( m4[0].xyz, m4[1].xyz, m4[2].xyz );\n" \
"float extralight = -dot(normalize(gl_Normal * m3), normalize(light_dir));\n" \
"extralight *= light_contrast - light_backlight;\n" \
"extralight *= lighting / 255.0;\n" \
"light += extralight * 2.5;\n" \
"}\n" \
"light = clamp(light / 255.0, 0.0, 1.0);\n" \
"gl_FrontColor = vec4(light, light, light, 1.0);\n" \
"gl_TexCoord[0].xy = gl_MultiTexCoord0.xy;\n" \
"gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;\n" \
"}\0"
// ==================
// Fragment shaders
// ==================
@@ -124,7 +99,6 @@
GLSL_DOOM_COLORMAP_NODITHER \
"#endif\n" \
"}\n"
// lighting cap adjustment:
// first num (155.0), increase to make it start to go dark sooner
// second num (0.26), increase to make it go dark faster
@@ -197,7 +171,7 @@
"gl_FragColor = final_color;\n" \
"}\n" \
"#endif\0"
#define GLSL_SOFTWARE_FRAGMENT_SHADER_NOPAL \
"uniform sampler2D tex;\n" \
"uniform vec4 poly_color;\n" \
@@ -220,29 +194,26 @@
// hand tuned adjustments for light level calculation
#define GLSL_FLOOR_FUDGES \
"#version 120\n" \
"#define STARTMAP_FUDGE 1.06\n" \
"#define SCALE_FUDGE 1.15\n"
#define GLSL_WALL_FUDGES \
"#version 120\n" \
"#define STARTMAP_FUDGE 1.05\n" \
"#define SCALE_FUDGE 2.2\n"
#define GLSL_FLOOR_FRAGMENT_SHADER \
"#version 120\n" \
GLSL_FLOOR_FUDGES \
GLSL_SOFTWARE_FRAGMENT_SHADER
// this is very backwards
// but we wanna have the game look like vanilla does
// oh well
#define GLSL_WALL_FRAGMENT_SHADER \
"#version 120\n" \
"#ifdef SRB2_PALETTE_RENDERING\n" \
GLSL_WALL_FUDGES \
"#else\n" \
GLSL_FLOOR_FUDGES \
"#endif\n" \
GLSL_SOFTWARE_FRAGMENT_SHADER
#define GLSL_SHADOW_FRAGMENT_SHADER \
GLSL_FLOOR_FUDGES \
GLSL_SOFTWARE_FRAGMENT_SHADER_NOPAL
//
// Water surface shader
@@ -259,7 +230,6 @@
"vec4 texel = texture2D(tex, vec2(gl_TexCoord[0].s - sdistort, gl_TexCoord[0].t - cdistort));\n"
#define GLSL_WATER_FRAGMENT_SHADER \
"#version 120\n" \
GLSL_FLOOR_FUDGES \
"const float freq = 0.025;\n" \
"const float amp = 0.025;\n" \
@@ -308,7 +278,6 @@
// The floor fudges are used, but should the wall fudges be used instead? or something inbetween?
// or separate values for floors and walls? (need to change more than this shader for that)
#define GLSL_FOG_FRAGMENT_SHADER \
"#version 120\n" \
GLSL_FLOOR_FUDGES \
"uniform vec4 tint_color;\n" \
"uniform vec4 fade_color;\n" \
+123
View File
@@ -0,0 +1,123 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// Copyright (C) 2005 by SRB2 Jr. Team.
//
// 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.
//-----------------------------------------------------------------------------
/// \file
/// \brief 3D sound definitions
#ifndef __HWS_DATA_H__
#define __HWS_DATA_H__
#define NORMAL_SEP 128
// abuse?
#define STATIC_SOURCES_NUM 6 // Total number of static sources
#define MIN_DISTANCE 160.0f
#define MAX_DISTANCE 1200.0f
typedef struct source_pos_s
{
double x;
double y;
double z;
} source_pos_t;
typedef struct source3D_pos_s
{
float x;
float y;
float z;
//float angle;
float momx;
float momy;
float momz;
} source3D_pos_t;
enum {NORMAL_PITCH = 128};
/*typedef struct source2D_data_s
{
INT32 volume;
INT32 sep;
} source2D_data_t;*/
// General 3D sound source description
typedef struct source3D_data_s
{
float min_distance; //
float max_distance; //
INT32 head_relative; //
INT32 permanent; //
source3D_pos_t pos; // source position in 3D
} source3D_data_t;
// Sound data
typedef struct sfx_data_s
{
size_t length;
void *data;
INT32 priority;
INT32 sep; // Only when source is 2D sound
} sfx_data_t;
// Sound cone (for 3D sources)
typedef struct cone_def_s
{
float inner;
float outer;
INT32 outer_gain;
/*float f_angle;
float h_angle;*/
} cone_def_t;
typedef struct listener_data_s
{
// Listener position
double x;
double y;
double z;
// Listener front and head orientation (degrees)
double f_angle;
double h_angle;
// Listener momentums
double momx;
double momy;
double momz;
} listener_data_t;
typedef struct snddev_s
{
INT32 sample_rate;
INT32 bps;
size_t numsfxs;
// Windows specific data
#ifdef _WIN32
UINT32 cooplevel;
HWND hWnd;
#endif
} snddev_t;
#endif //__HWS_DATA_H__
+22 -3
View File
@@ -358,8 +358,8 @@ static INT32 WINAPI SetRes(viddef_t *lvid, vmode_t *pcurrentmode)
else
textureformatGL = GL_RGB5_A1;
GL_SetModelView(lvid->width, lvid->height);
GL_SetStates();
SetModelView(lvid->width, lvid->height);
SetStates();
// we need to clear the depth buffer. Very important!!!
pglClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
@@ -526,7 +526,7 @@ EXPORT void HWRAPI(Shutdown) (void)
// -----------------+
// FinishUpdate : Swap front and back buffers
// -----------------+
void GL_FinishUpdate (INT32 waitvbl)
EXPORT void HWRAPI(FinishUpdate) (INT32 waitvbl)
{
#ifdef USE_WGL_SWAP
static INT32 oldwaitvbl = 0;
@@ -547,4 +547,23 @@ void GL_FinishUpdate (INT32 waitvbl)
SwapBuffers(hDC);
}
// -----------------+
// SetPalette : Set the color lookup table for paletted textures
// : in OpenGL, we store values for conversion of paletted graphics when
// : they are downloaded to the 3D card.
// -----------------+
EXPORT void HWRAPI(SetPalette) (RGBA_t *pal)
{
INT32 i;
for (i = 0; i < 256; i++)
{
myPaletteData[i].s.red = pal[i].s.red;
myPaletteData[i].s.green = pal[i].s.green;
myPaletteData[i].s.blue = pal[i].s.blue;
myPaletteData[i].s.alpha = pal[i].s.alpha;
}
}
#endif
File diff suppressed because it is too large. Load diff
+16 -13
View File
@@ -43,9 +43,8 @@
#endif
#define _CREATE_DLL_ // necessary for Unix AND Windows
#include "../../doomdef.h"
#include "../hw_gl.h"
#include "../hw_drv.h"
#include "../../z_zone.h"
// ==========================================================================
@@ -66,15 +65,14 @@ extern FILE *gllogstream;
// PROTOS
// ==========================================================================
FUNCPRINTF void GL_DBG_Printf(const char *format, ...);
boolean LoadGL(void);
void *GetGLFunc(const char *proc);
boolean SetupGLfunc(void);
void SetupGLFunc4(void);
void GL_Flush(void);
INT32 GL_isExtAvailable(const char *extension, const GLubyte *start);
void GL_SetModelView(GLint w, GLint h);
void GL_SetStates(void);
void Flush(void);
INT32 isExtAvailable(const char *extension, const GLubyte *start);
void SetModelView(GLint w, GLint h);
void SetStates(void);
#ifndef GL_EXT_texture_filter_anisotropic
#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
@@ -100,12 +98,18 @@ typedef void (APIENTRY * PFNglGetIntegerv) (GLenum pname, GLint *params);
extern PFNglGetIntegerv pglGetIntegerv;
typedef const GLubyte* (APIENTRY * PFNglGetString) (GLenum name);
extern PFNglGetString pglGetString;
#if 0
typedef void (APIENTRY * PFNglEnableClientState) (GLenum cap); // redefined in r_opengl.c
static PFNglEnableClientState pglEnableClientState;
#endif
#endif
#ifdef USE_FBO_OGL
void GL_Framebuffer_Unbind(void);
void GL_Framebuffer_Enable(void);
void GL_Framebuffer_Disable(void);
void GLFramebuffer_DeleteAttachments(void);
void GLFramebuffer_Unbind(void);
void GLFramebuffer_Enable(void);
void GLFramebuffer_Disable(void);
extern GLuint FramebufferObject, FramebufferTexture, RenderbufferObject;
extern GLboolean FrameBufferEnabled, RenderToFramebuffer;
@@ -119,8 +123,6 @@ extern boolean supportFBO;
extern const GLubyte *gl_version;
extern const GLubyte *gl_renderer;
extern const GLubyte *gl_extensions;
extern const GLubyte *gl_vendor;
extern GLuint gl_num_extensions;
extern int majorGL, minorGL;
@@ -134,6 +136,7 @@ extern boolean supportMipMap;
/** \brief OpenGL flags for video driver
*/
extern INT32 oglflags;
extern GLint textureformatGL;
extern GLfloat projMatrix[16];
File diff suppressed because it is too large. Load diff
+59
View File
@@ -0,0 +1,59 @@
[Project]
FileName=s_ds3d.dev
Name=s_ds3d
Ver=1
IsCpp=1
Type=3
Compiler=-D_M_IX86=500_@@_-Wall_@@_-D_WINDOWS_@@_-Os_@@_-fno-strict-aliasing_@@_-fomit-frame-pointer_@@_
CppCompiler=
Includes=
Linker=--def ../s_mingw.def_@@_-luuid_@@_-ldsound_@@_
Libs=
UnitCount=1
Folders=
ObjFiles=
PrivateResource=
ResourceIncludes=
MakeIncludes=
Icon=
ExeOutput=C:\srb2demo2
ObjectOutput=..\..\..\objs\Mingw\s_ds3d
OverrideOutput=1
OverrideOutputName=s_ds3d.dll
HostApplication=
CommandLine=
IncludeVersionInfo=0
SupportXPThemes=0
CompilerSet=0
CompilerSettings=00000000000000000111d0
UseCustomMakefile=0
CustomMakefile=
[Unit1]
FileName=s_ds3d.c
Folder=
Compile=1
CompileCpp=0
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[VersionInfo]
Major=0
Minor=1
Release=1
Build=1
LanguageID=1033
CharsetID=1252
CompanyName=
FileVersion=0.1
FileDescription=Developed using the Dev-C++ IDE
InternalName=
LegalCopyright=
LegalTrademarks=
OriginalFilename=s_ds3d.exe
ProductName=s_ds3d
ProductVersion=0.1
AutoIncBuildNr=0
+99
View File
@@ -0,0 +1,99 @@
# Microsoft Developer Studio Project File - Name="s_ds3d" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=s_ds3d - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "s_ds3d.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "s_ds3d.mak" CFG="s_ds3d - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "s_ds3d - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "s_ds3d - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "s_ds3d - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "..\..\..\bin\VC\Release\s_ds3d"
# PROP Intermediate_Dir "..\..\..\objs\VC\Release\s_ds3d"
# PROP Ignore_Export_Lib 1
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "S_DS3D_EXPORTS" /YX /FD /c
# ADD CPP /nologo /G5 /MT /W3 /GX /Zi /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "__WIN32__" /D "__MSC__" /FD /c
# SUBTRACT CPP /YX
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x419 /d "NDEBUG"
# ADD RSC /l 0x40c /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
# ADD LINK32 dsound.lib /nologo /dll /pdb:"..\..\..\bin\VC\Release\s_ds3d.pdb" /machine:I386 /out:"..\..\..\bin\VC\Release\s_ds3d.dll"
# SUBTRACT LINK32 /pdb:none
!ELSEIF "$(CFG)" == "s_ds3d - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "..\..\..\bin\VC\Debug\s_ds3d"
# PROP Intermediate_Dir "..\..\..\objs\VC\Debug\s_ds3d"
# PROP Ignore_Export_Lib 1
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "S_DS3D_EXPORTS" /YX /FD /GZ /c
# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "__WIN32__" /D "__MSC__" /FD /GZ /c
# SUBTRACT CPP /YX
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
# ADD BASE RSC /l 0x419 /d "_DEBUG"
# ADD RSC /l 0x40c /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 dsound.lib /nologo /dll /pdb:"..\..\..\bin\VC\Debug\s_ds3d.pdb" /debug /machine:I386 /out:"..\..\..\bin\VC\Debug\s_ds3d.dll" /pdbtype:sept
# SUBTRACT LINK32 /pdb:none /incremental:no /nodefaultlib
!ENDIF
# Begin Target
# Name "s_ds3d - Win32 Release"
# Name "s_ds3d - Win32 Debug"
# Begin Source File
SOURCE=.\s_ds3d.c
# End Source File
# End Target
# End Project
File diff suppressed because it is too large. Load diff
+59
View File
@@ -0,0 +1,59 @@
[Project]
FileName=s_fmod.dev
Name=s_fmod
Ver=1
IsCpp=1
Type=3
Compiler=-D_M_IX86=500_@@_-Wall_@@_-D_WINDOWS_@@_-Os_@@_-fomit-frame-pointer_@@_
CppCompiler=
Includes=..\..\win32\FMOD
Linker=--def ../s_mingw.def_@@_-lfmod_@@_
Libs=..\..\win32\FMOD
UnitCount=1
Folders=
ObjFiles=
PrivateResource=
ResourceIncludes=
MakeIncludes=
Icon=
ExeOutput=C:\srb2demo2
ObjectOutput=..\..\..\objs\Mingw\s_fmod
OverrideOutput=1
OverrideOutputName=s_fmod.dll
HostApplication=
CommandLine=
IncludeVersionInfo=0
SupportXPThemes=0
CompilerSet=0
CompilerSettings=00000000000000000111d0
UseCustomMakefile=0
CustomMakefile=
[Unit1]
FileName=s_fmod.c
Folder=
Compile=1
CompileCpp=0
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[VersionInfo]
Major=1
Minor=0
Release=8
Build=42
LanguageID=1033
CharsetID=1252
CompanyName=Alam Arias
FileVersion=1.42
FileDescription=SRB2 Sound API DLL for FMOD
InternalName=Super FMOD!
LegalCopyright=
LegalTrademarks=
OriginalFilename=s_fmod.dll
ProductName=s_fmod
ProductVersion=0.1
AutoIncBuildNr=0
+97
View File
@@ -0,0 +1,97 @@
# Microsoft Developer Studio Project File - Name="s_fmod" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=s_fmod - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "s_fmod.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "s_fmod.mak" CFG="s_fmod - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "s_fmod - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "s_fmod - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "s_fmod - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "..\..\..\bin\VC\Release\s_fmod"
# PROP Intermediate_Dir "..\..\..\objs\VC\Release\s_fmod"
# PROP Ignore_Export_Lib 1
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "S_FMOD_EXPORTS" /YX /FD /c
# ADD CPP /nologo /MT /W3 /GX /Zi /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "__WIN32__" /D "__MSC__" /FR /FD /c
# SUBTRACT CPP /YX
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
# ADD LINK32 fmodvc.lib /nologo /dll /pdb:"..\..\..\bin\VC\Release\s_fmod.pdb" /machine:I386 /out:"..\..\..\bin\VC\Release\s_fmod.dll"
!ELSEIF "$(CFG)" == "s_fmod - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "..\..\..\bin\VC\Debug\s_fmod"
# PROP Intermediate_Dir "..\..\..\objs\VC\Debug\s_fmod"
# PROP Ignore_Export_Lib 1
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "S_FMOD_EXPORTS" /YX /FD /GZ /c
# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "__WIN32__" /D "__MSC__" /FR /FD /GZ /c
# SUBTRACT CPP /YX
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 fmodvc.lib /nologo /dll /pdb:"..\..\..\bin\VC\Debug\s_fmod.pdb" /debug /machine:I386 /out:"..\..\..\bin\VC\Debug\s_fmod.dll" /pdbtype:sept
!ENDIF
# Begin Target
# Name "s_fmod - Win32 Release"
# Name "s_fmod - Win32 Debug"
# Begin Source File
SOURCE=.\s_fmod.c
# End Source File
# End Target
# End Project
+998
View File
@@ -0,0 +1,998 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// Copyright (C) 2001 by DooM Legacy Team.
//
// 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.
//-----------------------------------------------------------------------------
/// \file
/// \brief General driver for 3D sound system
///
/// Implementend via OpenAL API
#ifdef _WINDOWS
//#define WIN32_LEAN_AND_MEAN
#define RPC_NO_WINDOWS_H
#include <windows.h>
#include <stdio.h>
FILE* logstream = NULL;
#else
#include <stdarg.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#ifndef HAVE_SDL // let not make a logstream here is we are inline the HW3D in the SDL binary
FILE* logstream = NULL;
#endif
#endif
#ifdef __APPLE__
#include <al.h> //Main AL
#include <alc.h> //Helpers
#else
#include <AL/al.h> //Main AL
#include <AL/alc.h> //Helpers
#endif
#define _CREATE_DLL_
#include "../../doomdef.h"
#include "../hw3dsdrv.h"
//#undef DEBUG_TO_FILE
//#if defined ( HAVE_SDL ) && !defined ( LOGMESSAGES )
#define DEBUG_TO_FILE
//#endif
// Internal sound stack
typedef struct stack_snd_s
{
ALuint ALsource;// 3D data of 3D source
ALint sfx_id;// Currently unused
ALint LRU;// Currently unused
ALboolean permanent;// Flag of static source
} stack_snd_t;
#ifndef AL_INVALID
#define AL_INVALID (-1)
#endif
static I_Error_t I_ErrorOpenAl = NULL;
static stack_snd_t *ALstack = NULL; // Sound stack
static ALsizei allocated_sounds = 0; // Size of stack
static ALsizei allocate_delta = 16;
static ALCdevice *ALCDevice = NULL;
static ALCcontext *ALContext = NULL;
static ALenum ALo_Lasterror = AL_NO_ERROR;
static ALenum ALCo_Lasterror = ALC_NO_ERROR;
static ALenum ALo_GetError(ALvoid)
{
ALo_Lasterror = alGetError();
return ALo_Lasterror;
}
static ALenum ALCo_GetError(ALvoid)
{
ALCo_Lasterror = alcGetError(ALCDevice);
return ALCo_Lasterror;
}
static ALfloat ALvol(ALint vol, ALsizei step)
{
return ((ALfloat)vol)/(ALfloat)step;
}
/*
static ALfloat Alpitch(ALint pitch)
{
#if 1
pitch = NORMAL_PITCH;
#endif
return pitch < NORMAL_PITCH ?
(float)(pitch + NORMAL_PITCH) / (NORMAL_PITCH * 2)
:(float)pitch / (float)NORMAL_PITCH;
}
*/
static const ALchar *GetALErrorString(ALenum err)
{
switch (err)
{
case AL_NO_ERROR:
return "There no error";
break;
case AL_INVALID_NAME:
return "Invalid name";
break;
case AL_INVALID_ENUM:
return "Invalid enum";
break;
case AL_INVALID_VALUE:
return "Invalid value";
break;
case AL_INVALID_OPERATION:
return "Invalid operation";
break;
case AL_OUT_OF_MEMORY:
return "Out Of Memory";
break;
default:
return alGetString(err);
break;
}
}
static const ALchar *GetALCErrorString(ALenum err)
{
switch (err)
{
case ALC_NO_ERROR:
return "There no error";
break;
case ALC_INVALID_DEVICE:
return "Invalid Device";
break;
case ALC_INVALID_CONTEXT:
return "Invalid Context";
break;
case ALC_INVALID_ENUM:
return "Invalid enum";
break;
case ALC_INVALID_VALUE:
return "Invalid value";
break;
case ALC_OUT_OF_MEMORY:
return "Out Of Memory";
break;
default:
return alcGetString(ALCDevice, err);
break;
}
}
/***************************************************************
*
* DBG_Printf
* Output error messages to debug log if DEBUG_TO_FILE is defined,
* else do nothing
*
**************************************************************
*/
// -----------------+
// DBG_Printf : Output error messages to debug log if DEBUG_TO_FILE is defined,
// : else do nothing
// Returns :
// -----------------+
FUNCPRINTF void DBG_Printf(const char *lpFmt, ... )
{
#ifdef DEBUG_TO_FILE
char str[4096] = "";
va_list arglist;
va_start(arglist, lpFmt);
vsnprintf(str, 4096, lpFmt, arglist);
va_end(arglist);
if (logstream)
fwrite(str, strlen(str), 1 , logstream);
#else
lpFmt = NULL;
#endif
}
/***************************************************************
*
* Grow internal sound stack by allocate_delta amount
*
***************************************************************
*/
static ALboolean reallocate_stack(void)
{
stack_snd_t *new_stack;
if (ALstack)
new_stack = realloc(ALstack, sizeof (stack_snd_t) * (allocated_sounds + allocate_delta));
else
new_stack = malloc(sizeof (stack_snd_t) * (allocate_delta));
if (new_stack)
{
ALsizei clean_stack;
ALstack = new_stack;
memset(&ALstack[allocated_sounds], 0, allocate_delta * sizeof (stack_snd_t));
for (clean_stack = allocated_sounds; clean_stack < allocated_sounds; clean_stack++)
ALstack[clean_stack].ALsource = (ALuint)AL_INVALID;
allocated_sounds += allocate_delta;
return AL_TRUE;
}
return AL_FALSE;
}
/***************************************************************
*
* Destroys source in stack
*
***************************************************************
*/
static ALvoid kill_sound(stack_snd_t *snd)
{
if (alIsSource(snd->ALsource))
alDeleteSources(1,&snd->ALsource);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: alDeleteSources, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
memset(snd,0, sizeof (stack_snd_t));
snd->ALsource = (ALuint)AL_INVALID;
}
/***************************************************************
*
* Returns free (unused) source stack slot
* If none available sound stack will be increased
*
***************************************************************
*/
static ALsizei find_handle(void)
{
ALsizei free_sfx = 0;
stack_snd_t *snd;
for (snd = ALstack; free_sfx < allocated_sounds; snd++, free_sfx++)
{
if (snd->permanent)
continue;
if (snd->ALsource==(ALuint)AL_INVALID)
break;
if (!alIsSource(snd->ALsource))
break;
ALo_GetError();
if (snd->sfx_id == 0)
break;
}
// No suitable resource found so increase sound stack
//DBG_Printf("sfx chan %d\n", free_sfx);
if (free_sfx == allocated_sounds)
{
DBG_Printf("No free or same sfx found so increase stack (currently %d srcs)\n", allocated_sounds);
free_sfx = reallocate_stack() ? free_sfx : (ALsizei)AL_INVALID;
}
return free_sfx;
}
static ALvoid ALSetPan(ALuint sid, INT32 sep)
{
ALfloat facing[3] ={0.0f, 0.0f, 0.0f}; //Alam: bad?
const ALfloat fsep = (ALfloat)sep;
const ALfloat nsep = (ALfloat)NORMAL_SEP;
if (sep)
{
facing[0] = (ALfloat)(fsep/nsep);
facing[2] = 1.0f;
}
alSourcefv(sid, AL_POSITION, facing);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: alSourcefv, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
}
/******************************************************************************
*
* Initialise driver and listener
*
*****************************************************************************/
EXPORT INT32 HWRAPI( Startup ) (I_Error_t FatalErrorFunction, snddev_t *snd_dev)
{
ALenum model = AL_INVERSE_DISTANCE_CLAMPED;
ALCboolean inited = ALC_FALSE;
ALCint AlSetup[8] = {ALC_FREQUENCY,22050,ALC_REFRESH,35,ALC_SYNC,AL_FALSE,ALC_INVALID,ALC_INVALID};
#if (defined (_WIN32) || defined (_WIN64)) && 0
const ALCubyte *ALCdriver = alcGetString(NULL,ALC_DEFAULT_DEVICE_SPECIFIER);
const ALCubyte *DSdriver = "DirectSound";
if (!strcmp((const ALCbyte *)ALCdriver,"DirectSound3D")) //Alam: OpenAL's DS3D is buggy
ALCDevice = alcOpenDevice(DSdriver); //Open DirectSound
else //Alam: The OpenAl device
ALCDevice = alcOpenDevice(ALCdriver); //Open Default
#else
ALCDevice = alcOpenDevice(alcGetString(NULL,ALC_DEFAULT_DEVICE_SPECIFIER));
#endif
if (ALCo_GetError() != ALC_NO_ERROR || !ALCDevice)
{
DBG_Printf("S_OpenAl: Error %s when opening device!\n", GetALCErrorString(ALCo_Lasterror));
return inited;
}
else
{
DBG_Printf("Driver Name : %s\n", alcGetString(ALCDevice,ALC_DEVICE_SPECIFIER));
DBG_Printf("Extensions : %s\n", alcGetString(ALCDevice,ALC_EXTENSIONS));
DBG_Printf("S_OpenAl: OpenAl Device %s opened\n",alcGetString(ALCDevice, ALC_DEVICE_SPECIFIER));
}
I_ErrorOpenAl = FatalErrorFunction;
AlSetup[1] = snd_dev->sample_rate; //ALC_FREQUENCY
AlSetup[1] = 44100;
AlSetup[3] = 35; //ALC_REFRESH
//Alam: The Environment?
ALContext = alcCreateContext(ALCDevice,AlSetup);
if (ALCo_GetError() != ALC_NO_ERROR || !ALContext)
{
DBG_Printf("S_OpenAl: Error %s when making the environment!\n",GetALCErrorString(ALCo_Lasterror));
return inited;
}
else
{
DBG_Printf("S_OpenAl: OpenAl environment made\n");
}
alcMakeContextCurrent(ALContext);
if (ALCo_GetError() != ALC_NO_ERROR)
{
DBG_Printf("S_OpenAl: Error %s when setting the environment!\n",GetALCErrorString(ALCo_Lasterror));
return inited;
}
else
{
DBG_Printf("S_OpenAl: OpenAl environment setted up\n");
}
DBG_Printf("Vendor : %s\n", alGetString(AL_VENDOR));
DBG_Printf("Renderer : %s\n", alGetString(AL_RENDERER));
DBG_Printf("Version : %s\n", alGetString(AL_VERSION));
DBG_Printf("Extensions : %s\n", alGetString(AL_EXTENSIONS));
alDopplerFactor(0.0f);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("S_OpenAl: Error %s when setting Doppler Factor!\n",GetALErrorString(ALo_Lasterror));
return inited;
}
else
{
DBG_Printf("S_OpenAl: Doppler Factor of %f setted\n", alGetDouble(AL_DOPPLER_FACTOR));
}
alSpeedOfSound(600.0f);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("S_OpenAl: Error %s when setting Speed of Sound!\n",GetALErrorString(ALo_Lasterror));
return inited;
}
else
{
DBG_Printf("S_OpenAl: Speed of Sound set to %f\n", alGetDouble(AL_SPEED_OF_SOUND));
}
alDistanceModel(model);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("S_OpenAl: Error %s when setting Distance Model!\n",GetALErrorString(ALo_Lasterror));
return inited;
}
else
{
//DBG_Printf("S_OpenAl: %s mode setted\n",alGetString(model));
}
inited = reallocate_stack();
return inited;
}
/******************************************************************************
*
* Shutdown 3D Sound
*
******************************************************************************/
EXPORT void HWRAPI( Shutdown ) ( void )
{
ALsizei i;
DBG_Printf ("S_OpenAL Shutdown()\n");
for (i = 0; i < allocated_sounds; i++)
{
StopSource(i);
kill_sound(ALstack + i);
}
#if defined(linux) || defined(__linux) || defined(__linux__)
alcMakeContextCurrent(NULL);
//TODO:check?
#endif
if (ALContext)
{
alcDestroyContext(ALContext);
ALContext = NULL;
}
if (ALstack)
{
free(ALstack);
ALstack = NULL;
}
//TODO:check?
if (ALCDevice)
{
alcCloseDevice(ALCDevice);
ALCDevice = NULL;
}
//TODO:check?
}
#ifdef _MSC_VER
#pragma warning(disable : 4200)
#pragma pack(1)
#endif
typedef struct
{
ALushort header; // 3?
ALushort samplerate; // 11025+
ALushort samples; // number of samples
ALushort dummy; // 0
ALubyte data[0]; // data;
} ATTRPACK dssfx_t;
#ifdef _MSC_VER
#pragma pack()
#pragma warning(default : 4200)
#endif
static ALsizei getfreq(ALvoid *sfxdata, size_t len)
{
dssfx_t *dsfx = sfxdata;
const ALsizei freq = SHORT(dsfx->samplerate);
if (len <= 8)
return 0;
else
return freq;
}
static ALsizei makechan(ALuint sfxhandle, ALboolean perm)
{
ALsizei chan = find_handle();
if (chan == (ALsizei)AL_INVALID) return chan;
alGenSources(1, &ALstack[chan].ALsource);
if (ALo_GetError() != AL_NO_ERROR || !alIsSource(ALstack[chan].ALsource))
{
DBG_Printf("S_OpenAl: Error %s when make an ALSource!\n",GetALErrorString(ALo_Lasterror));
ALstack[chan].ALsource = (ALuint)AL_INVALID;
return (ALsizei)AL_INVALID;
}
ALstack[chan].permanent = perm;
alSourceQueueBuffers(ALstack[chan].ALsource, 1, &sfxhandle);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("S_OpenAl: Error %s when queue up an alSource!\n",GetALErrorString(ALo_Lasterror));
}
return chan;
}
/******************************************************************************
*
* Creates ?D source
*
******************************************************************************/
EXPORT INT32 HWRAPI ( AddSource ) (source3D_data_t *src, u_int sfxhandle)
{
ALsizei chan = makechan(sfxhandle, (ALboolean)(src?src->permanent:AL_FALSE));
ALuint sid = (ALuint)AL_INVALID;
if (chan == (ALsizei)AL_INVALID)
return AL_INVALID;
else
sid = ALstack[chan].ALsource;
if (src) //3D
{
#if 0
alSourcef(sid, AL_REFERENCE_DISTANCE, src->min_distance);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: AL_REFERENCE_DISTANCE, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
alSourcef(sid, AL_MAX_DISTANCE, src->max_distance);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: AL_MAX_DISTANCE, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
#endif
if (src->head_relative)
alSourcei(sid, AL_SOURCE_RELATIVE, AL_TRUE);
else
alSourcei(sid, AL_SOURCE_RELATIVE, AL_FALSE);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: AL_SOURCE_RELATIVE, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
alSource3f(sid, AL_POSITION, src->pos.x, src->pos.z, src->pos.y);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: AL_POSITION, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
alSource3f(sid, AL_VELOCITY, src->pos.momx, src->pos.momz, src->pos.momy);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: AL_VELOCITY, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
}
else //2D
{
alSourcei(sid, AL_SOURCE_RELATIVE, AL_TRUE);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: AL_SOURCE_RELATIVE, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
}
alSourcef(sid, AL_ROLLOFF_FACTOR, 0.0f);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: AL_ROLLOFF_FACTOR, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
alSourcef(sid, AL_REFERENCE_DISTANCE, 0.0f);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: AL_REFERENCE_DISTANC, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
return chan;
}
EXPORT INT32 HWRAPI ( StartSource ) (INT32 chan)
{
ALint state = AL_NONE;
ALuint sid = (ALuint)AL_INVALID;
if (chan <= AL_INVALID || !alIsSource(ALstack[chan].ALsource))
return AL_FALSE;
else
sid = ALstack[chan].ALsource;
ALo_GetError();
alSourcePlay(sid);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: alSourcePlay, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
alGetSourcei(sid, AL_SOURCE_STATE, &state);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: alGetSourcei, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
return (state == AL_PLAYING);
}
EXPORT void HWRAPI ( StopSource) (INT32 chan)
{
ALuint sfxhandle = AL_NONE;
ALuint sid = (ALuint)AL_INVALID;
if (chan <= AL_INVALID || !alIsSource(ALstack[chan].ALsource))
return;
else
sid = ALstack[chan].ALsource;
ALo_GetError();
#if 1
alSourceQueueBuffers(sid, 1, &sfxhandle);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: alSourceQueueBuffers, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
#else
alSourceStop(sid);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: alSourceStop, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
#endif
}
EXPORT INT32 HWRAPI ( GetHW3DSVersion) (void)
{
return VERSION;
}
EXPORT void HWRAPI (BeginFrameUpdate) (void)
{
alcSuspendContext(ALContext);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: alcSuspendContext, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
}
EXPORT void HWRAPI (EndFrameUpdate) (void)
{
alcProcessContext(ALContext);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: alcProcessContext, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
}
EXPORT INT32 HWRAPI (IsPlaying) (INT32 chan)
{
ALint state = AL_NONE;
ALuint sid = (ALuint)AL_INVALID;
if (chan <= AL_INVALID || !alIsSource(ALstack[chan].ALsource))
return AL_FALSE;
else
sid = ALstack[chan].ALsource;
ALo_GetError();
alGetSourcei(sid, AL_SOURCE_STATE, &state);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: alGetSourcei, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
return (state == AL_PLAYING);
}
/******************************************************************************
* UpdateListener
*
* Set up main listener properties:
* - position
* - orientation
* - velocity
*****************************************************************************/
EXPORT void HWRAPI (UpdateListener) (listener_data_t *data, INT32 num)
{
if (num != 1) return;
if (data)
{
ALfloat facing[6];
ALdouble f_angle = 0.0;
if (data->f_angle) f_angle = (ALdouble)((data->f_angle) / 180.0l * M_PIl);
facing[0] = (ALfloat)cos(f_angle);
facing[1] = 0.0f;
facing[2] = (ALfloat)sin(f_angle);
facing[3] = 0.0f;
facing[4] = 1.0f;
facing[5] = 0.0f;
alListener3f(AL_POSITION,(ALfloat)-data->x,(ALfloat)data->z,(ALfloat)data->y);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: AL_POSITIO, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
alListener3f(AL_VELOCITY,(ALfloat)data->momx,(ALfloat)data->momz,(ALfloat)data->momy);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: AL_VELOCITY, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
alListenerfv(AL_ORIENTATION, facing);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: AL_ORIENTATION, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
}
else
{
DBG_Printf("Error: 1st listener data is missing\n");
}
}
/******************************************************************************
*
* Update volume for 2D source and separation (panning) of 2D source
*
*****************************************************************************/
EXPORT void HWRAPI (UpdateSourceParms) (INT32 chan, INT32 vol, INT32 sep)
{
ALuint sid = AL_NONE;
ALint is2d = AL_FALSE;
if (chan > AL_INVALID && !alIsSource(ALstack[chan].ALsource))
return;
else
sid = ALstack[chan].ALsource;
alGetSourcei(sid, AL_SOURCE_RELATIVE, &is2d);
if (!is2d)
return;
if (vol != -1)
{
alSourcef(sid,AL_GAIN,ALvol(vol,256));
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: alSourcef, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
}
if (sep != -1)
{
ALSetPan(sid,sep-NORMAL_SEP);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: ALSetPan, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
}
}
// --------------------------------------------------------------------------
// Set the global volume for sound effects
// --------------------------------------------------------------------------
EXPORT void HWRAPI (SetGlobalSfxVolume) (INT32 vol)
{
alListenerf(AL_GAIN, ALvol(vol,32));
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: AL_GAIN, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
}
//Alam: Not Used?
EXPORT INT32 HWRAPI (SetCone) (INT32 chan, cone_def_t *cone_def)
{
ALuint sid = AL_NONE;
ALint is2d = AL_FALSE;
if (chan > AL_INVALID && !alIsSource(ALstack[chan].ALsource))
return AL_FALSE;
else
sid = ALstack[chan].ALsource;
alGetSourcei(sid, AL_SOURCE_RELATIVE, &is2d);
if(is2d || !cone_def)
return AL_FALSE;
alSourcef(sid,AL_CONE_INNER_ANGLE,cone_def->inner);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: AL_CONE_INNER_ANGLE, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
alSourcef(sid,AL_CONE_OUTER_ANGLE,cone_def->outer);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: AL_CONE_OUTER_ANGL, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
alSourcei(sid,AL_CONE_OUTER_GAIN, cone_def->outer_gain);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: AL_CONE_OUTER_GAIN, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
return AL_TRUE;
}
EXPORT void HWRAPI (Update3DSource) (INT32 chan, source3D_pos_t *sfx)
{
ALuint sid = AL_NONE;
ALint is2d = AL_FALSE;
if (chan > AL_INVALID && !alIsSource(ALstack[chan].ALsource))
return;
else
sid = ALstack[chan].ALsource;
alGetSourcei(sid, AL_SOURCE_RELATIVE, &is2d);
if (is2d)
return;
alSource3f(sid, AL_POSITION, sfx->x, sfx->z, sfx->y);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: AL_POSITION, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
alSource3f(sid, AL_VELOCITY, sfx->momx, sfx->momz, sfx->momy);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("%s: AL_VELOCITY, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
}
//-------------------------------------------------------------
// Load new sound data into source
//-------------------------------------------------------------
EXPORT INT32 HWRAPI (ReloadSource) (INT32 chan, u_int sfxhandle)
{
ALuint sid;
if (chan <= AL_INVALID || !alIsSource(ALstack[chan].ALsource) || !alIsBuffer(sfxhandle))
return AL_INVALID;
else
sid = ALstack[chan].ALsource;
ALo_GetError();
alSourceQueueBuffers(sid, 1, &sfxhandle);
if (ALo_GetError() == AL_INVALID_OPERATION) //Alam: not needed?
{
alSourceStop(sid);
alSourcei(sid, AL_BUFFER, sfxhandle);
ALo_GetError();
}
if (ALo_Lasterror != AL_NO_ERROR)
{
DBG_Printf("%s: alSourcei, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
return chan;
}
/******************************************************************************
*
* Destroy source and remove it from stack if it is a 2D source.
* Otherwise put source into cache
*
*****************************************************************************/
EXPORT void HWRAPI (KillSource) (INT32 chan)
{
if (chan > AL_INVALID && (ALsizei)chan <= allocated_sounds)
kill_sound(ALstack + chan);
}
EXPORT u_int HWRAPI (AddSfx) (sfx_data_t *sfx)
{
ALuint chan = (ALuint)AL_INVALID;
ALsizei freq = 11025;
ALubyte *data = NULL;
ALsizei size = 0;
if (!sfx)
return 0;
else
{
data = ((ALubyte *)sfx->data)+8;
size = (ALsizei)(sfx->length-8);
}
alGenBuffers(1, &chan);
if (ALo_GetError() != AL_NO_ERROR || !alIsBuffer(chan))
{
DBG_Printf("S_OpenAl: Error %s when make an ALBuffer!\n",GetALErrorString(ALo_Lasterror));
return (u_int)AL_INVALID;
}
freq = getfreq(sfx->data, sfx->length);
alBufferData(chan, AL_FORMAT_MONO8, data, size, freq);
if (ALo_GetError() != AL_NO_ERROR)
{
DBG_Printf("S_OpenAl: Error %s when setting up a alBuffer!\n",GetALErrorString(ALo_Lasterror));
}
return chan;
}
EXPORT void HWRAPI (KillSfx) (u_int sfxhandle)
{
ALuint ALsfx = sfxhandle;
if (!alIsBuffer(ALsfx))
return;
alDeleteBuffers(1, &ALsfx);
if (ALo_GetError() == AL_INVALID_OPERATION)
{
// Buffer leak
}
else if (ALo_Lasterror != AL_NO_ERROR)
{
DBG_Printf("%s: alDeleteBuffers, %s", __FUNCTION__, GetALErrorString(ALo_Lasterror));
}
}
EXPORT void HWRAPI (GetHW3DSTitle) (char *buf, size_t size)
{
strncpy(buf, "OpenAL", size);
}
#ifdef _WINDOWS
BOOL WINAPI DllMain(HINSTANCE hinstDLL, // handle to DLL module
DWORD fdwReason, // reason for calling function
LPVOID lpvReserved) // reserved
{
// Perform actions based on the reason for calling.
UNREFERENCED_PARAMETER(lpvReserved);
switch ( fdwReason )
{
case DLL_PROCESS_ATTACH:
// Initialize once for each new process.
// Return FALSE to fail DLL load.
#ifdef DEBUG_TO_FILE
logstream = fopen("s_openal.log", "wt");
if (logstream == NULL)
return FALSE;
#endif
DisableThreadLibraryCalls(hinstDLL);
break;
case DLL_THREAD_ATTACH:
// Do thread-specific initialization.
break;
case DLL_THREAD_DETACH:
// Do thread-specific cleanup.
break;
case DLL_PROCESS_DETACH:
// Perform any necessary cleanup.
#ifdef DEBUG_TO_FILE
if ( logstream)
{
fclose(logstream);
logstream = NULL;
}
#endif
break;
}
return TRUE; // Successful DLL_PROCESS_ATTACH.
}
#elif !defined (_WINDOWS)
// **************************************************************************
// FUNCTIONS
// **************************************************************************
EXPORT void _init()
{
#ifdef DEBUG_TO_FILE
logstream = fopen("s_openal.log", "w+");
#endif
}
EXPORT void _fini()
{
#ifdef DEBUG_TO_FILE
if (logstream)
fclose(logstream);
logstream = NULL;
#endif
}
#endif
+59
View File
@@ -0,0 +1,59 @@
[Project]
FileName=s_openal.dev
Name=s_openal
Ver=1
IsCpp=1
Type=3
Compiler=-D_M_IX86=500_@@_-Wall_@@_-fexceptions_@@_-D_WINDOWS_@@_
CppCompiler=
Includes=
Linker=--def ../s_mingw.def_@@_-lopenal32_@@_
Libs=
UnitCount=1
Folders=
ObjFiles=
PrivateResource=
ResourceIncludes=
MakeIncludes=
Icon=
ExeOutput=..\..\..\bin
ObjectOutput=..\..\..\objs\Mingw\s_opengl
OverrideOutput=0
OverrideOutputName=s_openal.dll
HostApplication=
CommandLine=
UseCustomMakefile=0
CustomMakefile=
IncludeVersionInfo=0
SupportXPThemes=0
CompilerSet=0
CompilerSettings=0000000010001001001001
[Unit1]
FileName=s_openal.c
Folder=
Compile=1
CompileCpp=0
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[VersionInfo]
Major=0
Minor=1
Release=1
Build=1
LanguageID=1033
CharsetID=1252
CompanyName=
FileVersion=0.1
FileDescription=Developed using the Dev-C++ IDE
InternalName=
LegalCopyright=
LegalTrademarks=
OriginalFilename=s_openal.dll
ProductName=s_openal
ProductVersion=0.1
AutoIncBuildNr=0
+98
View File
@@ -0,0 +1,98 @@
# Microsoft Developer Studio Project File - Name="s_openal" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=s_openal - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "s_openal.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "s_openal.mak" CFG="s_openal - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "s_openal - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "s_openal - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "s_openal - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "..\..\..\bin\VC\Release\s_openal"
# PROP Intermediate_Dir "..\..\..\objs\VC\Release\s_openal"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "S_OPENAL_EXPORTS" /YX /FD /c
# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "__WIN32__" /D "__MSC__" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /win32
# SUBTRACT MTL /mktyplib203
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
# ADD LINK32 OpenAL32.lib /nologo /dll /pdb:"..\..\..\bin\VC\Release\s_openal.pdb" /machine:I386 /out:"C:\srb2demo2\s_openal.dll"
# SUBTRACT LINK32 /pdb:none
!ELSEIF "$(CFG)" == "s_openal - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "..\..\..\bin\VC\Debug\s_openal"
# PROP Intermediate_Dir "..\..\..\objs\VC\Debug\s_openal"
# PROP Ignore_Export_Lib 1
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "S_OPENAL_EXPORTS" /YX /FD /GZ /c
# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "__WIN32__" /D "__MSC__" /D "_MBCS" /D "_USRDLL" /D "S_OPENAL_EXPORTS" /YX /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 OpenAL32.lib /nologo /dll /pdb:"..\..\..\bin\VC\Debug\s_openal.pdb" /debug /machine:I386 /out:"C:\srb2demo2\s_openaldebug.dll" /pdbtype:sept
# SUBTRACT LINK32 /pdb:none
!ENDIF
# Begin Target
# Name "s_openal - Win32 Release"
# Name "s_openal - Win32 Debug"
# Begin Source File
SOURCE=.\s_openal.c
# End Source File
# End Target
# End Project
+18 -18
View File
@@ -289,7 +289,7 @@ int
HMS_register (void)
{
struct HMS_buffer *hms;
int okay;
int ok;
char post[256];
@@ -316,23 +316,23 @@ HMS_register (void)
curl_easy_setopt(hms->curl, CURLOPT_POSTFIELDS, post);
okay = HMS_do(hms);
ok = HMS_do(hms);
if (okay)
if (ok)
{
hms_server_token = strdup(strtok(hms->buffer, "\n"));
}
HMS_end(hms);
return okay;
return ok;
}
int
HMS_unlist (void)
{
struct HMS_buffer *hms;
int okay;
int ok;
hms = HMS_connect("servers/%s/unlist", hms_server_token);
@@ -342,19 +342,19 @@ HMS_unlist (void)
curl_easy_setopt(hms->curl, CURLOPT_POST, 1);
curl_easy_setopt(hms->curl, CURLOPT_POSTFIELDSIZE, 0);
okay = HMS_do(hms);
ok = HMS_do(hms);
HMS_end(hms);
free(hms_server_token);
return okay;
return ok;
}
int
HMS_update (void)
{
struct HMS_buffer *hms;
int okay;
int ok;
char post[256];
@@ -376,10 +376,10 @@ HMS_update (void)
curl_easy_setopt(hms->curl, CURLOPT_POSTFIELDS, post);
okay = HMS_do(hms);
ok = HMS_do(hms);
HMS_end(hms);
return okay;
return ok;
}
void
@@ -488,7 +488,7 @@ int
HMS_compare_mod_version (char *buffer, size_t buffer_size)
{
struct HMS_buffer *hms;
int okay;
int ok;
char *version;
char *version_name;
@@ -498,7 +498,7 @@ HMS_compare_mod_version (char *buffer, size_t buffer_size)
if (! hms)
return 0;
okay = 0;
ok = 0;
if (HMS_do(hms))
{
@@ -510,16 +510,16 @@ HMS_compare_mod_version (char *buffer, size_t buffer_size)
if (atoi(version) != MODVERSION)
{
strlcpy(buffer, version_name, buffer_size);
okay = 1;
ok = 1;
}
else
okay = -1;
ok = -1;
}
}
HMS_end(hms);
return okay;
return ok;
}
const char *
@@ -532,9 +532,9 @@ HMS_fetch_rules (char *buffer, size_t buffer_size)
if (! hms)
return NULL;
boolean okay = HMS_do(hms);
boolean ok = HMS_do(hms);
if (okay)
if (ok)
{
char *p = strstr(hms->buffer, "\n\n");
@@ -552,7 +552,7 @@ HMS_fetch_rules (char *buffer, size_t buffer_size)
HMS_end(hms);
if (!okay)
if (!ok)
return NULL;
return buffer;
+222 -216
View File
@@ -26,7 +26,6 @@
#include "i_video.h"
#include "i_system.h"
#include "r_fps.h"
#include "st_stuff.h" // ST_HEIGHT
#include "r_local.h"
@@ -70,6 +69,7 @@ patch_t *hu_font[HU_FONTSIZE];
patch_t *kart_font[KART_FONTSIZE]; // SRB2kart
patch_t *tny_font[HU_FONTSIZE];
patch_t *tallnum[10]; // 0-9
patch_t *nightsnum[10]; // 0-9
// Level title and credits fonts
patch_t *lt_font[LT_FONTSIZE];
@@ -100,8 +100,24 @@ patch_t *rflagico;
patch_t *bflagico;
patch_t *rmatcico;
patch_t *bmatcico;
patch_t *tagico;
patch_t *tallminus;
//-------------------------------------------
// coop hud
//-------------------------------------------
patch_t *emeraldpics[7];
patch_t *tinyemeraldpics[7];
static patch_t *emblemicon;
static patch_t *tokenicon;
//-------------------------------------------
// misc vars
//-------------------------------------------
// crosshair 0 = off, 1 = cross, 2 = angle, 3 = point, see m_menu.c
static patch_t *crosshair[HU_CROSSHAIRS]; // 3 precached crosshair graphics
// song credits
static patch_t *songcreditbg;
@@ -169,7 +185,7 @@ char french_shiftxform[] =
31,
' ','$', //shift-!
'3', //shift-"
'#', '$', '%',
'#', '$', '%',
'1', //shift-&
'4', // shift-'
'5', // shift-(
@@ -179,7 +195,7 @@ char french_shiftxform[] =
'6', // shift--
'.', '/',
'0', '1', '2', '3', '4', '5',
'6', '7', '8', '9',
'6', '7', '8', '9',
'/', // shitf-:
'.', // shift-;
'>', // shift-<
@@ -222,7 +238,7 @@ char french_altgrxform[] =
'|', //altg--
'.', '/',
'0', '1', '2', '3', '4', '5',
'6', '7', '8', '9',
'6', '7', '8', '9',
':', ';', '<',
'}', //altgr-=
'>', '?', '@',
@@ -259,6 +275,8 @@ INT32 HU_FallBackFrSpecialLetter(INT32 key)
}
}
static char cechotext[1024];
static tic_t cechotimer = 0;
static tic_t cechoduration = 5*TICRATE;
@@ -363,6 +381,8 @@ void HU_LoadGraphics(void)
{
sprintf(buffer, "STTNUM%d", i);
tallnum[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
sprintf(buffer, "NGTNUM%d", i);
nightsnum[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX);
sprintf(buffer, "PINGN%d", i);
pingnum[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX);
sprintf(buffer, "OPPRNK0%d", i);
@@ -372,6 +392,32 @@ void HU_LoadGraphics(void)
// minus for negative tallnums
tallminus = (patch_t *)W_CachePatchName("STTMINUS", PU_HUDGFX);
// cache the crosshairs, don't bother to know which one is being used,
// just cache all 3, they're so small anyway.
for (i = 0; i < HU_CROSSHAIRS; i++)
{
sprintf(buffer, "CROSHAI%c", '1'+i);
crosshair[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
}
emblemicon = W_CachePatchName("EMBLICON", PU_HUDGFX);
tokenicon = W_CachePatchName("TOKNICON", PU_HUDGFX);
emeraldpics[0] = W_CachePatchName("CHAOS1", PU_HUDGFX);
emeraldpics[1] = W_CachePatchName("CHAOS2", PU_HUDGFX);
emeraldpics[2] = W_CachePatchName("CHAOS3", PU_HUDGFX);
emeraldpics[3] = W_CachePatchName("CHAOS4", PU_HUDGFX);
emeraldpics[4] = W_CachePatchName("CHAOS5", PU_HUDGFX);
emeraldpics[5] = W_CachePatchName("CHAOS6", PU_HUDGFX);
emeraldpics[6] = W_CachePatchName("CHAOS7", PU_HUDGFX);
tinyemeraldpics[0] = W_CachePatchName("TEMER1", PU_HUDGFX);
tinyemeraldpics[1] = W_CachePatchName("TEMER2", PU_HUDGFX);
tinyemeraldpics[2] = W_CachePatchName("TEMER3", PU_HUDGFX);
tinyemeraldpics[3] = W_CachePatchName("TEMER4", PU_HUDGFX);
tinyemeraldpics[4] = W_CachePatchName("TEMER5", PU_HUDGFX);
tinyemeraldpics[5] = W_CachePatchName("TEMER6", PU_HUDGFX);
tinyemeraldpics[6] = W_CachePatchName("TEMER7", PU_HUDGFX);
songcreditbg = W_CachePatchName("K_SONGCR", PU_HUDGFX);
// cache ping gfx:
@@ -912,9 +958,12 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
player_names[playernum]);
if (server)
{
SendKick(playernum, KICK_MSG_CON_FAIL);
}
UINT8 buf[2];
buf[0] = (UINT8)playernum;
buf[1] = KICK_MSG_CON_FAIL;
SendNetXCmd(XD_KICK, &buf, 2);
}
return;
}
@@ -929,7 +978,11 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
CONS_Alert(CONS_WARNING, M_GetText("Illegal say command received from %s containing invalid characters\n"), player_names[playernum]);
if (server)
{
SendKick(playernum, KICK_MSG_CON_FAIL);
char buf[2];
buf[0] = (char)playernum;
buf[1] = KICK_MSG_CON_FAIL;
SendNetXCmd(XD_KICK, &buf, 2);
}
return;
}
@@ -950,7 +1003,7 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
// run the lua hook even if we were supposed to eat the msg, netgame consistency goes first.
if (LUA_HookPlayerMsg(playernum, target, flags, msg, spam_eatmsg))
if (LUAh_PlayerMsg(playernum, target, flags, msg, spam_eatmsg))
return;
if (spam_eatmsg)
@@ -1138,14 +1191,14 @@ void HU_Ticker(void)
}
if (cechotimer > 0) --cechotimer;
// Animate the desynch dots
if (hu_resynching
#ifdef SATURNPAK
#ifdef SATURNSYNCH
|| hu_redownloadinggamestate
#endif
)
resynch_ticker++; //tic tic tic tic tic
resynch_ticker++; //tic tic tic tic tic
HU_TickSongCredits();
}
@@ -1313,7 +1366,7 @@ boolean HU_Responder(event_t *ev)
INT32 i;
for (i = 0; i < num_gamecontrols; i++)
{
if (gamecontrol[0][i][0] == ev->data1 || gamecontrol[0][i][1] == ev->data1)
if (gamecontrol[i][0] == ev->data1 || gamecontrol[i][1] == ev->data1)
break;
}
@@ -1325,7 +1378,7 @@ boolean HU_Responder(event_t *ev)
if (!chat_on)
{
// enter chat mode
if ((ev->data1 == gamecontrol[0][gc_talkkey][0] || ev->data1 == gamecontrol[0][gc_talkkey][1])
if ((ev->data1 == gamecontrol[gc_talkkey][0] || ev->data1 == gamecontrol[gc_talkkey][1])
&& netgame && !OLD_MUTE) // check for old chat mute, still let the players open the chat incase they want to scroll otherwise.
{
chat_on = true;
@@ -1336,7 +1389,7 @@ boolean HU_Responder(event_t *ev)
typelines = 1;
return true;
}
if ((ev->data1 == gamecontrol[0][gc_teamkey][0] || ev->data1 == gamecontrol[0][gc_teamkey][1])
if ((ev->data1 == gamecontrol[gc_teamkey][0] || ev->data1 == gamecontrol[gc_teamkey][1])
&& netgame && !OLD_MUTE)
{
chat_on = true;
@@ -1362,8 +1415,8 @@ boolean HU_Responder(event_t *ev)
// Ignore non-keyboard keys, except when the talk key is bound
if (ev->data1 >= KEY_MOUSE1
&& (ev->data1 != gamecontrol[0][gc_talkkey][0]
&& ev->data1 != gamecontrol[0][gc_talkkey][1]))
&& (ev->data1 != gamecontrol[gc_talkkey][0]
&& ev->data1 != gamecontrol[gc_talkkey][1]))
return false;
M_TextInputHandle(&w_chat, c);
@@ -1375,8 +1428,8 @@ boolean HU_Responder(event_t *ev)
HU_SendChatMessage();
}
else if (c == KEY_ESCAPE
|| ((c == gamecontrol[0][gc_talkkey][0] || c == gamecontrol[0][gc_talkkey][1]
|| c == gamecontrol[0][gc_teamkey][0] || c == gamecontrol[0][gc_teamkey][1])
|| ((c == gamecontrol[gc_talkkey][0] || c == gamecontrol[gc_talkkey][1]
|| c == gamecontrol[gc_teamkey][0] || c == gamecontrol[gc_teamkey][1])
&& c >= KEY_MOUSE1)) // If it's not a keyboard key, then the chat button is used as a toggle.
{
chat_on = false;
@@ -1859,8 +1912,7 @@ static void HU_DrawChat(void)
if (strnicmp(w_chat_buf, "/pm", 3) == 0 && vid.width >= 400 && !teamtalk) // 320x200 unsupported kthxbai
{
INT32 count = 0;
INT32 p_dispy = chaty - charheight - 1;
size_t longest_name_length = 0;
INT32 p_dispy = chaty - charheight -1;
#ifdef NETSPLITSCREEN
if (splitscreen)
{
@@ -1872,33 +1924,27 @@ static void HU_DrawChat(void)
#endif
p_dispy -= (cv_kartspeedometer.value ? 16 : 0);
// Find longest player name, for drawing background for /pm list later
for (i = 0; i < MAXPLAYERS; i++)
i = 0;
for(i=0; (i<MAXPLAYERS); i++)
{
if (!playeringame[i]) continue;
longest_name_length = max(longest_name_length, strlen(player_names[i]));
}
for(i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i])
continue;
// filter: (code needs optimization pls help I'm bad with C)
if (w_chat_buf[3])
{
char nodenum[3];
char *nodenum;
UINT32 n;
// right, that's half important: (w_chat_buf[4] may be a space since /pm0 msg is perfectly acceptable!)
if (!isdigit(w_chat_buf[3]) || !(isdigit(w_chat_buf[4]) || (w_chat_buf[4] == ' ') || (w_chat_buf[4] == 0)))
if ( ( ((w_chat_buf[3] != 0) && ((w_chat_buf[3] < '0') || (w_chat_buf[3] > '9'))) || ((w_chat_buf[4] != 0) && (((w_chat_buf[4] < '0') || (w_chat_buf[4] > '9'))))) && (w_chat_buf[4] != ' '))
break;
nodenum = (char*) malloc(3);
memcpy(nodenum, w_chat_buf+3, 2);
nodenum[2] = '\0';
n = atoi(nodenum); // turn that into a number
n = atoi((const char*) nodenum); // turn that into a number
free(nodenum);
// special cases:
if ((n == 0) && !(w_chat_buf[4] == '0'))
{
if (!(i<10))
@@ -1926,20 +1972,23 @@ static void HU_DrawChat(void)
}
}
// fill it like the chat so the text doesn't become hard to read because of the hud.
V_DrawFillConsoleMap(chatx + boxw + 2, p_dispy - (6*count), (longest_name_length+4)*4, 6, 239 | V_SNAPTOBOTTOM | V_SNAPTOLEFT);
V_DrawSmallString(chatx + boxw + 4, p_dispy - (6*count), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, va("\x82%d\x80 - %s", i, player_names[i]));
count++;
if (playeringame[i])
{
char name[MAXPLAYERNAME+1];
strlcpy(name, player_names[i], 7); // shorten name to 7 characters.
V_DrawFillConsoleMap(chatx+ boxw + 2, p_dispy- (6*count), 48, 6, 239 | V_SNAPTOBOTTOM | V_SNAPTOLEFT); // fill it like the chat so the text doesn't become hard to read because of the hud.
V_DrawSmallString(chatx+ boxw + 4, p_dispy- (6*count), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, va("\x82%d\x80 - %s", i, name));
count++;
}
}
if (count == 0) // no results.
{
V_DrawFillConsoleMap(chatx + boxw + 2, p_dispy - (6*count), 48, 6, 239 | V_SNAPTOBOTTOM | V_SNAPTOLEFT); // fill it like the chat so the text doesn't become hard to read because of the hud.
V_DrawSmallString(chatx + boxw + 4, p_dispy - (6*count), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, "NO RESULT.");
V_DrawFillConsoleMap(chatx+boxw+2, p_dispy- (6*count), 48, 6, 239 | V_SNAPTOBOTTOM | V_SNAPTOLEFT); // fill it like the chat so the text doesn't become hard to read because of the hud.
V_DrawSmallString(chatx+boxw+4, p_dispy- (6*count), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, "NO RESULT.");
}
}
HU_drawChatLog(typelines - 1); // typelines is the # of lines we're typing. If there's more than 1 then the log should scroll up to give us more space.
HU_drawChatLog(typelines-1); // typelines is the # of lines we're typing. If there's more than 1 then the log should scroll up to give us more space.
}
@@ -1951,11 +2000,17 @@ static void HU_DrawChat_Old(void)
const char *ntalk = "Say: ", *ttalk = "Say-Team: ";
const char *talk = ntalk;
size_t select_start = 0, select_end = 0;
INT32 charwidth = 8 * con_scalefactor; //hu_font['A'-HU_FONTSTART]->width * con_scalefactor;
INT32 charheight = 8 * con_scalefactor; //hu_font['A'-HU_FONTSTART]->height * con_scalefactor;
INT32 charwidth = 8 * con_scalefactor; //SHORT(hu_font['A'-HU_FONTSTART]->width) * con_scalefactor;
INT32 charheight = 8 * con_scalefactor; //SHORT(hu_font['A'-HU_FONTSTART]->height) * con_scalefactor;
if (teamtalk)
{
talk = ttalk;
#if 0
if (players[consoleplayer].ctfteam == 1)
t = 0x500; // Red
else if (players[consoleplayer].ctfteam == 2)
t = 0x400; // Blue
#endif
}
while (talk[i])
@@ -1967,7 +2022,7 @@ static void HU_DrawChat_Old(void)
}
else
{
//charwidth = hu_font[talk[i]-HU_FONTSTART]->width * con_scalefactor;
//charwidth = SHORT(hu_font[talk[i]-HU_FONTSTART]->width) * con_scalefactor;
V_DrawCharacter(HU_INPUTX + c, y, talk[i++] | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value);
}
c += charwidth;
@@ -1995,7 +2050,7 @@ static void HU_DrawChat_Old(void)
//Hurdler: isn't it better like that?
if (w_chat_buf[i] >= HU_FONTSTART)
{
//charwidth = hu_font[w_chat[i]-HU_FONTSTART]->width * con_scalefactor;
//charwidth = SHORT(hu_font[w_chat[i]-HU_FONTSTART]->width) * con_scalefactor;
V_DrawCharacter(HU_INPUTX + c, y, w_chat_buf[i] | cv_constextsize.value | V_NOSCALESTART | t, !cv_allcaps.value);
}
@@ -2176,7 +2231,7 @@ void HU_DrawSongCredits(void)
//
void HU_Drawer(void)
{
if (cv_vhseffect.value && ((paused && !camera[R_GetViewNumber()].freecam) || (demo.playback && cv_playbackspeed.value > 1)))
if (cv_vhseffect.value && (paused || (demo.playback && cv_playbackspeed.value > 1)))
V_DrawVhsEffect(demo.rewinding);
#ifndef NONET
@@ -2201,10 +2256,6 @@ void HU_Drawer(void)
if (cechotimer)
HU_DrawCEcho();
// draw song credits
if (cv_songcredits.value)
HU_DrawSongCredits();
if (!( Playing() || demo.playback )
|| gamestate == GS_INTERMISSION || gamestate == GS_CUTSCENE
|| gamestate == GS_CREDITS || gamestate == GS_EVALUATION
@@ -2223,7 +2274,7 @@ void HU_Drawer(void)
if (renderisnewtic)
{
LUA_HUD_ClearDrawList(luahuddrawlist_scores);
LUA_HUDHOOK(scores, luahuddrawlist_scores);
LUAh_ScoresHUD(luahuddrawlist_scores);
}
LUA_HUD_DrawList(luahuddrawlist_scores);
@@ -2238,9 +2289,29 @@ void HU_Drawer(void)
if (gamestate != GS_LEVEL)
return;
// draw the crosshair, not when viewing demos nor with chasecam
/*if (!automapactive && !demo.playback)
{
if (cv_crosshair.value && !camera[0].chase && !players[displayplayers[0]].spectator)
HU_DrawCrosshair();
if (cv_crosshair2.value && !camera[1].chase && !players[displayplayers[1]].spectator)
HU_DrawCrosshair2();
if (cv_crosshair3.value && !camera[2].chase && !players[displayplayers[2]].spectator)
HU_DrawCrosshair3();
if (cv_crosshair4.value && !camera[3].chase && !players[displayplayers[3]].spectator)
HU_DrawCrosshair4();
}*/
// draw song credits
if (cv_songcredits.value)
HU_DrawSongCredits();
// draw desynch text
if (hu_resynching
#ifdef SATURNPAK
#ifdef SATURNSYNCH
|| hu_redownloadinggamestate
#endif
)
@@ -2345,147 +2416,92 @@ Ping_gfx_num (int lag)
return 4;
}
static int
Ping_gfx_color (UINT32 lag)
{
if (lag < 2)
return SKINCOLOR_JAWZ;
else if (lag < 4)
return SKINCOLOR_MINT;
else if (lag < 7)
return SKINCOLOR_GOLD;
else if (lag < 10)
return SKINCOLOR_RED;
else if (lag < servermaxping)
{
if (hu_tick & 2)
return SKINCOLOR_GREEN;
else if (hu_tick & 4)
return SKINCOLOR_YELLOW;
else
return SKINCOLOR_BLUEBERRY;
}
else
return SKINCOLOR_WHITE; // to make the flashing work
}
static const UINT8 *
Ping_gfx_colormap (UINT32 lag, boolean gentleman)
{
const UINT8 *colormap = NULL;
if (K_UseColorHud())
colormap = R_GetTranslationColormap(TC_RAINBOW, Ping_gfx_color(lag), GTC_CACHE);
if (servermaxping && lag > servermaxping && hu_tick < 4)
{
// flash ping red if too high
colormap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_RASPBERRY, GTC_CACHE);
}
else if (gentleman)
{
colormap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_PASTEL, GTC_CACHE);
}
return colormap;
}
static UINT32
Ping_conversion (UINT32 lag)
{
if (cv_pingmeasurement.value)
{
lag = (INT32)(lag * (1000.00f / TICRATE));
}
return lag;
}
//
// HU_drawPing
//
void HU_drawPlayerPing(INT32 x, INT32 y, INT32 pnum, INT32 flags)
void HU_drawPing(INT32 x, INT32 y, UINT32 lag, INT32 flags)
{
UINT8 *colormap = NULL;
INT32 measureid = cv_pingmeasurement.value ? 1 : 0;
INT32 gfxnum; // gfx to draw
//SRB2/Kart v1.0 style
UINT8 numbars = 0; // how many ping bars do we draw?
UINT8 barcolor = 31; // color we use for the bars (green, yellow, red or black)
SINT8 i = 0;
SINT8 yoffset = 6;
//INT32 dx;
UINT32 lag = playerpingtable[pnum];
const boolean gentleman = (cv_mindelay.value && (lag < (tic_t)simulated_lag));
if (gentleman)
gfxnum = Ping_gfx_num(lag);
if (!cv_pingstyle.value)
{
lag = simulated_lag;
}
if (cv_pingstyle.value == 0) // kart
{
gfxnum = Ping_gfx_num(lag);
if (measureid == 1)
V_DrawScaledPatch(x+11 - pingmeasure[measureid]->width, y+9, flags, pingmeasure[measureid]);
if (cv_pingicon.value)
V_DrawScaledPatch(x+2, y, flags, pinggfx[gfxnum]);
x = V_DrawPingNum(x + (measureid == 1 ? 11 - pingmeasure[measureid]->width : 10), y+9, flags, Ping_conversion(lag), Ping_gfx_colormap(lag, gentleman));
if (servermaxping && lag > servermaxping && hu_tick < 4)
colormap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_RASPBERRY, GTC_CACHE); // flash ping red if too high
if (cv_pingmeasurement.value)
lag = (INT32)(lag * (1000.00f / TICRATE));
x = V_DrawPingNum(x + (measureid == 1 ? 11 - pingmeasure[measureid]->width : 10), y+9, flags, lag, colormap);
if (measureid == 0)
V_DrawScaledPatch(x+1 - pingmeasure[measureid]->width, y+9, flags, pingmeasure[measureid]);
V_DrawScaledPatch(x+1 - pingmeasure[measureid]->width, y+9, flags, pingmeasure[measureid]);
}
else if (cv_pingstyle.value == 1) // old style ping
else if (cv_pingstyle.value) // old style ping
{
if (cv_pingicon.value)
{
if (lag < 4)
{
numbars = 3;
barcolor = 184;
}
else if (lag < 7)
{
numbars = 2; // Apparently ternaries w/ multiple statements don't look good in C so I decided against it.
barcolor = 103;
}
else if (lag < 10)
{
numbars = 1;
barcolor = 155; // need a better red
}
else // brazil
{
numbars = 0;
barcolor = 31;
}
}
if (cv_pingmeasurement.value)
lag = (INT32)(lag * (1000.00f / TICRATE));
if (vid.width >= 640) // how sad, we're using a shit resolution.
{
if (measureid == 1)
{
V_DrawRightAlignedSmallString(x+12, y+13, V_ALLOWLOWERCASE|flags, va("%dms", Ping_conversion(lag)));
//dx = x+1 - (V_SmallStringWidth(va("%dms", lag), V_ALLOWLOWERCASE|flags)/2);
//V_DrawSmallString(dx, y+4, V_ALLOWLOWERCASE|flags, va("%dms", lag));
V_DrawRightAlignedSmallString(x+12, y+13, V_ALLOWLOWERCASE|flags, va("%dms", lag));
}
else if (measureid == 0)
{
V_DrawRightAlignedSmallString(x+12, y+13, flags, va("d%d", Ping_conversion(lag)));
//dx = x+1 - (V_SmallStringWidth(va("d%d", lag), flags)/2);
//V_DrawSmallString(dx, y+4, flags, va("d%d", lag));
V_DrawRightAlignedSmallString(x+12, y+13, flags, va("d%d", lag));
}
}
if (cv_pingicon.value)
{
switch (lag)
{
case 0 ... 1:
numbars = 3;
barcolor = 215; // Blue
break;
case 2 ... 3:
numbars = 3;
barcolor = 184; // Green
break;
case 4 ... 6:
numbars = 2; // Apparently ternaries w/ multiple statements don't look good in C so I decided against it.
barcolor = 103; // Yellow
break;
case 7 ... 9:
numbars = 1;
barcolor = 155; // Red
break;
default: // Brazil
numbars = 0;
barcolor = 31; // black
break;
}
if (gentleman)
{
barcolor = 194; // make it purplish
// bars get indirectly set earlier
}
for (i = 0; (i < 3); i++) // Draw the ping bar
{
for (i=0; (i<3); i++) // Draw the ping bar
{
V_DrawFill(x+2 *(i-1)+7, y+8+yoffset-4, 2, 8-yoffset, 31|flags);
if (i < numbars)
@@ -2559,25 +2575,28 @@ static inline void HU_DrawSpectatorTicker(void)
if (cv_showspecstuff.value)
{
player_t *player;
player = &players[i];
if (player->mo && player->mo->color)
if (players[i].mo)
{
const UINT8 *colormap = R_GetTranslationColormap(player->skin, player->mo->color, GTC_CACHE);
if (player->mo->colorized)
colormap = R_GetTranslationColormap(TC_RAINBOW, player->mo->color, GTC_CACHE);
player_t *p;
p = &players[i];
if (K_UseHighResPortraits())
V_DrawSmallMappedPatch((templength - duptweak), height+10, V_TRANSLUCENT, R_GetSkinFaceWant(player), colormap);
else
V_DrawMappedPatch((templength - duptweak), height+10, V_TRANSLUCENT, R_GetSkinFaceRank(player), colormap);
if (players[i].mo->color)
{
const UINT8 *colormap;
if (players[i].mo->colorized)
colormap = R_GetTranslationColormap(TC_RAINBOW, players[i].mo->color, GTC_CACHE);
else
colormap = R_GetTranslationColormap(players[i].skin, players[i].mo->color, GTC_CACHE);
if (cv_highresportrait.value)
V_DrawSmallMappedPatch((templength - duptweak), height+10, V_TRANSLUCENT, R_GetSkinFaceWant(p), colormap);
else
V_DrawMappedPatch((templength - duptweak), height+10, V_TRANSLUCENT, R_GetSkinFaceRank(p), colormap);
}
}
if ((netgame && i != serverplayer) || (cv_mindelay.value && P_IsLocalPlayer(&players[i])))
{
HU_drawPlayerPing((templength - duptweak)+8, height-20, i, V_TRANSLUCENT);
}
if (netgame && i != serverplayer)
HU_drawPing((templength - duptweak)+8, height-20, playerpingtable[i], V_TRANSLUCENT);
}
if ((length += len) >= dupadjust+8)
@@ -2586,6 +2605,7 @@ static inline void HU_DrawSpectatorTicker(void)
}
}
//
// HU_DrawRankings
//
@@ -2595,6 +2615,7 @@ static void HU_DrawRankings(void)
playersort_t tab[MAXPLAYERS];
INT32 i, j, scorelines, hilicol, numplayersingame = 0;
boolean completed[MAXPLAYERS];
UINT32 whiteplayer = MAXPLAYERS;
if (!automapactive)
V_DrawFadeScreen(0xFF00, 16); // A little more readable, and prevents cheating the fades under other circumstances.
@@ -2606,25 +2627,20 @@ static void HU_DrawRankings(void)
else
hilicol = ((gametype == GT_RACE) ? V_SKYMAP : V_REDMAP);
if (!demo.playback)
{
// draw the current map in the lower right
char *maptitle = G_BuildMapTitle(gamemap);
if (maptitle)
{
V_DrawString(4, 188, hilicol|V_SNAPTOBOTTOM|V_SNAPTOLEFT, maptitle);
Z_Free(maptitle);
}
else
{
V_DrawString(4, 188, hilicol|V_SNAPTOBOTTOM|V_SNAPTOLEFT, "UNKNOWN");
}
}
// draw the current gametype in the lower right
//if (modeattacking)
//V_DrawString(4, 188, hilicol|V_SNAPTOBOTTOM|V_SNAPTOLEFT, "Record Attack");
//else
//V_DrawString(4, 188, hilicol|V_SNAPTOBOTTOM|V_SNAPTOLEFT, gametype_cons_t[gametype].strvalue);
// draw the current map in the lower right if theres none just say its unknown
char *maptitle = G_BuildMapTitle(gamemap);
if (!maptitle)
V_DrawString(4, 188, hilicol|V_SNAPTOBOTTOM|V_SNAPTOLEFT, "UNKNOWN");
else
{
// draw the current gametype in the lower right
V_DrawString(4, 188, hilicol|V_SNAPTOBOTTOM|V_SNAPTOLEFT, (modeattacking) ? "Record Attack" : gametype_cons_t[gametype].strvalue);
V_DrawString(4, 188, hilicol|V_SNAPTOBOTTOM|V_SNAPTOLEFT, maptitle);
Z_Free(maptitle);
}
if (G_GametypeHasTeams())
@@ -2634,7 +2650,7 @@ static void HU_DrawRankings(void)
else
p = bmatcico;
V_DrawSmallScaledPatch(128 - p->width/4, 4, 0, p);
V_DrawSmallScaledPatch(128 - SHORT(p->width)/4, 4, 0, p);
V_DrawCenteredString(128, 16, 0, va("%u", bluescore));
if (gametype == GT_CTF)
@@ -2642,7 +2658,7 @@ static void HU_DrawRankings(void)
else
p = rmatcico;
V_DrawSmallScaledPatch(192 - p->width/4, 4, 0, p);
V_DrawSmallScaledPatch(192 - SHORT(p->width)/4, 4, 0, p);
V_DrawCenteredString(192, 16, 0, va("%u", redscore));
}
@@ -2687,6 +2703,11 @@ static void HU_DrawRankings(void)
V_DrawCenteredString(256, 16, hilicol, cv_kartspeed.string);
}
// When you play, you quickly see your score because your name is displayed in white.
// When playing back a demo, you quickly see who's the view.
if (!splitscreen)
whiteplayer = demo.playback ? displayplayers[0] : consoleplayer;
scorelines = 0;
memset(completed, 0, sizeof (completed));
memset(tab, 0, sizeof (playersort_t)*MAXPLAYERS);
@@ -2742,7 +2763,7 @@ static void HU_DrawRankings(void)
#endif
}
HU_DrawTabRankings(((scorelines > 8) ? 32 : 40), 33, tab, scorelines, hilicol);
HU_DrawTabRankings(((scorelines > 8) ? 32 : 40), 33, tab, scorelines, whiteplayer, hilicol);
// draw spectators in a ticker across the bottom
if (netgame && G_GametypeHasSpectators())
@@ -2769,31 +2790,16 @@ void HU_SetCEchoFlags(INT32 flags)
void HU_DoCEcho(const char *msg)
{
if (!cv_cechotoggle.value)
return
I_OutputMsg("%s\n", msg); // print to log
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstringop-truncation" // This is fine, we set null byte later
strncpy(cechotext, msg, sizeof(cechotext));
#pragma GCC diagnostic pop
strncat(cechotext, "\\", sizeof(cechotext) - strlen(cechotext) - 1);
cechotext[sizeof(cechotext) - 1] = '\0';
// just print it to console
if (cv_cechotoggle.value == 2)
{
char temp[1024];
strncpy(temp, cechotext, sizeof(temp));
for (char *p = temp; *p != '\0'; ++p)
if (*p == '\\')
*p = '\n';
CONS_Printf("%s\n", temp);
return;
}
I_OutputMsg("%s\n", msg); // print to log
if (!cv_cechotoggle.value)
return;
cechotimer = cechoduration;
}
+8 -2
View File
@@ -42,6 +42,8 @@
#define CRED_FONTEND 'Z' // the last font character
#define CRED_FONTSIZE (CRED_FONTEND - CRED_FONTSTART + 1)
#define HU_CROSSHAIRS 3 // maximum of 9 - see HU_Init();
extern char *shiftxform; // english translation shift table
extern char english_shiftxform[];
@@ -88,14 +90,18 @@ extern patch_t *tallnum[10];
extern patch_t *pingnum[10];
extern patch_t *pinggfx[5];
extern patch_t *ranknum[10];
extern patch_t *nightsnum[10];
extern patch_t *framecounter;
extern patch_t *frameslash;
extern patch_t *lt_font[LT_FONTSIZE];
extern patch_t *cred_font[CRED_FONTSIZE];
extern patch_t *emeraldpics[7];
extern patch_t *tinyemeraldpics[7];
extern patch_t *rflagico;
extern patch_t *bflagico;
extern patch_t *rmatcico;
extern patch_t *bmatcico;
extern patch_t *tagico;
extern patch_t *tallminus;
// set true whenever the tab rankings are being shown for any reason
@@ -119,10 +125,10 @@ void HU_Drawer(void);
char HU_dequeueChatChar(void);
void HU_Erase(void);
void HU_clearChatChars(void);
void HU_drawPlayerPing(INT32 x, INT32 y, INT32 pnum, INT32 flags); // Lat': Ping drawer for scoreboard.
void HU_drawPing(INT32 x, INT32 y, UINT32 ping, INT32 flags); // Lat': Ping drawer for scoreboard.
//void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer);
//void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer);
void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 hilicol);
void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer, INT32 hilicol);
void HU_DrawEmeralds(INT32 x, INT32 y, INT32 pemeralds);
const char *HU_SkinColorToConsoleColor(skincolors_t color);
+1 -1
View File
@@ -53,6 +53,6 @@ typedef struct JoyType_s JoyType_t;
for palyer[sic] 1-4's joystick/gamepad
*/
extern JoyType_t Joystick[MAXSPLITSCREENPLAYERS];
extern JoyType_t Joystick, Joystick2, Joystick3, Joystick4;
#endif // __I_JOY_H__
+8 -19
View File
@@ -41,36 +41,17 @@ extern INT16 hardware_MAXPACKETLENGTH;
typedef struct
{
/// Supposed to be DOOMCOM_ID
INT32 id;
/// SRB2 executes an INT32 to execute commands.
INT16 intnum;
/// Communication between SRB2 and the driver.
/// Is CMD_SEND or CMD_GET.
INT16 command;
/// Is dest for send, set by get (-1 = no packet).
INT16 remotenode;
/// Number of bytes in doomdata to be sent
INT16 datalength;
/// Info common to all nodes.
/// Console is always node 0.
INT16 numnodes;
/// Flag: 1 = no duplication, 2-5 = dup for slow nets.
INT16 ticdup;
/// Flag: 1 = send a backup tic in every packet.
INT16 extratics;
/// kind of game
INT16 gametype;
/// Flag: -1 = new game, 0-5 = load savegame
INT16 savegame;
/// currect map
INT16 map;
/// Info specific to this node.
INT16 consoleplayer;
/// Number of "slots": the highest player number in use plus one.
INT16 numslots;
@@ -101,10 +82,18 @@ extern holepunch_t *holepunchpacket;
*/
extern boolean (*I_NetGet)(void);
/** \brief ask to driver if there is data waiting
*/
extern boolean (*I_NetCanGet)(void);
/** \brief send packet within doomcom struct
*/
extern void (*I_NetSend)(void);
/** \brief ask to driver if all is ok to send data now
*/
extern boolean (*I_NetCanSend)(void);
/** \brief close a connection
\param nodenum node to be closed
+96 -11
View File
@@ -112,6 +112,77 @@ ticcmd_t *I_BaseTiccmd4(void);
*/
void I_Quit(void) FUNCNORETURN;
typedef enum
{
EvilForce = -1,
//Constant
ConstantForce = 0,
//Ramp
RampForce,
//Periodics
SquareForce,
SineForce,
TriangleForce,
SawtoothUpForce,
SawtoothDownForce,
//MAX
NumberofForces,
} FFType;
typedef struct JoyFF_s
{
INT32 ForceX; ///< The X of the Force's Vel
INT32 ForceY; ///< The Y of the Force's Vel
//All
UINT32 Duration; ///< The total duration of the effect, in microseconds
INT32 Gain; //< /The gain to be applied to the effect, in the range from 0 through 10,000.
//All, CONSTANTFORCE -10,000 to 10,000
INT32 Magnitude; ///< Magnitude of the effect, in the range from 0 through 10,000.
//RAMPFORCE
INT32 Start; ///< Magnitude at the start of the effect, in the range from -10,000 through 10,000.
INT32 End; ///< Magnitude at the end of the effect, in the range from -10,000 through 10,000.
//PERIODIC
INT32 Offset; ///< Offset of the effect.
UINT32 Phase; ///< Position in the cycle of the periodic effect at which playback begins, in the range from 0 through 35,999
UINT32 Period; ///< Period of the effect, in microseconds.
} JoyFF_t;
/** \brief Forcefeedback for the first joystick
\param Type what kind of Effect
\param Effect Effect Info
\return void
*/
void I_Tactile(FFType Type, const JoyFF_t *Effect);
/** \brief Forcefeedback for the second joystick
\param Type what kind of Effect
\param Effect Effect Info
\return void
*/
void I_Tactile2(FFType Type, const JoyFF_t *Effect);
/** \brief Forcefeedback for the third joystick
\param Type what kind of Effect
\param Effect Effect Info
\return void
*/
void I_Tactile3(FFType Type, const JoyFF_t *Effect);
/** \brief Forcefeedback for the fourth joystick
\param Type what kind of Effect
\param Effect Effect Info
\return void
*/
void I_Tactile4(FFType Type, const JoyFF_t *Effect);
/** \brief to set up the first joystick scale
*/
@@ -131,13 +202,9 @@ void I_JoyScale4(void);
// Called by D_SRB2Main.
/** \brief to startup joystick
*/
void I_InitJoystick(UINT8 index);
/** \brief to startup the first joystick
*/
void I_InitJoystick1(void);
void I_InitJoystick(void);
/** \brief to startup the second joystick
*/
@@ -155,8 +222,6 @@ void I_InitJoystick4(void);
*/
INT32 I_NumJoys(void);
extern INT32 numcontrollers;
/** \brief The *I_GetJoyName function
\param joyindex which joystick
@@ -165,8 +230,8 @@ extern INT32 numcontrollers;
*/
const char *I_GetJoyName(INT32 joyindex);
void I_GamepadRumble(INT32 playernum, UINT16 low_strength, UINT16 high_strength, UINT32 duration);
void I_SetGamepadIndicatorColor(INT32 playernum, UINT8 red, UINT8 green, UINT8 blue);
void I_GamepadRumble(INT32 device_id, UINT16 low_strength, UINT16 high_strength, UINT32 duration);
void I_SetGamepadIndicatorColor(INT32 device_id, UINT8 red, UINT8 green, UINT8 blue);
#ifndef NOMUMBLE
#include "p_mobj.h" // mobj_t
@@ -180,6 +245,10 @@ void I_UpdateMumble(const mobj_t *mobj, const listener_t listener);
*/
void I_StartupMouse(void);
/** \brief Startup the second mouse
*/
void I_StartupMouse2(void);
/** \brief setup timer irq and user timer routine.
*/
void I_StartupTimer(void);
@@ -238,9 +307,25 @@ INT32 I_mkdir(const char *dirname, INT32 unixright);
*/
const char *I_LocateWad(void);
/** \brief Joystick events
/** \brief First Joystick's events
*/
void I_GetJoystickEvents(UINT8 index);
void I_GetJoystickEvents(void);
/** \brief Second Joystick's events
*/
void I_GetJoystick2Events(void);
/** \brief Third Joystick's events
*/
void I_GetJoystick3Events(void);
/** \brief Fourth Joystick's events
*/
void I_GetJoystick4Events(void);
/** \brief Mouses events
*/
void I_GetMouseEvents(void);
char *I_GetEnv(const char *name);
+187 -164
View File
@@ -24,7 +24,7 @@
#endif // __OS2__
#ifndef NO_IPV6
//#define HAVE_IPV6
#define HAVE_IPV6
#endif
#ifdef _WIN32
@@ -49,28 +49,34 @@
#ifdef NONET
#undef HAVE_MINIUPNPC
#else
#include <time.h>
#ifdef USE_WINSOCK1
#include <winsock.h>
#else
#ifndef USE_WINSOCK
#include <arpa/inet.h>
#ifdef __APPLE_CC__
#ifndef _BSD_SOCKLEN_T_
#define _BSD_SOCKLEN_T_
#endif //_BSD_SOCKLEN_T_
#endif //__APPLE_CC__
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/ioctl.h>
#endif //normal BSD API
#include <winsock.h>
#elif !defined (SCOUW2) && !defined (SCOUW7) && !defined (__OS2__)
#ifndef USE_WINSOCK
#include <arpa/inet.h>
#endif //normal BSD API
#include <errno.h>
#ifndef USE_WINSOCK
#ifdef __APPLE_CC__
#ifndef _BSD_SOCKLEN_T_
#define _BSD_SOCKLEN_T_
#endif //_BSD_SOCKLEN_T_
#endif //__APPLE_CC__
#include <sys/socket.h>
#include <netinet/in.h>
#endif //normal BSD API
#if defined (__unix__) || defined (__APPLE__) || defined (UNIXCOMMON)
#include <sys/time.h>
#endif // UNIXCOMMON
#ifndef USE_WINSOCK
#include <netdb.h>
#include <sys/ioctl.h>
#endif //normal BSD API
#include <errno.h>
#include <time.h>
#if defined (__unix__) || defined (__APPLE__) || defined (UNIXCOMMON)
#include <sys/time.h>
#endif // UNIXCOMMON
#endif // !NONET
#ifdef USE_WINSOCK
@@ -117,7 +123,7 @@
#ifndef STATUS_INVALID_PARAMETER
#define STATUS_INVALID_PARAMETER 0xC000000D
#endif
#endif // USE_WINSOCK
#endif
typedef union
{
@@ -162,6 +168,8 @@ static UINT8 UPNP_support = TRUE;
#endif
#include "i_addrinfo.h"
#define SELECTTEST
#define DEFAULTPORT "5029"
#if defined (USE_WINSOCK) && !defined (NONET)
@@ -176,8 +184,6 @@ typedef unsigned long SOCKET_TYPE;
#define ERRSOCKET (-1)
#endif
#define IPV6_MULTICAST_ADDRESS "ff15::57e1:1a12"
#ifdef USE_WINSOCK1
typedef int socklen_t;
#endif
@@ -374,7 +380,6 @@ static const char *SOCK_AddrToStr(mysockaddr_t *sk)
static char s[64]; // 255.255.255.255:65535 or IPv6:65535
#ifdef HAVE_NTOP
void *addr;
int e = 0; // save error code so it can't be modified later code and avoid calling WSAGetLastError() more then once
if(sk->any.sa_family == AF_INET)
addr = &sk->ip4.sin_addr;
@@ -388,10 +393,7 @@ static const char *SOCK_AddrToStr(mysockaddr_t *sk)
if(addr == NULL)
sprintf(s, "No address");
else if(inet_ntop(sk->any.sa_family, addr, s, sizeof (s)) == NULL)
{
e = errno;
sprintf(s, "Unknown family type, error #%u: %s", e, strerror(e));
}
sprintf(s, "Unknown family type, error #%u", errno);
#ifdef HAVE_IPV6
else if(sk->any.sa_family == AF_INET6 && sk->ip6.sin6_port != 0)
strcat(s, va(":%d", ntohs(sk->ip6.sin6_port)));
@@ -592,7 +594,6 @@ void Command_Numnodes(void)
#endif
#ifndef NONET
#ifdef HOLEPUNCH
/* not one of the reserved "local" addresses */
static boolean
is_external_address (UINT32 p)
@@ -618,6 +619,7 @@ is_external_address (UINT32 p)
}
}
#ifdef HOLEPUNCH
static boolean hole_punch(ssize_t c)
{
@@ -643,7 +645,7 @@ static boolean hole_punch(ssize_t c)
}
}
#endif //ifdef HOLEPUNCH
#endif
// Returns true if a packet was received from a new node, false in all other cases
static boolean SOCK_Get(void)
@@ -748,6 +750,59 @@ static boolean SOCK_Get(void)
}
#endif
// check if we can send (do not go over the buffer)
#ifndef NONET
static fd_set masterset;
#ifdef SELECTTEST
static boolean FD_CPY(fd_set *src, fd_set *dst, SOCKET_TYPE *fd, size_t len)
{
size_t i;
boolean testset = false;
FD_ZERO(dst);
for (i = 0; i < len;i++)
{
if(fd[i] != (SOCKET_TYPE)ERRSOCKET &&
FD_ISSET(fd[i], src) && !FD_ISSET(fd[i], dst)) // no checking for dups
{
FD_SET(fd[i], dst);
testset = true;
}
}
return testset;
}
static boolean SOCK_CanSend(void)
{
struct timeval timeval_for_select = {0, 0};
fd_set tset;
int wselect;
if(!FD_CPY(&masterset, &tset, mysockets, mysocketses))
return false;
wselect = select(255, NULL, &tset, NULL, &timeval_for_select);
if (wselect >= 1)
return true;
return false;
}
static boolean SOCK_CanGet(void)
{
struct timeval timeval_for_select = {0, 0};
fd_set tset;
int rselect;
if(!FD_CPY(&masterset, &tset, mysockets, mysocketses))
return false;
rselect = select(255, &tset, NULL, NULL, &timeval_for_select);
if (rselect >= 1)
return true;
return false;
}
#endif
#endif
#ifndef NONET
static inline ssize_t SOCK_SendToAddr(SOCKET_TYPE socket, mysockaddr_t *sockaddr)
{
@@ -769,12 +824,11 @@ static inline ssize_t SOCK_SendToAddr(SOCKET_TYPE socket, mysockaddr_t *sockaddr
return sendto(socket, (char *)&doomcom->data, doomcom->datalength, 0, &sockaddr->any, d);
}
#define ALLOWEDERROR(x) ((x) == ECONNREFUSED || (x) == EWOULDBLOCK || (x) == EHOSTUNREACH || (x) == ENETUNREACH || (x) == EADDRNOTAVAIL)
#define ALLOWEDERROR(x) ((x) == ECONNREFUSED || (x) == EWOULDBLOCK || (x) == EHOSTUNREACH || (x) == ENETUNREACH)
static void SOCK_Send(void)
{
ssize_t c = ERRSOCKET;
int e = 0; // save error code so it can't be modified later code and avoid calling WSAGetLastError() more then once
size_t i, j;
if (!nodeconnected[doomcom->remotenode])
@@ -789,15 +843,12 @@ static void SOCK_Send(void)
if (myfamily[i] == broadcastaddress[j].any.sa_family)
{
c = SOCK_SendToAddr(mysockets[i], &broadcastaddress[j]);
if (c == ERRSOCKET)
{
e = errno;
if (!ALLOWEDERROR(e))
break;
}
if (c == ERRSOCKET && !ALLOWEDERROR(errno))
break;
}
}
}
return;
}
else if (nodesocket[doomcom->remotenode] == (SOCKET_TYPE)ERRSOCKET)
{
@@ -806,33 +857,27 @@ static void SOCK_Send(void)
if (myfamily[i] == clientaddress[doomcom->remotenode].any.sa_family)
{
c = SOCK_SendToAddr(mysockets[i], &clientaddress[doomcom->remotenode]);
if (c == ERRSOCKET)
{
e = errno;
if (!ALLOWEDERROR(e))
break;
}
if (c == ERRSOCKET && !ALLOWEDERROR(errno))
break;
}
}
return;
}
else
{
c = SOCK_SendToAddr(nodesocket[doomcom->remotenode], &clientaddress[doomcom->remotenode]);
if (c == ERRSOCKET)
{
e = errno;
}
}
if (c == ERRSOCKET && e != 0) // 0 means no socket for the address family was found
if (c == ERRSOCKET)
{
int e = errno; // save error code so it can't be modified later
if (!ALLOWEDERROR(e))
I_Error("SOCK_Send, error sending to node %d (%s) #%u, %s", doomcom->remotenode,
I_Error("SOCK_Send, error sending to node %d (%s) #%u: %s", doomcom->remotenode,
SOCK_GetNodeAddress(doomcom->remotenode), e, strerror(e));
}
}
#undef ALLOWEDERROR
#endif //NONET
#endif
#ifndef NONET
static void SOCK_FreeNodenum(INT32 numnode)
@@ -861,8 +906,6 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen
{
SOCKET_TYPE s = socket(family, SOCK_DGRAM, IPPROTO_UDP);
int opt;
int rc;
int e = 0; // save error code so it can't be modified later code and avoid calling WSAGetLastError() more then once
socklen_t opts;
#ifdef FIONBIO
unsigned long trueval = true;
@@ -878,17 +921,12 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen
#ifdef USE_WINSOCK2
DWORD dwBytesReturned = 0;
BOOL bfalse = FALSE;
rc = WSAIoctl(s, SIO_UDP_CONNRESET, &bfalse, sizeof(bfalse),
WSAIoctl(s, SIO_UDP_CONNRESET, &bfalse, sizeof(bfalse),
NULL, 0, &dwBytesReturned, NULL, NULL);
#else
unsigned long falseval = false;
rc = ioctl(s, SIO_UDP_CONNRESET, &falseval);
ioctl(s, SIO_UDP_CONNRESET, &falseval);
#endif
if (rc == -1)
{
e = errno;
I_OutputMsg("SIO_UDP_CONNRESET failed: #%u, %s\n", e, strerror(e));
}
}
#endif
@@ -903,22 +941,14 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen
{
opt = true;
opts = (socklen_t)sizeof(opt);
rc = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, opts);
if (rc <= -1)
{
e = errno;
I_OutputMsg("setting SO_REUSEADDR failed: #%u, %s\n", e, strerror(e));
}
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, opts);
}
// make it broadcastable
opt = true;
opts = (socklen_t)sizeof(opt);
rc = setsockopt(s, SOL_SOCKET, SO_BROADCAST, (char *)&opt, opts);
if (rc <= -1)
if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, (char *)&opt, opts))
{
e = errno;
CONS_Alert(CONS_WARNING, M_GetText("Could not get broadcast rights\n")); // I do not care anymore
I_OutputMsg("setting SO_BROADCAST failed: #%u, %s\n", e, strerror(e));
}
}
#ifdef HAVE_IPV6
@@ -928,117 +958,56 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen
{
opt = true;
opts = (socklen_t)sizeof(opt);
rc = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, opts);
if (rc <= -1)
{
e = errno;
I_OutputMsg("setting SO_REUSEADDR failed: #%u, %s\n", e, strerror(e));
}
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, opts);
}
#ifdef IPV6_V6ONLY
// make it IPv6 ony
opt = true;
opts = (socklen_t)sizeof(opt);
rc = setsockopt(s, SOL_SOCKET, IPV6_V6ONLY, (char *)&opt, opts);
if (rc <= -1)
if (setsockopt(s, SOL_SOCKET, IPV6_V6ONLY, (char *)&opt, opts))
{
e = errno;
CONS_Alert(CONS_WARNING, M_GetText("Could not limit IPv6 bind\n")); // I do not care anymore
I_OutputMsg("setting IPV6_V6ONLY failed: #%u, %s\n", e, strerror(e));
}
#endif
}
#endif
rc = bind(s, addr, addrlen);
if (rc == ERRSOCKET)
if (bind(s, addr, addrlen) == ERRSOCKET)
{
e = errno;
close(s);
I_OutputMsg("Binding failed: #%u, %s\n", e, strerror(e));
I_OutputMsg("Binding failed\n");
return (SOCKET_TYPE)ERRSOCKET;
}
#ifdef HAVE_IPV6
if (family == AF_INET6)
{
// we need to set all of this *after* binding to an address!
if (memcmp(&straddr.ip6.sin6_addr, &in6addr_any, sizeof(in6addr_any)) == 0) //IN6_ARE_ADDR_EQUAL
{
struct ipv6_mreq maddr;
inet_pton(AF_INET6, IPV6_MULTICAST_ADDRESS, &maddr.ipv6mr_multiaddr);
maddr.ipv6mr_interface = 0;
rc = setsockopt(s, SOL_SOCKET, IPV6_JOIN_GROUP, (const char *)&maddr, sizeof(maddr));
if (rc <= -1)
{
e = errno;
CONS_Alert(CONS_WARNING, M_GetText("Could not register multicast address\n"));
if (e == ENODEV)
{
close(s);
I_OutputMsg("Binding failed: no IPv6 device\n");
return (SOCKET_TYPE)ERRSOCKET;
}
I_OutputMsg("setting IPV6_JOIN_GROUP failed: #%u, %s \n", e, strerror(e));
}
}
}
#endif
#ifdef FIONBIO
// make it non blocking
rc = ioctl(s, FIONBIO, &trueval);
if (rc == -1)
opt = true;
if (ioctl(s, FIONBIO, &trueval) != 0)
{
e = errno;
close(s);
I_OutputMsg("FIOBIO failed: #%u, %s\n", e, strerror(e));
I_OutputMsg("Seting FIOBIO on failed\n");
return (SOCKET_TYPE)ERRSOCKET;
}
#endif
opt = 0;
opts = (socklen_t)sizeof(opt);
rc = getsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&opt, &opts);
if (rc <= -1)
{
e = errno;
I_OutputMsg("getting SO_RCVBUF failed: #%u, %s\n", e, strerror(e));
}
getsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&opt, &opts);
CONS_Printf(M_GetText("Network system buffer: %dKb\n"), opt>>10);
if (opt < 64<<10) // 64k
{
opt = 64<<10;
opts = (socklen_t)sizeof(opt);
rc = setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&opt, opts);
if (rc <= -1)
{
e = errno;
I_OutputMsg("setting SO_RCVBUF failed: #%u, %s\n", e, strerror(e));
}
opt = 0;
rc = getsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&opt, &opts);
if (rc <= -1)
{
e = errno;
I_OutputMsg("getting SO_RCVBUF failed: #%u, %s\n", e, strerror(e));
}
setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&opt, opts);
getsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&opt, &opts);
if (opt < 64<<10)
CONS_Alert(CONS_WARNING, M_GetText("Can't set buffer length to 64k, file transfer will be bad\n"));
else
CONS_Printf(M_GetText("Network system buffer set to: %dKb\n"), opt>>10);
}
rc = getsockname(s, (struct sockaddr *)&sin, &len);
if (rc != 0)
{
e = errno;
if (getsockname(s, (struct sockaddr *)&sin, &len) == -1)
CONS_Alert(CONS_WARNING, M_GetText("Failed to get port number\n"));
I_OutputMsg("getsockname failed: #%u, %s\n", e, strerror(e));
}
else
current_port = (UINT16)ntohs(sin.sin_port);
@@ -1060,6 +1029,7 @@ static boolean UDP_Socket(void)
mysockets[s] = ERRSOCKET;
for (s = 0; s < MAXNETNODES+1; s++)
nodesocket[s] = ERRSOCKET;
FD_ZERO(&masterset);
s = 0;
memset(&hints, 0x00, sizeof (hints));
@@ -1086,6 +1056,7 @@ static boolean UDP_Socket(void)
mysockets[s] = UDP_Bind(runp->ai_family, runp->ai_addr, (socklen_t)runp->ai_addrlen);
if (mysockets[s] != (SOCKET_TYPE)ERRSOCKET)
{
FD_SET(mysockets[s], &masterset);
myfamily[s] = hints.ai_family;
s++;
}
@@ -1106,6 +1077,7 @@ static boolean UDP_Socket(void)
mysockets[s] = UDP_Bind(runp->ai_family, runp->ai_addr, (socklen_t)runp->ai_addrlen);
if (mysockets[s] != (SOCKET_TYPE)ERRSOCKET)
{
FD_SET(mysockets[s], &masterset);
myfamily[s] = hints.ai_family;
s++;
#ifdef HAVE_MINIUPNPC
@@ -1138,6 +1110,7 @@ static boolean UDP_Socket(void)
mysockets[s] = UDP_Bind(runp->ai_family, runp->ai_addr, (socklen_t)runp->ai_addrlen);
if (mysockets[s] != (SOCKET_TYPE)ERRSOCKET)
{
FD_SET(mysockets[s], &masterset);
myfamily[s] = hints.ai_family;
s++;
}
@@ -1158,6 +1131,7 @@ static boolean UDP_Socket(void)
mysockets[s] = UDP_Bind(runp->ai_family, runp->ai_addr, (socklen_t)runp->ai_addrlen);
if (mysockets[s] != (SOCKET_TYPE)ERRSOCKET)
{
FD_SET(mysockets[s], &masterset);
myfamily[s] = hints.ai_family;
s++;
}
@@ -1178,28 +1152,65 @@ static boolean UDP_Socket(void)
// ip + udp
packetheaderlength = 20 + 8; // for stats
clientaddress[s].any.sa_family = AF_INET;
clientaddress[s].ip4.sin_port = htons(0);
clientaddress[s].ip4.sin_addr.s_addr = htonl(INADDR_LOOPBACK); //GetLocalAddress(); // my own ip
s++;
hints.ai_family = AF_INET;
gaie = I_getaddrinfo("127.0.0.1", "0", &hints, &ai);
if (gaie == 0)
{
runp = ai;
while (runp != NULL && s < MAXNETNODES+1)
{
memcpy(&clientaddress[s], runp->ai_addr, runp->ai_addrlen);
s++;
runp = runp->ai_next;
}
I_freeaddrinfo(ai);
}
else
{
clientaddress[s].any.sa_family = AF_INET;
clientaddress[s].ip4.sin_port = htons(0);
clientaddress[s].ip4.sin_addr.s_addr = htonl(INADDR_LOOPBACK); //GetLocalAddress(); // my own ip
s++;
}
s = 0;
// setup broadcast adress to BROADCASTADDR entry
broadcastaddress[s].any.sa_family = AF_INET;
broadcastaddress[s].ip4.sin_port = htons(atoi(DEFAULTPORT));
broadcastaddress[s].ip4.sin_addr.s_addr = htonl(INADDR_BROADCAST);
s++;
gaie = I_getaddrinfo("255.255.255.255", "0", &hints, &ai);
if (gaie == 0)
{
runp = ai;
while (runp != NULL && s < MAXNETNODES+1)
{
memcpy(&broadcastaddress[s], runp->ai_addr, runp->ai_addrlen);
s++;
runp = runp->ai_next;
}
I_freeaddrinfo(ai);
}
else
{
broadcastaddress[s].any.sa_family = AF_INET;
broadcastaddress[s].ip4.sin_port = htons(0);
broadcastaddress[s].ip4.sin_addr.s_addr = htonl(INADDR_BROADCAST);
s++;
}
#ifdef HAVE_IPV6
if (b_ipv6)
{
broadcastaddress[s].any.sa_family = AF_INET6;
broadcastaddress[s].ip6.sin6_port = htons(atoi(DEFAULTPORT));
broadcastaddress[s].ip6.sin6_flowinfo = 0;
inet_pton(AF_INET6, IPV6_MULTICAST_ADDRESS, &broadcastaddress[s].ip6.sin6_addr);
broadcastaddress[s].ip6.sin6_scope_id = 0;
s++;
hints.ai_family = AF_INET6;
gaie = I_getaddrinfo("ff02::1", "0", &hints, &ai);
if (gaie == 0)
{
runp = ai;
while (runp != NULL && s < MAXNETNODES+1)
{
memcpy(&broadcastaddress[s], runp->ai_addr, runp->ai_addrlen);
s++;
runp = runp->ai_next;
}
I_freeaddrinfo(ai);
}
}
#endif
@@ -1287,15 +1298,16 @@ boolean I_InitTcpDriver(void)
static void SOCK_CloseSocket(void)
{
size_t i;
for (i = 0; i < mysocketses; i++)
for (i=0; i < MAXNETNODES+1; i++)
{
if (mysockets[i] != (SOCKET_TYPE)ERRSOCKET)
if (mysockets[i] != (SOCKET_TYPE)ERRSOCKET
&& FD_ISSET(mysockets[i], &masterset))
{
FD_CLR(mysockets[i], &masterset);
close(mysockets[i]);
}
mysockets[i] = ERRSOCKET;
}
mysocketses = 0;
}
#endif
@@ -1405,7 +1417,9 @@ static void rendezvous(int size)
if (tic == refreshtic)
{
#ifdef HOLEPUNCH
holepunchpacket->magic = hole_punch_magic;
#endif
sendto(mysockets[0], doomcom->data, size, 0, &rzv.any, sizeof rzv.ip4);
}
@@ -1430,6 +1444,7 @@ static void SOCK_RegisterHolePunch(void)
rendezvous(4);
}
#endif
#endif
static boolean SOCK_OpenSocket(void)
@@ -1449,7 +1464,13 @@ static boolean SOCK_OpenSocket(void)
I_NetFreeNodenum = SOCK_FreeNodenum;
I_NetMakeNodewPort = SOCK_NetMakeNodewPort;
#ifdef SELECTTEST
// seem like not work with libsocket : (
I_NetCanSend = SOCK_CanSend;
I_NetCanGet = SOCK_CanGet;
#endif
#ifdef HOLEPUNCH
I_NetRequestHolePunch = SOCK_RequestHolePunch;
I_NetRegisterHolePunch = SOCK_RegisterHolePunch;
#endif
@@ -1690,8 +1711,6 @@ boolean I_InitTcpNetwork(void)
// FIXME: for dedicated server, numnodes needs to be set to 0 upon start
if (dedicated)
doomcom->numnodes = 0;
/* else if (M_IsNextParm())
doomcom->numnodes = (INT16)atoi(M_GetNextParm());*/
else
doomcom->numnodes = 1;
@@ -1719,6 +1738,7 @@ boolean I_InitTcpNetwork(void)
// server address only in ip
if (serverhostname[0])
{
CV_Set(&cv_lastserver, serverhostname);
COM_BufAddText("connect \"");
COM_BufAddText(serverhostname);
COM_BufAddText("\"\n");
@@ -1728,6 +1748,9 @@ boolean I_InitTcpNetwork(void)
}
else
{
// Not quite sure if we want to save that but i'll do that for now
CV_Set(&cv_lastserver, "any");
// so we're on a LAN
COM_BufAddText("connect any\n");
+3 -3
View File
@@ -58,10 +58,10 @@ void I_UpdateTime(fixed_t timescale)
tic_t realtics;
// get real tics
ticratescaled = (double)TICRATE * FixedToFloat(timescale);
ticratescaled = (double)TICRATE * FIXED_TO_FLOAT(timescale);
enterprecise = I_GetPreciseTime();
elapsedseconds = (double)((INT64)enterprecise - oldenterprecise) / I_GetPrecisePrecision();
elapsedseconds = (double)(enterprecise - oldenterprecise) / I_GetPrecisePrecision();
tictimer += elapsedseconds;
while (tictimer > 1.0/ticratescaled)
{
@@ -77,6 +77,6 @@ void I_UpdateTime(fixed_t timescale)
{
double fractional, integral;
fractional = modf(tictimer * ticratescaled, &integral);
g_time.timefrac = FloatToFixed(fractional);
g_time.timefrac = FLOAT_TO_FIXED(fractional);
}
}
+3 -3
View File
@@ -139,13 +139,13 @@ UINT32 I_GetRefreshRate(void);
boolean I_UseNativeKeyboard(void);
boolean I_CheckNativeRes(void);
#ifdef USE_FBO_OGL
#if defined (__unix__)
extern boolean xwaylandcrap;
#endif
void RefreshOGLSDLSurface(void);
void I_DownSample(void);
boolean UseScreenFBO(void);
extern boolean downsample;
#endif
+1
View File
@@ -21,6 +21,7 @@
#include "d_player.h"
#include "lzf.h"
// Hey, moron! If you change this table, don't forget about the sprite enum in info.h and the sprite lights in hw_light.c!
char sprnames[NUMSPRITES + 1][5] =
{
"NULL","UNKN","THOK","PLAY","POSS","SPOS","FISH","BUZZ","RBUZ","JETB",
+4
View File
@@ -159,6 +159,9 @@ enum actionnum
A_SPAWNOBJECTRELATIVE,
A_CHANGEANGLERELATIVE,
A_CHANGEANGLEABSOLUTE,
A_ROLLANGLE,
A_CHANGEROLLANGLERELATIVE,
A_CHANGEROLLANGLEABSOLUTE,
A_PLAYSOUND,
A_FINDTARGET,
A_FINDTRACER,
@@ -457,6 +460,7 @@ extern boolean actionsoverridden[NUMACTIONS];
#define NUMSPRITEFREESLOTS NUMMOBJFREESLOTS
#define NUMSTATEFREESLOTS (NUMMOBJFREESLOTS*8)
// Hey, moron! If you change this table, don't forget about sprnames in info.c and the sprite lights in hw_light.c!
typedef enum sprite
{
SPR_NULL, // invisible object
+73 -126
View File
@@ -12,17 +12,13 @@
//#include "k_kart.h"
#include "doomdef.h"
#include "doomstat.h"
#include "g_game.h"
#include "m_random.h"
#include "v_video.h"
#include "k_director.h"
#include "d_netcmd.h"
#include "p_local.h"
#include "st_stuff.h"
#include "r_fps.h"
#define SWITCHTIME TICRATE * 5 // cooldown between unforced switches
#define BOREDOMTIME 3 * TICRATE / 2 // how long until players considered far apart?
#define TRANSFERTIME TICRATE // how long to delay reaction shots?
@@ -32,9 +28,7 @@
struct directorinfo
{
player_t* viewplayer;
tic_t cooldown; // how long has it been since we last switched?
tic_t chaosleep;// how long did we watch the same player?
tic_t freeze; // when nonzero, fixed switch pending, freeze logic!
INT32 attacker; // who to switch to when freeze delay elapses
INT32 maxdist; // how far is the closest player from finishing?
@@ -44,17 +38,23 @@ struct directorinfo
INT32 boredom[MAXPLAYERS]; // how long has a given position had no credible attackers?
} directorinfo;
static INT32 K_PlayersPlaying(void)
boolean K_DirectorIsPlayerAlone(void)
{
INT32 num = 0, i;
for (i = 0; i < MAXPLAYERS; i++)
UINT8 pingame = 0;
// Gotta check how many players are active at this moment.
for (UINT8 i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i] || players[i].spectator || !players[i].mo)
if (!playeringame[i] || players[i].spectator)
continue;
num++;
pingame++;
if (pingame >= 2) // we dont need to check further
break;
}
return num;
return (pingame <= 1);
}
static inline boolean race_rules(void)
@@ -67,58 +67,9 @@ static fixed_t ScaleFromMap(fixed_t n, fixed_t scale)
return FixedMul(n, FixedDiv(scale, mapobjectscale));
}
boolean K_DirectorIsAvailable(void)
{
if (splitscreen || dedicated || (demo.playback && demo.title) || modeattacking)
return false;
return ((gamestate == GS_LEVEL) && ((demo.playback && !camera[0].freecam) || (players[consoleplayer].spectator && (K_PlayersPlaying() > 1))));
}
static boolean K_DirectorIsEnabled(void)
{
return (cv_director.value && K_DirectorIsAvailable());
}
static mobj_t *finishmo = NULL;
// scan for the waypoint on the finish line
// used to get a very approximate distance from player to finishline
// we probably should like, do some maths to find the middle point between multiplayer
// waypoints with the same values, but idk if its really worth it
static void K_SetupFinishMo(void)
{
INT16 maxMoveCount = -1;
INT16 maxAngle = -1;
finishmo = NULL;
if (!(mapheaderinfo[gamemap - 1]->levelflags & LF_SECTIONRACE)) // not a sprint map
{
// waypoint with angle 0 should always be at the finish line
for (finishmo = waypointcap; finishmo != NULL; finishmo = finishmo->tracer)
{
if (finishmo->spawnpoint->angle == 0)
break;
}
}
else // crappy optimization weeeee
{
// sprint maps finishline waypoint is the one with highest movecount AND angle
for (finishmo = waypointcap; finishmo != NULL; finishmo = finishmo->tracer)
{
if (finishmo->movecount > maxMoveCount)
maxMoveCount = finishmo->movecount;
if (finishmo->spawnpoint->angle > maxAngle)
maxAngle = finishmo->spawnpoint->angle;
}
// now actually get the one
for (finishmo = waypointcap; finishmo != NULL; finishmo = finishmo->tracer)
{
if (finishmo->movecount == maxMoveCount && finishmo->spawnpoint->angle == maxAngle)
break; // found it
}
}
return cv_director.value && !splitscreen && (gamestate == GS_LEVEL && (((stplyr && !stplyr->spectator) && (!playeringame[consoleplayer] || players[consoleplayer].spectator)) || (demo.playback && !demo.freecam && (!demo.title || !modeattacking))) && !K_DirectorIsPlayerAlone());
}
void K_InitDirector(void)
@@ -129,8 +80,6 @@ void K_InitDirector(void)
directorinfo.freeze = 0;
directorinfo.attacker = 0;
directorinfo.maxdist = 0;
directorinfo.viewplayer = NULL;
directorinfo.chaosleep = 0;
for (playernum = 0; playernum < MAXPLAYERS; playernum++)
{
@@ -138,18 +87,50 @@ void K_InitDirector(void)
directorinfo.gap[playernum] = INT32_MAX;
directorinfo.boredom[playernum] = 0;
}
K_SetupFinishMo();
}
static fixed_t K_GetDistanceToFinish(player_t player)
{
if (P_MobjWasRemoved(finishmo))
return 0;
mobj_t *mo;
fixed_t dist = 0;
INT16 maxMoveCount = -1;
INT16 maxAngle = -1;
return P_AproxDistance(P_AproxDistance(finishmo->x - player.mo->x,
finishmo->y - player.mo->y),
finishmo->z - player.mo->z) / FRACUNIT;
if (!(mapheaderinfo[gamemap - 1]->levelflags & LF_SECTIONRACE))
{
for (mo = waypointcap; mo != NULL; mo = mo->tracer)
{
if (mo->spawnpoint->angle != 0)
continue;
dist = P_AproxDistance(P_AproxDistance(mo->x - player.mo->x,
mo->y - player.mo->y),
mo->z - player.mo->z) / FRACUNIT;
break;
}
}
else // crappy optimization weeeee
{
for (mo = waypointcap; mo != NULL; mo = mo->tracer)
{
if (mo->movecount > maxMoveCount)
maxMoveCount = mo->movecount;
if (mo->spawnpoint->angle > maxAngle)
maxAngle = mo->spawnpoint->angle;
if (!(mo->movecount == maxMoveCount && mo->spawnpoint->angle == maxAngle)) // sprint maps finishline waypoint is the one with highest movecount AND angle
continue;
dist = P_AproxDistance(P_AproxDistance(mo->x - player.mo->x,
mo->y - player.mo->y),
mo->z - player.mo->z) / FRACUNIT;
break;
}
}
return dist;
}
static fixed_t K_GetFinishGap(INT32 leader, INT32 follower)
@@ -173,10 +154,10 @@ static void K_UpdateDirectorPositions(void)
INT32 position;
player_t* target;
memset(directorinfo.sortedplayers, -1, sizeof(directorinfo.sortedplayers));
for (playernum = 0; playernum < MAXPLAYERS; playernum++)
{
directorinfo.sortedplayers[playernum] = -1;
target = &players[playernum];
if (playeringame[playernum] && !target->spectator && target->kartstuff[k_position] > 0)
@@ -232,6 +213,11 @@ static void K_DirectorSwitch(INT32 player, boolean force)
return;
}
if (P_IsDisplayPlayer(&players[player]))
{
return;
}
if (players[player].exiting)
{
return;
@@ -244,7 +230,6 @@ static void K_DirectorSwitch(INT32 player, boolean force)
G_ResetView(1, player, true);
directorinfo.cooldown = SWITCHTIME;
directorinfo.chaosleep = 0;
}
static void K_DirectorForceSwitch(INT32 player, INT32 time)
@@ -256,26 +241,6 @@ static void K_DirectorForceSwitch(INT32 player, INT32 time)
directorinfo.attacker = player;
directorinfo.freeze = time;
directorinfo.chaosleep = 0;
}
static void K_DirectorSwitchRandom(void)
{
INT32 randomplayer = -1;
// kinda dumb but just check if the random player is existing lmao
for (INT32 h = 0; h < MAXPLAYERS; h++)
{
randomplayer = directorinfo.sortedplayers[M_RandomRange(0, K_PlayersPlaying()-1)]; // switch to someone random
if (randomplayer != -1 && randomplayer != displayplayers[0]) // dont switch to ourselves Zzz...
{
break;
}
}
if (randomplayer != -1)
K_DirectorSwitch(randomplayer, true);
}
void K_DirectorFollowAttack(player_t *player, mobj_t *inflictor, mobj_t *source)
@@ -285,7 +250,7 @@ void K_DirectorFollowAttack(player_t *player, mobj_t *inflictor, mobj_t *source)
return;
}
if (directorinfo.viewplayer != player)
if (!P_IsDisplayPlayer(player))
{
return;
}
@@ -318,7 +283,6 @@ void K_DrawDirectorDebugger(void)
V_DrawThinString(120, 0, V_70TRANS, va("BORED"));
V_DrawThinString(150, 0, V_70TRANS, va("COOLDOWN: %d", directorinfo.cooldown));
V_DrawThinString(230, 0, V_70TRANS, va("MAXDIST: %d", directorinfo.maxdist));
V_DrawThinString(310, 0, V_70TRANS, va("SLEEPTIME: %d", directorinfo.chaosleep));
for (position = 0; position < MAXPLAYERS - 1; position++)
{
@@ -355,8 +319,8 @@ void K_DrawDirectorDebugger(void)
void K_UpdateDirector(void)
{
INT32 *displayplayerp = &displayplayers[0];
INT32 targetposition;
directorinfo.viewplayer = &players[displayplayers[0]];
if (!K_DirectorIsEnabled())
{
@@ -365,8 +329,7 @@ void K_UpdateDirector(void)
K_UpdateDirectorPositions();
if (directorinfo.cooldown > 0)
{
if (directorinfo.cooldown > 0) {
directorinfo.cooldown--;
}
@@ -388,27 +351,6 @@ void K_UpdateDirector(void)
return;
}
// insta switch if the player were watching finishes
if (players[displayplayers[0]].exiting)
{
K_DirectorSwitchRandom();
return;
}
// begin counting when cooldown wore off
if (!directorinfo.cooldown)
{
directorinfo.chaosleep++;
}
// force switch 10 seconds after the cooldown has ended
// otherwise i fall asleeb zzz...
if (directorinfo.chaosleep > TICRATE*10)
{
K_DirectorSwitchRandom();
return;
}
// aaight, time to walk through the standings to find the first interesting pair
// NB: targetposition/sortedplayers is 0-indexed, aiming at the "back half" of a given pair by default.
// we adjust for this when comparing to player->position or when looking at the leading player, Don't Freak Out
@@ -449,19 +391,25 @@ void K_UpdateDirector(void)
target = directorinfo.sortedplayers[targetposition];
// stop here since we're already viewing this player
if (displayplayers[0] == target)
if (*displayplayerp == target)
{
break;
}
// if this is a splitscreen player, try next pair
if (P_IsDisplayPlayer(&players[target]))
{
continue;
}
// if we're certain the back half of the pair is actually in this position, try to switch
if (!players[target].kartstuff[k_positiondelay])
{
K_DirectorSwitch(target, false);
}
// even if we're not certain, if we're cetain we're watching the WRONG player, try to switch
if (directorinfo.viewplayer->kartstuff[k_position] != targetposition+1 && !directorinfo.viewplayer->kartstuff[k_positiondelay])
// even if we're not certain, if we're certain we're watching the WRONG player, try to switch
if (players[*displayplayerp].kartstuff[k_position] != targetposition+1 && !players[*displayplayerp].kartstuff[k_positiondelay])
{
K_DirectorSwitch(target, false);
}
@@ -472,16 +420,15 @@ void K_UpdateDirector(void)
void K_ToggleDirector(void)
{
if (!K_DirectorIsAvailable())
if (!directortextactive)
return;
if (!K_DirectorIsEnabled())
{
G_AdjustView(1, 1, true);
directorinfo.cooldown = 0; // switch immediately
}
directortoggletimer = 0;
CV_SetValue(&cv_director, (cv_director.value ^ 1));
COM_ImmedExecute("add director 1");
}
Loaded 100 of 299 files, more files were not shown because too many files have changed in this diff. Show more