diff --git a/.circleci/config.yml b/.circleci/config.yml index b5c43d017..ca9105685 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -58,6 +58,3 @@ jobs: key: v1-SRB2-{{ .Branch }}-{{ checksum "objs/Linux/SDL/Release/depend.dep" }} paths: - /root/.ccache - - - diff --git a/.travis.yml b/.travis.yml index e5dbb58e4..4648ae567 100644 --- a/.travis.yml +++ b/.travis.yml @@ -100,6 +100,21 @@ matrix: compiler: gcc-6 env: WFLAGS="-Wno-tautological-compare" #gcc-6 (Ubuntu 6.1.1-3ubuntu11~14.04.1) 6.1.1 20160511 + - os: linux + addons: + apt: + sources: + - ubuntu-toolchain-r-test + packages: + - libsdl2-mixer-dev + - libpng-dev + - libgl1-mesa-dev + - libgme-dev + - p7zip-full + - gcc-7 + compiler: gcc-7 + env: WFLAGS="-Wno-tautological-compare -Wno-error=implicit-fallthrough -Wimplicit-fallthrough=3" + #gcc-7 (Ubuntu 7.2.0-1ubuntu1~14.04) 7.2.0 20170802 - os: linux compiler: clang #clang version 3.5.0 (tags/RELEASE_350/final) @@ -162,6 +177,51 @@ matrix: - clang-3.8 compiler: clang-3.8 #clang version 3.8.1-svn271127-1~exp1 (branches/release_38) + - os: linux + addons: + apt: + sources: + - llvm-toolchain-precise-3.9 + - ubuntu-toolchain-r-test + packages: + - libsdl2-mixer-dev + - libpng-dev + - libgl1-mesa-dev + - libgme-dev + - p7zip-full + - clang-3.9 + compiler: clang-3.9 + #clang version 3.9.X +# - os: linux +# addons: +# apt: +# sources: +# - llvm-toolchain-precise-4.0 +# - ubuntu-toolchain-r-test +# packages: +# - libsdl2-mixer-dev +# - libpng-dev +# - libgl1-mesa-dev +# - libgme-dev +# - p7zip-full +# - clang-4.0 +# compiler: clang-4.0 +# #clang version 4.0.X +# - os: linux +# addons: +# apt: +# sources: +# - llvm-toolchain-precise-5.0 +# - ubuntu-toolchain-r-test +# packages: +# - libsdl2-mixer-dev +# - libpng-dev +# - libgl1-mesa-dev +# - libgme-dev +# - p7zip-full +# - clang-5.0 +# compiler: clang-5.0 +# #clang version 5.0.X # - os: osx # osx_image: beta-xcode6.1 # #Apple LLVM version 6.0 (clang-600.0.54) (based on LLVM 3.5svn) @@ -192,6 +252,9 @@ matrix: - compiler: clang-3.6 - compiler: clang-3.7 - compiler: clang-3.8 + - compiler: clang-3.9 + - compiler: clang-4.0 + - compiler: clang-5.0 cache: apt: true @@ -219,9 +282,9 @@ before_script: before_install: - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install sdl2_mixer game-music-emu p7zip; fi + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install sdl2 sdl2_mixer game-music-emu p7zip; fi - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install cmake||true; fi - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then curl -O -L https://www.libsdl.org/release/SDL2-2.0.4.dmg; hdiutil attach SDL2-2.0.4.dmg; sudo cp -a /Volumes/SDL2/SDL2.framework /Library/Frameworks/; fi + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then curl -O -L https://www.libsdl.org/release/SDL2-2.0.6.dmg; hdiutil attach SDL2-2.0.6.dmg; sudo cp -a /Volumes/SDL2/SDL2.framework /Library/Frameworks/; fi - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then curl -O -L https://www.libsdl.org/projects/SDL_mixer/release/SDL2_mixer-2.0.1.dmg; hdiutil attach SDL2_mixer-2.0.1.dmg; sudo cp -a /Volumes/SDL2_mixer/SDL2_mixer.framework /Library/Frameworks/; fi - mkdir -p $HOME/srb2_cache diff --git a/bin/DC/.gitignore b/bin/DC/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/bin/DC/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/bin/Dos/Debug/.gitignore b/bin/Dos/Debug/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/bin/Dos/Debug/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/bin/Dos/Release/.gitignore b/bin/Dos/Release/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/bin/Dos/Release/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/bin/FreeBSD/Debug/.gitignore b/bin/FreeBSD/Debug/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/bin/FreeBSD/Debug/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/bin/FreeBSD/Release/.gitignore b/bin/FreeBSD/Release/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/bin/FreeBSD/Release/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/bin/SDL/Debug/.gitignore b/bin/SDL/Debug/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/bin/SDL/Debug/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/bin/SDL/Release/.gitignore b/bin/SDL/Release/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/bin/SDL/Release/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/bin/WinCE/ARMV4Dbg/.gitignore b/bin/WinCE/ARMV4Dbg/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/bin/WinCE/ARMV4Dbg/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/bin/WinCE/ARMV4IDbg/.gitignore b/bin/WinCE/ARMV4IDbg/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/bin/WinCE/ARMV4IDbg/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/bin/WinCE/ARMV4IRel/.gitignore b/bin/WinCE/ARMV4IRel/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/bin/WinCE/ARMV4IRel/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/bin/WinCE/ARMV4Rel/.gitignore b/bin/WinCE/ARMV4Rel/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/bin/WinCE/ARMV4Rel/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/bin/WinCE/ARMV4TDbg/.gitignore b/bin/WinCE/ARMV4TDbg/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/bin/WinCE/ARMV4TDbg/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/bin/WinCE/ARMV4TRel/.gitignore b/bin/WinCE/ARMV4TRel/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/bin/WinCE/ARMV4TRel/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/bin/WinCE/MIPS16Dbg/.gitignore b/bin/WinCE/MIPS16Dbg/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/bin/WinCE/MIPS16Dbg/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/bin/WinCE/MIPS16Rel/.gitignore b/bin/WinCE/MIPS16Rel/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/bin/WinCE/MIPS16Rel/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/bin/WinCE/MIPSIIDbg/.gitignore b/bin/WinCE/MIPSIIDbg/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/bin/WinCE/MIPSIIDbg/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/bin/WinCE/MIPSIIRel/.gitignore b/bin/WinCE/MIPSIIRel/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/bin/WinCE/MIPSIIRel/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/bin/WinCE/MIPSII_FPDbg/.gitignore b/bin/WinCE/MIPSII_FPDbg/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/bin/WinCE/MIPSII_FPDbg/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/bin/WinCE/MIPSII_FPRel/.gitignore b/bin/WinCE/MIPSII_FPRel/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/bin/WinCE/MIPSII_FPRel/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/bin/WinCE/MIPSIVDbg/.gitignore b/bin/WinCE/MIPSIVDbg/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/bin/WinCE/MIPSIVDbg/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/bin/WinCE/MIPSIVRel/.gitignore b/bin/WinCE/MIPSIVRel/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/bin/WinCE/MIPSIVRel/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/bin/WinCE/MIPSIV_FPDbg/.gitignore b/bin/WinCE/MIPSIV_FPDbg/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/bin/WinCE/MIPSIV_FPDbg/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/bin/WinCE/MIPSIV_FPRel/.gitignore b/bin/WinCE/MIPSIV_FPRel/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/bin/WinCE/MIPSIV_FPRel/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/bin/WinCE/Release/.gitignore b/bin/WinCE/Release/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/bin/WinCE/Release/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/bin/WinCE/SH3Dbg/.gitignore b/bin/WinCE/SH3Dbg/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/bin/WinCE/SH3Dbg/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/bin/WinCE/SH3Rel/.gitignore b/bin/WinCE/SH3Rel/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/bin/WinCE/SH3Rel/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/bin/WinCE/SH4Dbg/.gitignore b/bin/WinCE/SH4Dbg/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/bin/WinCE/SH4Dbg/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/bin/WinCE/SH4Rel/.gitignore b/bin/WinCE/SH4Rel/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/bin/WinCE/SH4Rel/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/bin/WinCE/X86Dbg/.gitignore b/bin/WinCE/X86Dbg/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/bin/WinCE/X86Dbg/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/bin/WinCE/X86Rel/.gitignore b/bin/WinCE/X86Rel/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/bin/WinCE/X86Rel/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/bin/WinCE/emulatorDbg/.gitignore b/bin/WinCE/emulatorDbg/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/bin/WinCE/emulatorDbg/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/bin/WinCE/emulatorRel/.gitignore b/bin/WinCE/emulatorRel/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/bin/WinCE/emulatorRel/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/bin/dummy/.gitignore b/bin/dummy/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/bin/dummy/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/objs/FreeBSD/SDL/Debug/.gitignore b/objs/FreeBSD/SDL/Debug/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/objs/FreeBSD/SDL/Debug/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/objs/FreeBSD/SDL/Release/.gitignore b/objs/FreeBSD/SDL/Release/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/objs/FreeBSD/SDL/Release/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/objs/MasterClient/.gitignore b/objs/MasterClient/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/objs/MasterClient/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/objs/MasterServer/.gitignore b/objs/MasterServer/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/objs/MasterServer/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/objs/XBOX/SDL/Debug/.gitignore b/objs/XBOX/SDL/Debug/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/objs/XBOX/SDL/Debug/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/objs/XBOX/SDL/Release/.gitignore b/objs/XBOX/SDL/Release/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/objs/XBOX/SDL/Release/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/objs/cygwin/Debug/.gitignore b/objs/cygwin/Debug/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/objs/cygwin/Debug/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/objs/cygwin/Release/.gitignore b/objs/cygwin/Release/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/objs/cygwin/Release/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/objs/dummy/.gitignore b/objs/dummy/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/objs/dummy/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/src/Makefile b/src/Makefile index 27569b36c..1d4f8e01c 100644 --- a/src/Makefile +++ b/src/Makefile @@ -209,7 +209,13 @@ LIBS+=-lm endif ifdef SDL -include sdl/Makefile.cfg +#SDL 2.0 +ifndef SDL12 + include sdl/Makefile.cfg +#SDL 1.2 +else + include sdl12/Makefile.cfg +endif #ifndef SDL12 endif #ifdef SDL ifdef DISTCC diff --git a/src/Makefile.cfg b/src/Makefile.cfg index 5bf7f247d..317218397 100644 --- a/src/Makefile.cfg +++ b/src/Makefile.cfg @@ -7,6 +7,21 @@ # and other things # +ifdef GCC80 +GCC72=1 +endif + +ifdef GCC72 +GCC71=1 +endif + +ifdef GCC71 +GCC64=1 +endif + +ifdef GCC64 +GCC64=1 +endif ifdef GCC63 GCC62=1 @@ -322,22 +337,24 @@ ifdef MINGW64 BIN:=$(BIN)/Mingw64 else ifdef WII - INTERFACE=sdl + INTERFACE=sdl12 NONX86=1 STATIC=1 PREFIX?=powerpc-eabi SDL=1 + SDL12=1 SDLMAIN=1 OBJDIR:=$(OBJDIR)/Wii BIN:=$(BIN)/Wii NOUPX=1 else ifdef PS3N - INTERFACE=sdl + INTERFACE=sdl12 NONX86=1 STATIC=1 PREFIX?=ppu SDL=1 + SDL12=1 # unsure? #SDLMAIN=1 # can't compile SDL_mixer for ps3... @@ -352,34 +369,38 @@ ifdef MINGW BIN:=$(BIN)/Mingw else ifdef XBOX - INTERFACE=sdl + INTERFACE=sdl12 NASMFORMAT=win32 PREFIX?=/usr/local/openxdk/bin/i386-pc-xbox SDL=1 + SDL12=1 OBJDIR:=$(OBJDIR)/XBOX BIN:=$(BIN)/XBOX else ifdef PSP - INTERFACE=sdl + INTERFACE=sdl12 NONX86=1 SDL=1 + SDL12=1 OBJDIR:=$(OBJDIR)/PSP BIN:=$(BIN)/PSP NOUPX=1 else ifdef DC - INTERFACE=sdl + INTERFACE=sdl12 NONX86=1 SDL=1 + SDL12=1 OBJDIR:=$(OBJDIR)/DC BIN:=$(BIN)/DC NOUPX=1 else ifdef WINCE - INTERFACE=sdl + INTERFACE=sdl12 NONX86=1 PREFIX?=arm-wince-pe SDL=1 + SDL12=1 OBJDIR:=$(OBJDIR)/WinCE BIN:=$(BIN)/WinCE else @@ -404,6 +425,12 @@ endif endif endif +ifdef GP2X +ifdef SDL + SDL12=1 +endif +endif + ifdef ARCHNAME OBJDIR:=$(OBJDIR)/$(ARCHNAME) BIN:=$(BIN)/$(ARCHNAME) @@ -437,7 +464,13 @@ OBJDUMP_OPTS?=--wide --source --line-numbers LD=$(CC) ifdef SDL +# SDL 2.0 +ifndef SDL12 INTERFACE=sdl +# SDL 1.2 +else + INTERFACE=sdl12 +endif OBJDIR:=$(OBJDIR)/SDL endif diff --git a/src/b_bot.c b/src/b_bot.c index dc65c9c16..543bcb183 100644 --- a/src/b_bot.c +++ b/src/b_bot.c @@ -271,6 +271,12 @@ void B_RespawnBot(INT32 playernum) player->powers[pw_spacetime] = sonic->player->powers[pw_spacetime]; player->powers[pw_gravityboots] = sonic->player->powers[pw_gravityboots]; player->powers[pw_nocontrol] = sonic->player->powers[pw_nocontrol]; + player->acceleration = sonic->player->acceleration; + player->accelstart = sonic->player->accelstart; + player->thrustfactor = sonic->player->thrustfactor; + player->normalspeed = sonic->player->normalspeed; + player->pflags |= PF_AUTOBRAKE; + player->pflags &= ~PF_DIRECTIONCHAR; P_TeleportMove(tails, x, y, z); if (player->charability == CA_FLY) diff --git a/src/blua/ldebug.c b/src/blua/ldebug.c index 497d54980..542e209a1 100644 --- a/src/blua/ldebug.c +++ b/src/blua/ldebug.c @@ -412,7 +412,7 @@ static Instruction symbexec (const Proto *pt, int lastpc, int reg) { case OP_FORLOOP: case OP_FORPREP: checkreg(pt, a+3); - /* go through */ + /* FALLTHRU */ case OP_JMP: { int dest = pc+1+b; /* not full check and jump is forward and do not skip `lastpc'? */ diff --git a/src/blua/llex.c b/src/blua/llex.c index 0b328dcad..9e3dc2929 100644 --- a/src/blua/llex.c +++ b/src/blua/llex.c @@ -306,11 +306,12 @@ static void read_string (LexState *ls, int del, SemInfo *seminfo) { save_and_next(ls); /* skip $ */ seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + 1, luaZ_bufflen(ls->buff) - 2); - ls->refstr++; /* expect '\' anytime soon */ + ls->refstr++; /* expect '\' anytime soon */ lua_assert(ls->lookahead.token == TK_EOS); - ls->lookahead.token = TK_CONCAT; - return; - } + ls->lookahead.token = TK_CONCAT; + return; + } + /* FALLTHRU */ default: { if (!isdigit(ls->current)) save_and_next(ls); /* handles \\, \", \', and \? */ @@ -340,7 +341,8 @@ static void read_string (LexState *ls, int del, SemInfo *seminfo) { }; switch (i) { - case 4: save( ls, (c>>8) & 0xff ); // pass-through.. + case 4: save( ls, (c>>8) & 0xff ); + /* FALLTHRU */ case 2: save( ls, c&0xff ); break; case 5: @@ -350,7 +352,7 @@ static void read_string (LexState *ls, int del, SemInfo *seminfo) { } continue; - // "\u0000".."\x10FFFF": UTF-8 encoded Unicode + // "\u0000".."\x10FFFF": UTF-8 encoded Unicode // // Note that although codes are entered like this (must have min. four digit, // just to tease you!) the actual outcome in the string will vary between @@ -482,20 +484,22 @@ static int llex (LexState *ls, SemInfo *seminfo) { else if (sep == -1) return '['; else luaX_lexerror(ls, "invalid long string delimiter", TK_STRING); } + /* FALLTHRU */ case '=': { next(ls); if (ls->current != '=') return '='; else { next(ls); return TK_EQ; } } + /* FALLTHRU */ case '<': { next(ls); - if (ls->current == '<') { next(ls); return TK_SHL; } + if (ls->current == '<') { next(ls); return TK_SHL; } if (ls->current != '=') return '<'; else { next(ls); return TK_LE; } } case '>': { next(ls); - if (ls->current == '>') { next(ls); return TK_SHR; } + if (ls->current == '>') { next(ls); return TK_SHR; } if (ls->current != '=') return '>'; else { next(ls); return TK_GE; } } @@ -547,9 +551,10 @@ static int llex (LexState *ls, SemInfo *seminfo) { } case '\\': if (ls->refstr) { ls->refstr--; - ls->current = '"'; /* whacky! */ - return TK_CONCAT; + ls->current = '"'; /* whacky! */ + return TK_CONCAT; } + /* FALLTHRU */ default: { if (isspace(ls->current)) { lua_assert(!currIsNewline(ls)); diff --git a/src/blua/ltable.c b/src/blua/ltable.c index 9f4d91ff2..0ddd9ef4f 100644 --- a/src/blua/ltable.c +++ b/src/blua/ltable.c @@ -478,6 +478,7 @@ static TValue *newkey (lua_State *L, Table *t, const TValue *key) { return luaH_getnum(t, k); /* use specialized version */ /* else go through */ } + /* FALLTHRU */ default: { Node *n = mainposition(t, key); do { /* check whether `key' is somewhere in the chain */ diff --git a/src/command.c b/src/command.c index d72f845ad..3ffde94ad 100644 --- a/src/command.c +++ b/src/command.c @@ -1189,7 +1189,10 @@ finish: CONS_Printf(M_GetText("%s set to %s\n"), var->name, var->string); var->flags &= ~CV_SHOWMODIFONETIME; } - DEBFILE(va("%s set to %s\n", var->name, var->string)); + else // display message in debug file only + { + DEBFILE(va("%s set to %s\n", var->name, var->string)); + } var->flags |= CV_MODIFIED; // raise 'on change' code #ifdef HAVE_BLUA diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 3878d8795..6685cd5ee 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -51,7 +51,7 @@ #endif #ifdef _XBOX -#include "sdl/SRB2XBOX/xboxhelp.h" +#include "sdl12/SRB2XBOX/xboxhelp.h" #endif // @@ -1903,6 +1903,7 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic break; // exit the case cl_mode = CL_ASKJOIN; // don't break case continue to cljoin request now + /* FALLTHRU */ case CL_ASKJOIN: CL_LoadServerFiles(); @@ -2253,7 +2254,8 @@ static void Command_connect(void) CONS_Printf(M_GetText( "Connect (port): connect to a server\n" "Connect ANY: connect to the first lan server found\n" - "Connect SELF: connect to your own server.\n")); + //"Connect SELF: connect to your own server.\n" + )); return; } @@ -2267,7 +2269,7 @@ static void Command_connect(void) // we don't request a restart unless the filelist differs server = false; - +/* if (!stricmp(COM_Argv(1), "self")) { servernode = 0; @@ -2276,6 +2278,7 @@ static void Command_connect(void) //SV_SpawnServer(); } else +*/ { // used in menu to connect to a server in the list if (netgame && !stricmp(COM_Argv(1), "node")) @@ -2299,10 +2302,13 @@ static void Command_connect(void) if (!stricmp(COM_Argv(1), "any")) servernode = BROADCASTADDR; - else if (I_NetMakeNodewPort && COM_Argc() >= 3) - servernode = I_NetMakeNodewPort(COM_Argv(1), COM_Argv(2)); else if (I_NetMakeNodewPort) - servernode = I_NetMakeNode(COM_Argv(1)); + { + if (COM_Argc() >= 3) // address AND port + servernode = I_NetMakeNodewPort(COM_Argv(1), COM_Argv(2)); + else // address only, or address:port + servernode = I_NetMakeNode(COM_Argv(1)); + } else { CONS_Alert(CONS_ERROR, M_GetText("There is no server identification with this network driver\n")); @@ -3097,11 +3103,15 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum) secondarydisplayplayer = newplayernum; DEBFILE("spawning me\n"); // Apply player flags as soon as possible! - players[newplayernum].pflags &= ~(PF_FLIPCAM|PF_ANALOGMODE); + players[newplayernum].pflags &= ~(PF_FLIPCAM|PF_ANALOGMODE|PF_DIRECTIONCHAR|PF_AUTOBRAKE); if (cv_flipcam.value) players[newplayernum].pflags |= PF_FLIPCAM; if (cv_analog.value) players[newplayernum].pflags |= PF_ANALOGMODE; + if (cv_directionchar.value) + players[newplayernum].pflags |= PF_DIRECTIONCHAR; + if (cv_autobrake.value) + players[newplayernum].pflags |= PF_AUTOBRAKE; } else { @@ -3110,11 +3120,15 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum) if (botingame) players[newplayernum].bot = 1; // Same goes for player 2 when relevant - players[newplayernum].pflags &= ~(PF_FLIPCAM|PF_ANALOGMODE); + players[newplayernum].pflags &= ~(PF_FLIPCAM|PF_ANALOGMODE|PF_DIRECTIONCHAR|PF_AUTOBRAKE); if (cv_flipcam2.value) players[newplayernum].pflags |= PF_FLIPCAM; if (cv_analog2.value) players[newplayernum].pflags |= PF_ANALOGMODE; + if (cv_directionchar2.value) + players[newplayernum].pflags |= PF_DIRECTIONCHAR; + if (cv_autobrake2.value) + players[newplayernum].pflags |= PF_AUTOBRAKE; } D_SendPlayerConfig(); addedtogame = true; @@ -3622,6 +3636,7 @@ static void HandlePacketFromAwayNode(SINT8 node) // Do not remove my own server (we have just get a out of order packet) if (node == servernode) break; + /* FALLTHRU */ default: DEBFILE(va("unknown packet received (%d) from unknown host\n",netbuffer->packettype)); @@ -3778,6 +3793,7 @@ FILESTAMP break; case PT_TEXTCMD2: // splitscreen special netconsole = nodetoplayer2[node]; + /* FALLTHRU */ case PT_TEXTCMD: if (client) break; @@ -4132,7 +4148,10 @@ static INT16 Consistancy(void) #ifdef MOBJCONSISTANCY if (!thinkercap.next) + { + DEBFILE(va("Consistancy = %u\n", ret)); return ret; + } for (th = thinkercap.next; th != &thinkercap; th = th->next) { if (th->function.acp1 != (actionf_p1)P_MobjThinker) @@ -4201,6 +4220,8 @@ static INT16 Consistancy(void) } #endif + DEBFILE(va("Consistancy = %u\n", (ret & 0xFFFF))); + return (INT16)(ret & 0xFFFF); } diff --git a/src/d_main.c b/src/d_main.c index 27ab71641..87a314d3f 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -83,7 +83,7 @@ int snprintf(char *str, size_t n, const char *fmt, ...); #endif #ifdef _XBOX -#include "sdl/SRB2XBOX/xboxhelp.h" +#include "sdl12/SRB2XBOX/xboxhelp.h" #endif #ifdef HWRENDER @@ -301,7 +301,7 @@ static void D_Display(void) if (rendermode != render_none) { // Fade to black first - if (gamestate != GS_LEVEL // fades to black on its own timing, always + if (!(gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction)) // fades to black on its own timing, always && wipedefs[wipedefindex] != UINT8_MAX) { F_WipeStartScreen(); @@ -317,6 +317,12 @@ static void D_Display(void) // do buffered drawing switch (gamestate) { + case GS_TITLESCREEN: + if (!titlemapinaction) { + F_TitleScreenDrawer(); + break; + } + // Intentional fall-through case GS_LEVEL: if (!gametic) break; @@ -365,10 +371,6 @@ static void D_Display(void) HU_Drawer(); break; - case GS_TITLESCREEN: - F_TitleScreenDrawer(); - break; - case GS_WAITINGPLAYERS: // The clientconnect drawer is independent... case GS_DEDICATEDSERVER: @@ -378,9 +380,10 @@ static void D_Display(void) // clean up border stuff // see if the border needs to be initially drawn - if (gamestate == GS_LEVEL) + if (gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction)) { // draw the view directly + if (!automapactive && !dedicated && cv_renderview.value) { if (players[displayplayer].mo || players[displayplayer].playerstate == PST_DEAD) @@ -438,9 +441,13 @@ static void D_Display(void) lastdraw = false; } - ST_Drawer(); - - HU_Drawer(); + if (gamestate == GS_LEVEL) + { + ST_Drawer(); + HU_Drawer(); + } + else + F_TitleScreenDrawer(); } // change gamma if needed @@ -680,6 +687,9 @@ void D_AdvanceDemo(void) void D_StartTitle(void) { INT32 i; + + S_StopMusic(); + if (netgame) { if (gametype == GT_COOP) @@ -1341,6 +1351,19 @@ void D_SRB2Main(void) ultimatemode = true; } + // rei/miru: bootmap (Idea: starts the game on a predefined map) + if (bootmap && !(M_CheckParm("-warp") && M_IsNextParm())) + { + pstartmap = bootmap; + + if (pstartmap < 1 || pstartmap > NUMMAPS) + I_Error("Cannot warp to map %d (out of range)\n", pstartmap); + else + { + autostart = true; + } + } + if (autostart || netgame || M_CheckParm("+connect") || M_CheckParm("-connect")) { gameaction = ga_nothing; diff --git a/src/d_net.c b/src/d_net.c index 48c1d60ea..8de5cf088 100644 --- a/src/d_net.c +++ b/src/d_net.c @@ -1030,6 +1030,7 @@ boolean HSendPacket(INT32 node, boolean reliable, UINT8 acknum, size_t packetlen #endif return false; } + netbuffer->ack = netbuffer->ackreturn = 0; // don't hold over values from last packet sent/received M_Memcpy(&reboundstore[rebound_head], netbuffer, doomcom->datalength); reboundsize[rebound_head] = doomcom->datalength; @@ -1365,7 +1366,7 @@ boolean D_CheckNetGame(void) #else if (M_CheckParm("-debugfile")) { - char filename[20]; + char filename[21]; INT32 k = doomcom->consoleplayer - 1; if (M_IsNextParm()) k = atoi(M_GetNextParm()) - 1; diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 4c9ed9625..4a22245a2 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -771,6 +771,12 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_useranalog); CV_RegisterVar(&cv_useranalog2); + // deez New User eXperiences + CV_RegisterVar(&cv_directionchar); + CV_RegisterVar(&cv_directionchar2); + CV_RegisterVar(&cv_autobrake); + CV_RegisterVar(&cv_autobrake2); + // s_sound.c CV_RegisterVar(&cv_soundvolume); CV_RegisterVar(&cv_closedcaptioning); @@ -1433,6 +1439,10 @@ void SendWeaponPref(void) buf[0] |= 1; if (players[consoleplayer].pflags & PF_ANALOGMODE) buf[0] |= 2; + if (players[consoleplayer].pflags & PF_DIRECTIONCHAR) + buf[0] |= 4; + if (players[consoleplayer].pflags & PF_AUTOBRAKE) + buf[0] |= 8; SendNetXCmd(XD_WEAPONPREF, buf, 1); } @@ -1445,6 +1455,10 @@ void SendWeaponPref2(void) buf[0] |= 1; if (players[secondarydisplayplayer].pflags & PF_ANALOGMODE) buf[0] |= 2; + if (players[secondarydisplayplayer].pflags & PF_DIRECTIONCHAR) + buf[0] |= 4; + if (players[secondarydisplayplayer].pflags & PF_AUTOBRAKE) + buf[0] |= 8; SendNetXCmd2(XD_WEAPONPREF, buf, 1); } @@ -1452,11 +1466,15 @@ static void Got_WeaponPref(UINT8 **cp,INT32 playernum) { UINT8 prefs = READUINT8(*cp); - players[playernum].pflags &= ~(PF_FLIPCAM|PF_ANALOGMODE); + players[playernum].pflags &= ~(PF_FLIPCAM|PF_ANALOGMODE|PF_DIRECTIONCHAR|PF_AUTOBRAKE); if (prefs & 1) players[playernum].pflags |= PF_FLIPCAM; if (prefs & 2) players[playernum].pflags |= PF_ANALOGMODE; + if (prefs & 4) + players[playernum].pflags |= PF_DIRECTIONCHAR; + if (prefs & 8) + players[playernum].pflags |= PF_AUTOBRAKE; } void D_SendPlayerConfig(void) @@ -2508,7 +2526,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum) error = true; break; } - //fall down + /* FALLTHRU */ case GT_TAG: switch (NetPacket.packet.newteam) { @@ -2572,12 +2590,12 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum) { players[playernum].spectator = true; players[playernum].pflags &= ~PF_TAGIT; - players[playernum].pflags &= ~PF_TAGGED; + players[playernum].pflags &= ~PF_GAMETYPEOVER; } else if (NetPacket.packet.newteam != 3) // .newteam == 1 or 2. { players[playernum].spectator = false; - players[playernum].pflags &= ~PF_TAGGED;//Just in case. + players[playernum].pflags &= ~PF_GAMETYPEOVER; //Just in case. if (NetPacket.packet.newteam == 1) //Make the player IT. players[playernum].pflags |= PF_TAGIT; diff --git a/src/d_player.h b/src/d_player.h index d578d15ef..bf0b303b8 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -98,66 +98,58 @@ typedef enum // typedef enum { - // Flip camera angle with gravity flip prefrence. - PF_FLIPCAM = 1, + // Cvars + PF_FLIPCAM = 1, // Flip camera angle with gravity flip prefrence. + PF_ANALOGMODE = 1<<1, // Analog mode? + PF_DIRECTIONCHAR = 1<<2, // Directional character sprites? + PF_AUTOBRAKE = 1<<3, // Autobrake? // Cheats - PF_GODMODE = 1<<1, - PF_NOCLIP = 1<<2, - PF_INVIS = 1<<3, + PF_GODMODE = 1<<4, + PF_NOCLIP = 1<<5, + PF_INVIS = 1<<6, // True if button down last tic. - PF_ATTACKDOWN = 1<<4, - PF_USEDOWN = 1<<5, - PF_JUMPDOWN = 1<<6, - PF_WPNDOWN = 1<<7, + PF_ATTACKDOWN = 1<<7, + PF_USEDOWN = 1<<8, + PF_JUMPDOWN = 1<<9, + PF_WPNDOWN = 1<<10, // Unmoving states - PF_STASIS = 1<<8, // Player is not allowed to move - PF_JUMPSTASIS = 1<<9, // and that includes jumping. + PF_STASIS = 1<<11, // Player is not allowed to move + PF_JUMPSTASIS = 1<<12, // and that includes jumping. PF_FULLSTASIS = PF_STASIS|PF_JUMPSTASIS, - // Did you get a time-over? - PF_TIMEOVER = 1<<10, + // Applying autobrake? + PF_APPLYAUTOBRAKE = 1<<13, // Character action status - PF_STARTJUMP = 1<<11, - PF_JUMPED = 1<<12, - PF_SPINNING = 1<<13, - PF_STARTDASH = 1<<14, - PF_THOKKED = 1<<15, + PF_STARTJUMP = 1<<14, + PF_JUMPED = 1<<15, + PF_NOJUMPDAMAGE = 1<<16, - // Are you gliding? - PF_GLIDING = 1<<16, + PF_SPINNING = 1<<17, + PF_STARTDASH = 1<<18, + + PF_THOKKED = 1<<19, + PF_SHIELDABILITY = 1<<20, + PF_GLIDING = 1<<21, + PF_BOUNCING = 1<<22, // Sliding (usually in water) like Labyrinth/Oil Ocean - PF_SLIDING = 1<<17, + PF_SLIDING = 1<<23, - // Bouncing - PF_BOUNCING = 1<<18, + // NiGHTS stuff + PF_TRANSFERTOCLOSEST = 1<<24, + PF_DRILLING = 1<<25, - /*** NIGHTS STUFF ***/ - PF_TRANSFERTOCLOSEST = 1<<19, - PF_NIGHTSFALL = 1<<20, - PF_DRILLING = 1<<21, - PF_SKIDDOWN = 1<<22, - - /*** TAG STUFF ***/ - PF_TAGGED = 1<<23, // Player has been tagged and awaits the next round in hide and seek. - PF_TAGIT = 1<<24, // The player is it! For Tag Mode + // Gametype-specific stuff + PF_GAMETYPEOVER = 1<<26, // Race time over, or H&S out-of-game + PF_TAGIT = 1<<27, // The player is it! For Tag Mode /*** misc ***/ - PF_FORCESTRAFE = 1<<25, // Turning inputs are translated into strafing inputs - PF_ANALOGMODE = 1<<26, // Analog mode? - - // Can carry another player? - PF_CANCARRY = 1<<27, - - // Used shield ability - PF_SHIELDABILITY = 1<<28, - - // Jump damage? - PF_NOJUMPDAMAGE = 1<<29, + PF_FORCESTRAFE = 1<<28, // Turning inputs are translated into strafing inputs + PF_CANCARRY = 1<<29, // Can carry another player? // up to 1<<31 is free } pflags_t; @@ -234,6 +226,7 @@ typedef enum CR_PLAYER, // NiGHTS mode. Not technically a CARRYING, but doesn't stack with any of the others, so might as well go here. CR_NIGHTSMODE, + CR_NIGHTSFALL, // Old Brak sucks hard, but this gimmick could be used for something better, so we might as well continue supporting it. CR_BRAKGOOP, // Specific level gimmicks. @@ -254,6 +247,7 @@ typedef enum pw_underwater, // underwater timer pw_spacetime, // In space, no one can hear you spin! pw_extralife, // Extra Life timer + pw_pushing, pw_super, // Are you super? pw_gravityboots, // gravity boots @@ -326,6 +320,9 @@ typedef struct player_s // It is updated with cmd->aiming. angle_t aiming; + // fun thing for player sprite + angle_t drawangle; + // player's ring count INT32 rings; diff --git a/src/dehacked.c b/src/dehacked.c index 719476543..cddbd1a0e 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -11,6 +11,7 @@ /// \brief Load dehacked file and change tables and text #include "doomdef.h" +#include "d_main.h" // for srb2home #include "g_game.h" #include "sounds.h" #include "info.h" @@ -64,6 +65,7 @@ memset(used_spr,0,sizeof(UINT8) * ((NUMSPRITEFREESLOTS / 8) + 1));\ static mobjtype_t get_mobjtype(const char *word); static statenum_t get_state(const char *word); static spritenum_t get_sprite(const char *word); +static playersprite_t get_sprite2(const char *word); static sfxenum_t get_sfx(const char *word); #ifdef MUSICSLOT_COMPATIBILITY static UINT16 get_mus(const char *word, UINT8 dehacked_mode); @@ -77,6 +79,8 @@ boolean deh_loaded = false; static int dbg_line; static boolean gamedataadded = false; +static boolean titlechanged = false; +static boolean introchanged = false; ATTRINLINE static FUNCINLINE char myfget_color(MYFILE *f) { @@ -769,6 +773,49 @@ static void readspritelight(MYFILE *f, INT32 num) } #endif // HWRENDER +static void readsprite2(MYFILE *f, INT32 num) +{ + char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); + char *word, *word2; + char *tmp; + + do + { + if (myfgets(s, MAXLINELEN, f)) + { + if (s[0] == '\n') + break; + + tmp = strchr(s, '#'); + if (tmp) + *tmp = '\0'; + if (s == tmp) + continue; // Skip comment lines, but don't break. + + word = strtok(s, " "); + if (word) + strupr(word); + else + break; + + word2 = strtok(NULL, " = "); + if (word2) + strupr(word2); + else + break; + if (word2[strlen(word2)-1] == '\n') + word2[strlen(word2)-1] = '\0'; + + if (fastcmp(word, "DEFAULT")) + spr2defaults[num] = get_number(word2); + else + deh_warning("Sprite2 %s: unknown word '%s'", spr2names[num], word); + } + } while (!myfeof(f)); // finish when the line is empty + + Z_Free(s); +} + static const struct { const char *name; const UINT16 flag; @@ -2667,14 +2714,36 @@ static void readmaincfg(MYFILE *f) // range check, you morons. if (introtoplay > 128) introtoplay = 128; + introchanged = true; } else if (fastcmp(word, "LOOPTITLE")) { looptitle = (boolean)(value || word2[0] == 'T' || word2[0] == 'Y'); + titlechanged = true; + } + else if (fastcmp(word, "TITLEMAP")) + { + // Support using the actual map name, + // i.e., Level AB, Level FZ, etc. + + // Convert to map number + if (word2[0] >= 'A' && word2[0] <= 'Z') + value = M_MapNumber(word2[0], word2[1]); + else + value = get_number(word2); + + titlemap = (INT16)value; + titlechanged = true; + } + else if (fastcmp(word, "HIDETITLEPICS")) + { + hidetitlepics = (boolean)(value || word2[0] == 'T' || word2[0] == 'Y'); + titlechanged = true; } else if (fastcmp(word, "TITLESCROLLSPEED")) { titlescrollspeed = get_number(word2); + titlechanged = true; } else if (fastcmp(word, "CREDITSCUTSCENE")) { @@ -2690,14 +2759,17 @@ static void readmaincfg(MYFILE *f) else if (fastcmp(word, "NUMDEMOS")) { numDemos = (UINT8)get_number(word2); + titlechanged = true; } else if (fastcmp(word, "DEMODELAYTIME")) { demoDelayTime = get_number(word2); + titlechanged = true; } else if (fastcmp(word, "DEMOIDLETIME")) { demoIdleTime = get_number(word2); + titlechanged = true; } else if (fastcmp(word, "USE1UPSOUND")) { @@ -2729,16 +2801,35 @@ static void readmaincfg(MYFILE *f) strncpy(savegamename, timeattackfolder, sizeof (timeattackfolder)); strlcat(savegamename, "%u.ssg", sizeof(savegamename)); + // can't use sprintf since there is %u in savegamename + strcatbf(savegamename, srb2home, PATHSEP); gamedataadded = true; + titlechanged = true; } else if (fastcmp(word, "RESETDATA")) { P_ResetData(value); + titlechanged = true; } else if (fastcmp(word, "CUSTOMVERSION")) { strlcpy(customversionstring, word2, sizeof (customversionstring)); + //titlechanged = true; + } + else if (fastcmp(word, "BOOTMAP")) + { + // Support using the actual map name, + // i.e., Level AB, Level FZ, etc. + + // Convert to map number + if (word2[0] >= 'A' && word2[0] <= 'Z') + value = M_MapNumber(word2[0], word2[1]); + else + value = get_number(word2); + + bootmap = (INT16)value; + //titlechanged = true; } else deh_warning("Maincfg: unknown word '%s'", word); @@ -2935,7 +3026,7 @@ static void DEH_LoadDehackedFile(MYFILE *f) deh_num_warning = 0; - gamedataadded = false; + gamedataadded = titlechanged = introchanged = false; // it doesn't test the version of SRB2 and version of dehacked file dbg_line = -1; // start at -1 so the first line is 0. @@ -3020,9 +3111,21 @@ static void DEH_LoadDehackedFile(MYFILE *f) ignorelines(f); } } + else if (fastcmp(word, "SPRITE2")) + { + if (i == 0 && word2[0] != '0') // If word2 isn't a number + i = get_sprite2(word2); // find a sprite by name + if (i < (INT32)free_spr2 && i >= (INT32)SPR2_FIRSTFREESLOT) + readsprite2(f, i); + else + { + deh_warning("Sprite2 number %d out of range (%d - %d)", i, SPR2_FIRSTFREESLOT, free_spr2-1); + ignorelines(f); + } + } +#ifdef HWRENDER else if (fastcmp(word, "LIGHT")) { -#ifdef HWRENDER // TODO: Read lights by name if (i > 0 && i < NUMLIGHTS) readlight(f, i); @@ -3031,22 +3134,20 @@ static void DEH_LoadDehackedFile(MYFILE *f) deh_warning("Light number %d out of range (1 - %d)", i, NUMLIGHTS-1); ignorelines(f); } -#endif } else if (fastcmp(word, "SPRITE")) { -#ifdef HWRENDER if (i == 0 && word2[0] != '0') // If word2 isn't a number i = get_sprite(word2); // find a sprite by name - if (i < NUMSPRITES && i >= 0) + if (i < NUMSPRITES && i > 0) readspritelight(f, i); else { deh_warning("Sprite number %d out of range (0 - %d)", i, NUMSPRITES-1); ignorelines(f); } -#endif } +#endif else if (fastcmp(word, "LEVEL")) { // Support using the actual map name, @@ -3236,6 +3337,14 @@ static void DEH_LoadDehackedFile(MYFILE *f) if (gamedataadded) G_LoadGameData(); + if (gamestate == GS_TITLESCREEN) + { + if (introchanged) + COM_BufAddText("playintro"); + else if (titlechanged) + COM_BufAddText("exitgame"); // Command_ExitGame_f() but delayed + } + dbg_line = -1; if (deh_num_warning) { @@ -3302,6 +3411,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_PLAY_STND", "S_PLAY_WAIT", "S_PLAY_WALK", + "S_PLAY_SKID", "S_PLAY_RUN", "S_PLAY_DASH", "S_PLAY_PAIN", @@ -6422,8 +6532,12 @@ static const char *const MAPTHINGFLAG_LIST[4] = { #endif static const char *const PLAYERFLAG_LIST[] = { - // Flip camera angle with gravity flip prefrence. - "FLIPCAM", + + // Cvars + "FLIPCAM", // Flip camera angle with gravity flip prefrence. + "ANALOGMODE", // Analog mode? + "DIRECTIONCHAR", // Directional character sprites? + "AUTOBRAKE", // Autobrake? // Cheats "GODMODE", @@ -6441,41 +6555,36 @@ static const char *const PLAYERFLAG_LIST[] = { "JUMPSTASIS", // and that includes jumping. // (we don't include FULLSTASIS here I guess because it's just those two together...?) - // Did you get a time-over? - "TIMEOVER", + // Applying autobrake? + "APPLYAUTOBRAKE", // Character action status "STARTJUMP", "JUMPED", + "NOJUMPDAMAGE", + "SPINNING", "STARTDASH", - "THOKKED", - // Are you gliding? + "THOKKED", + "SHIELDABILITY", "GLIDING", + "BOUNCING", // Sliding (usually in water) like Labyrinth/Oil Ocean "SLIDING", - // Bouncing - "BOUNCING", - - /*** NIGHTS STUFF ***/ + // NiGHTS stuff "TRANSFERTOCLOSEST", - "NIGHTSFALL", "DRILLING", - "SKIDDOWN", - /*** TAG STUFF ***/ - "TAGGED", // Player has been tagged and awaits the next round in hide and seek. + // Gametype-specific stuff + "GAMETYPEOVER", // Race time over, or H&S out-of-game "TAGIT", // The player is it! For Tag Mode /*** misc ***/ "FORCESTRAFE", // Translate turn inputs into strafe inputs - "ANALOGMODE", // Analog mode? "CANCARRY", // Can carry? - "SHIELDABILITY", // Thokked with shield ability - "NOJUMPDAMAGE", // No jump damage NULL // stop loop here. }; @@ -6641,6 +6750,7 @@ static const char *const POWERS_LIST[] = { "UNDERWATER", // underwater timer "SPACETIME", // In space, no one can hear you spin! "EXTRALIFE", // Extra Life timer + "PUSHING", "SUPER", // Are you super? "GRAVITYBOOTS", // gravity boots @@ -6891,6 +7001,7 @@ struct { {"CR_GENERIC",CR_GENERIC}, {"CR_PLAYER",CR_PLAYER}, {"CR_NIGHTSMODE",CR_NIGHTSMODE}, + {"CR_NIGHTSFALL",CR_NIGHTSFALL}, {"CR_BRAKGOOP",CR_BRAKGOOP}, {"CR_ZOOMTUBE",CR_ZOOMTUBE}, {"CR_ROPEHANG",CR_ROPEHANG}, @@ -6963,7 +7074,7 @@ struct { {"ME_ALLEMERALDS",ME_ALLEMERALDS}, {"ME_ULTIMATE",ME_ULTIMATE}, {"ME_PERFECT",ME_PERFECT}, - + #ifdef HAVE_BLUA // p_local.h constants {"FLOATSPEED",FLOATSPEED}, @@ -7290,6 +7401,20 @@ static spritenum_t get_sprite(const char *word) return SPR_NULL; } +static playersprite_t get_sprite2(const char *word) +{ // Returns the value of SPR2_ enumerations + playersprite_t i; + if (*word >= '0' && *word <= '9') + return atoi(word); + if (fastncmp("SPR2_",word,5)) + word += 5; // take off the SPR2_ + for (i = 0; i < NUMPLAYERSPRITES; i++) + if (!spr2names[i][4] && memcmp(word,spr2names[i],4)==0) + return i; + deh_warning("Couldn't find sprite named 'SPR2_%s'",word); + return SPR2_STND; +} + static sfxenum_t get_sfx(const char *word) { // Returns the value of SFX_ enumerations sfxenum_t i; @@ -7735,7 +7860,7 @@ static inline int lib_freeslot(lua_State *L) else if (fastcmp(type, "SPR2")) { // Search if we already have an SPR2 by that name... - enum playersprite i; + playersprite_t i; for (i = SPR2_FIRSTFREESLOT; i < free_spr2; i++) if (memcmp(spr2names[i],word,4) == 0) break; @@ -7914,7 +8039,7 @@ static inline int lib_getenum(lua_State *L) if (mathlib) return luaL_error(L, "sprite '%s' could not be found.\n", word); return 0; } - else if (fastncmp("SPR2_",word,4)) { + else if (fastncmp("SPR2_",word,5)) { p = word+5; for (i = 0; i < (fixed_t)free_spr2; i++) if (!spr2names[i][4]) @@ -8119,6 +8244,12 @@ static inline int lib_getenum(lua_State *L) } else if (fastcmp(word,"paused")) { lua_pushboolean(L, paused); return 1; + } else if (fastcmp(word,"titlemap")) { + lua_pushinteger(L, titlemap); + return 1; + } else if (fastcmp(word,"titlemapinaction")) { + lua_pushboolean(L, (titlemapinaction != TITLEMAP_OFF)); + return 1; } else if (fastcmp(word,"gametype")) { lua_pushinteger(L, gametype); return 1; diff --git a/src/doomstat.h b/src/doomstat.h index a24bad79d..0d763a5a9 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -45,6 +45,10 @@ extern INT32 cursaveslot; extern INT16 lastmaploaded; extern boolean gamecomplete; +#define maxgameovers 13 +extern UINT8 numgameovers; +extern SINT8 startinglivesbalance[maxgameovers+1]; + #define PRECIP_NONE 0 #define PRECIP_STORM 1 #define PRECIP_SNOW 2 @@ -125,6 +129,10 @@ extern INT16 spstage_start; extern INT16 sstage_start; extern INT16 sstage_end; +extern INT16 titlemap; +extern boolean hidetitlepics; +extern INT16 bootmap; //bootmap for loading a map on startup + extern boolean looptitle; extern boolean useNightsSS; diff --git a/src/f_finale.c b/src/f_finale.c index db497daf7..05c3d5fc0 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -31,11 +31,18 @@ #include "m_random.h" #include "y_inter.h" #include "m_cond.h" +#include "p_local.h" +#include "p_setup.h" + +#ifdef HAVE_BLUA +#include "lua_hud.h" +#endif // Stage of animation: // 0 = text, 1 = art screen static INT32 finalecount; INT32 titlescrollspeed = 80; +UINT8 titlemapinaction = TITLEMAP_OFF; static INT32 timetonext; // Delay between screen changes static INT32 continuetime; // Short delay when continuing @@ -217,17 +224,19 @@ static void F_SkyScroll(INT32 scrollspeed) { INT32 scrolled, x, mx, fakedwidth; patch_t *pat; + INT16 patwidth; pat = W_CachePatchName("TITLESKY", PU_CACHE); - animtimer = ((finalecount*scrollspeed)/16) % SHORT(pat->width); + patwidth = SHORT(pat->width); + animtimer = ((finalecount*scrollspeed)/16 + patwidth) % patwidth; fakedwidth = vid.width / vid.dupx; if (rendermode == render_soft) { // if only hardware rendering could be this elegant and complete - scrolled = (SHORT(pat->width) - animtimer) - 1; - for (x = 0, mx = scrolled; x < fakedwidth; x++, mx = (mx+1)%SHORT(pat->width)) + scrolled = (patwidth - animtimer) - 1; + for (x = 0, mx = scrolled; x < fakedwidth; x++, mx = (mx+1)%patwidth) F_DrawPatchCol(x, pat, mx); } #ifdef HWRENDER @@ -235,8 +244,8 @@ static void F_SkyScroll(INT32 scrollspeed) { // if only software rendering could be this simple and retarded scrolled = animtimer; if (scrolled > 0) - V_DrawScaledPatch(scrolled - SHORT(pat->width), 0, 0, pat); - for (x = 0; x < fakedwidth; x += SHORT(pat->width)) + V_DrawScaledPatch(scrolled - patwidth, 0, 0, pat); + for (x = 0; x < fakedwidth; x += patwidth) V_DrawScaledPatch(x + scrolled, 0, 0, pat); } #endif @@ -278,6 +287,8 @@ void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean reset void F_StartIntro(void) { + S_StopMusic(); + if (introtoplay) { if (!cutscenes[introtoplay - 1]) @@ -998,7 +1009,7 @@ static const char *credits[] = { "", "\1Sprite Artists", "Odi \"Iceman404\" Atunzu", - "Victor \"VAdaPEGA\" Ara\x1Fjo", // Araújo -- sorry for our limited font! D: + "Victor \"VAdaPEGA\" Ara\x1Fjo", // Araújo -- sorry for our limited font! D: "Jim \"MotorRoach\" DeMello", "Desmond \"Blade\" DesJardins", "Sherman \"CoatRack\" DesJardins", @@ -1114,7 +1125,7 @@ void F_StartCredits(void) M_ClearMenus(true); // Save the second we enter the credits - if ((!modifiedgame || savemoddata) && !(netgame || multiplayer) && cursaveslot >= 0) + if ((!modifiedgame || savemoddata) && !(netgame || multiplayer) && cursaveslot > 0) G_SaveGame((UINT32)cursaveslot); if (creditscutscene) @@ -1252,7 +1263,7 @@ static boolean drawemblem = false, drawchaosemblem = false; void F_StartGameEvaluation(void) { // Credits option in secrets menu - if (cursaveslot == -2) + if (cursaveslot == -1) { F_StartGameEnd(); return; @@ -1266,7 +1277,7 @@ void F_StartGameEvaluation(void) // Save the second we enter the evaluation // We need to do this again! Remember, it's possible a mod designed skipped // the credits sequence! - if ((!modifiedgame || savemoddata) && !(netgame || multiplayer) && cursaveslot >= 0) + if ((!modifiedgame || savemoddata) && !(netgame || multiplayer) && cursaveslot > 0) G_SaveGame((UINT32)cursaveslot); gameaction = ga_nothing; @@ -1415,17 +1426,72 @@ void F_GameEndTicker(void) // ============== void F_StartTitleScreen(void) { + S_ChangeMusicInternal("_title", looptitle); + if (gamestate != GS_TITLESCREEN && gamestate != GS_WAITINGPLAYERS) finalecount = 0; else wipegamestate = GS_TITLESCREEN; + + if (titlemap) + { + mapthing_t *startpos; + + gamestate_t prevwipegamestate = wipegamestate; + titlemapinaction = TITLEMAP_LOADING; + gamemap = titlemap; + + if (!mapheaderinfo[gamemap-1]) + P_AllocMapHeader(gamemap-1); + + maptol = mapheaderinfo[gamemap-1]->typeoflevel; + globalweather = mapheaderinfo[gamemap-1]->weather; + + G_DoLoadLevel(true); + if (!titlemap) + return; + + players[displayplayer].playerstate = PST_DEAD; // Don't spawn the player in dummy (I'm still a filthy cheater) + + // Set Default Position + if (playerstarts[0]) + startpos = playerstarts[0]; + else if (deathmatchstarts[0]) + startpos = deathmatchstarts[0]; + else + startpos = NULL; + + if (startpos) + { + camera.x = startpos->x << FRACBITS; + camera.y = startpos->y << FRACBITS; + camera.subsector = R_PointInSubsector(camera.x, camera.y); + camera.z = camera.subsector->sector->floorheight + ((startpos->options >> ZSHIFT) << FRACBITS); + camera.angle = (startpos->angle % 360)*ANG1; + camera.aiming = 0; + } + else + { + camera.x = camera.y = camera.z = camera.angle = camera.aiming = 0; + camera.subsector = NULL; // toast is filthy too + } + + camera.chase = true; + camera.height = 0; + + wipegamestate = prevwipegamestate; + } + else + { + titlemapinaction = TITLEMAP_OFF; + gamemap = 1; // g_game.c + CON_ClearHUD(); + } + G_SetGamestate(GS_TITLESCREEN); - CON_ClearHUD(); // IWAD dependent stuff. - S_ChangeMusicInternal("_title", looptitle); - animtimer = 0; demoDelayLeft = demoDelayTime; @@ -1455,12 +1521,21 @@ void F_TitleScreenDrawer(void) return; // We likely came here from retrying. Don't do a damn thing. // Draw that sky! - F_SkyScroll(titlescrollspeed); + if (!titlemapinaction) + F_SkyScroll(titlescrollspeed); // Don't draw outside of the title screewn, or if the patch isn't there. if (!ttwing || (gamestate != GS_TITLESCREEN && gamestate != GS_WAITINGPLAYERS)) return; + // rei|miru: use title pics? + if (hidetitlepics) +#ifdef HAVE_BLUA + goto luahook; +#else + return; +#endif + V_DrawScaledPatch(30, 14, 0, ttwing); if (finalecount < 57) @@ -1497,6 +1572,11 @@ void F_TitleScreenDrawer(void) } V_DrawScaledPatch(48, 142, 0,ttbanner); + +#ifdef HAVE_BLUA +luahook: + LUAh_TitleHUD(); +#endif } // (no longer) De-Demo'd Title Screen @@ -1509,6 +1589,46 @@ void F_TitleScreenTicker(boolean run) if (gameaction != ga_nothing || gamestate != GS_TITLESCREEN) return; + // Execute the titlemap camera settings + if (titlemapinaction) + { + thinker_t *th; + mobj_t *mo2; + mobj_t *cameraref = NULL; + + for (th = thinkercap.next; th != &thinkercap; th = th->next) + { + if (th->function.acp1 != (actionf_p1)P_MobjThinker) // Not a mobj thinker + continue; + + mo2 = (mobj_t *)th; + + if (!mo2) + continue; + + if (mo2->type != MT_ALTVIEWMAN) + continue; + + cameraref = mo2; + break; + } + + if (cameraref) + { + camera.x = cameraref->x; + camera.y = cameraref->y; + camera.z = cameraref->z; + camera.angle = cameraref->angle; + camera.aiming = cameraref->cusval; + camera.subsector = cameraref->subsector; + } + else + { + // Default behavior: Do a lil' camera spin if a title map is loaded; + camera.angle += titlescrollspeed*ANG1/64; + } + } + // no demos to play? or, are they disabled? if (!cv_rollingdemos.value || !numDemos) return; diff --git a/src/f_finale.h b/src/f_finale.h index 1f23643be..aadc64ad0 100644 --- a/src/f_finale.h +++ b/src/f_finale.h @@ -62,6 +62,15 @@ void F_ContinueDrawer(void); extern INT32 titlescrollspeed; +typedef enum +{ + TITLEMAP_OFF = 0, + TITLEMAP_LOADING, + TITLEMAP_RUNNING +} titlemap_enum; + +extern UINT8 titlemapinaction; + // // WIPE // diff --git a/src/f_wipe.c b/src/f_wipe.c index acc4efaaa..49ab9cc01 100644 --- a/src/f_wipe.c +++ b/src/f_wipe.c @@ -94,7 +94,7 @@ static fixed_t paldiv = 0; * \return fademask_t for lump */ static fademask_t *F_GetFadeMask(UINT8 masknum, UINT8 scrnnum) { - static char lumpname[9] = "FADEmmss"; + static char lumpname[10] = "FADEmmss"; static fademask_t fm = {NULL,0,0,0,0,0}; lumpnum_t lumpnum; UINT8 *lump, *mask; diff --git a/src/filesrch.c b/src/filesrch.c index a28c4d83c..b931bdd05 100644 --- a/src/filesrch.c +++ b/src/filesrch.c @@ -22,7 +22,7 @@ #include #endif #ifdef _WIN32_WCE -#include "sdl/SRB2CE/cehelp.h" +#include "sdl12/SRB2CE/cehelp.h" #else #include #endif diff --git a/src/g_game.c b/src/g_game.c index e996938ab..19abd516b 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -76,11 +76,14 @@ INT16 gamemap = 1; INT16 maptol; UINT8 globalweather = 0; INT32 curWeather = PRECIP_NONE; -INT32 cursaveslot = -1; // Auto-save 1p savegame slot +INT32 cursaveslot = 0; // Auto-save 1p savegame slot //INT16 lastmapsaved = 0; // Last map we auto-saved at INT16 lastmaploaded = 0; // Last map the game loaded boolean gamecomplete = false; +UINT8 numgameovers = 0; // for startinglives balance +SINT8 startinglivesbalance[maxgameovers+1] = {3, 5, 7, 9, 12, 15, 20, 25, 30, 40, 50, 75, 99, 0x7F}; + UINT16 mainwads = 0; boolean modifiedgame; // Set if homebrew PWAD stuff has been added. boolean savemoddata = false; @@ -121,6 +124,10 @@ INT16 spstage_start; INT16 sstage_start; INT16 sstage_end; +INT16 titlemap = 0; +boolean hidetitlepics = false; +INT16 bootmap; //bootmap for loading a map on startup + boolean looptitle = false; boolean useNightsSS = false; @@ -286,6 +293,10 @@ static void UserAnalog_OnChange(void); static void UserAnalog2_OnChange(void); static void Analog_OnChange(void); static void Analog2_OnChange(void); +static void DirectionChar_OnChange(void); +static void DirectionChar2_OnChange(void); +static void AutoBrake_OnChange(void); +static void AutoBrake2_OnChange(void); void SendWeaponPref(void); void SendWeaponPref2(void); @@ -368,6 +379,14 @@ consvar_t cv_useranalog = {"useranalog", "Off", CV_SAVE|CV_CALL, CV_OnOff, UserA consvar_t cv_useranalog2 = {"useranalog2", "Off", CV_SAVE|CV_CALL, CV_OnOff, UserAnalog2_OnChange, 0, NULL, NULL, 0, 0, NULL}; #endif +static CV_PossibleValue_t directionchar_cons_t[] = {{0, "Camera"}, {1, "Movement"}, {0, NULL}}; + +// deez New User eXperiences +consvar_t cv_directionchar = {"directionchar", "Movement", CV_SAVE|CV_CALL, directionchar_cons_t, DirectionChar_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_directionchar2 = {"directionchar2", "Movement", CV_SAVE|CV_CALL, directionchar_cons_t, DirectionChar2_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_autobrake = {"autobrake", "On", CV_SAVE|CV_CALL, CV_OnOff, AutoBrake_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_autobrake2 = {"autobrake2", "On", CV_SAVE|CV_CALL, CV_OnOff, AutoBrake2_OnChange, 0, NULL, NULL, 0, 0, NULL}; + typedef enum { AXISNONE = 0, @@ -728,7 +747,7 @@ void G_SetGameModified(boolean silent) */ const char *G_BuildMapName(INT32 map) { - static char mapname[9] = "MAPXX"; // internal map name (wad resource name) + static char mapname[10] = "MAPXX"; // internal map name (wad resource name) I_Assert(map > 0); I_Assert(map <= NUMMAPS); @@ -1615,6 +1634,46 @@ static void Analog2_OnChange(void) SendWeaponPref2(); } +static void DirectionChar_OnChange(void) +{ + if (cv_directionchar.value) + players[consoleplayer].pflags |= PF_DIRECTIONCHAR; + else + players[consoleplayer].pflags &= ~PF_DIRECTIONCHAR; + + SendWeaponPref(); +} + +static void DirectionChar2_OnChange(void) +{ + if (cv_directionchar2.value) + players[secondarydisplayplayer].pflags |= PF_DIRECTIONCHAR; + else + players[secondarydisplayplayer].pflags &= ~PF_DIRECTIONCHAR; + + SendWeaponPref2(); +} + +static void AutoBrake_OnChange(void) +{ + if (cv_autobrake.value) + players[consoleplayer].pflags |= PF_AUTOBRAKE; + else + players[consoleplayer].pflags &= ~PF_AUTOBRAKE; + + SendWeaponPref(); +} + +static void AutoBrake2_OnChange(void) +{ + if (cv_autobrake2.value) + players[secondarydisplayplayer].pflags |= PF_AUTOBRAKE; + else + players[secondarydisplayplayer].pflags &= ~PF_AUTOBRAKE; + + SendWeaponPref2(); +} + // // G_DoLoadLevel // @@ -1633,6 +1692,21 @@ void G_DoLoadLevel(boolean resetplayer) if (gamestate == GS_INTERMISSION) Y_EndIntermission(); + // cleanup + if (titlemapinaction == TITLEMAP_LOADING) + { + if (W_CheckNumForName(G_BuildMapName(gamemap)) == LUMPERROR) + { + titlemap = 0; // let's not infinite recursion ok + Command_ExitGame_f(); + return; + } + + titlemapinaction = TITLEMAP_RUNNING; + } + else + titlemapinaction = TITLEMAP_OFF; + G_SetGamestate(GS_LEVEL); for (i = 0; i < MAXPLAYERS; i++) @@ -1642,7 +1716,7 @@ void G_DoLoadLevel(boolean resetplayer) } // Setup the level. - if (!P_SetupLevel(false)) + if (!P_SetupLevel(false)) // this never returns false? { // fail so reset game stuff Command_ExitGame_f(); @@ -1991,6 +2065,8 @@ void G_Ticker(boolean run) break; case GS_TITLESCREEN: + if (titlemapinaction) P_Ticker(run); // then intentionally fall through + /* FALLTHRU */ case GS_WAITINGPLAYERS: F_TitleScreenTicker(run); break; @@ -2103,7 +2179,7 @@ void G_PlayerReborn(INT32 player) jointime = players[player].jointime; spectator = players[player].spectator; outofcoop = players[player].outofcoop; - pflags = (players[player].pflags & (PF_TIMEOVER|PF_FLIPCAM|PF_TAGIT|PF_TAGGED|PF_ANALOGMODE)); + pflags = (players[player].pflags & (PF_FLIPCAM|PF_ANALOGMODE|PF_DIRECTIONCHAR|PF_AUTOBRAKE|PF_TAGIT|PF_GAMETYPEOVER)); // As long as we're not in multiplayer, carry over cheatcodes from map to map if (!(netgame || multiplayer)) @@ -3129,8 +3205,11 @@ static void G_DoContinued(void) tokenlist = 0; token = 0; + if (!(netgame || multiplayer || demoplayback || demorecording || metalrecording || modeattacking) && (!modifiedgame || savemoddata) && cursaveslot > 0) + G_SaveGameOver((UINT32)cursaveslot, true); + // Reset # of lives - pl->lives = (ultimatemode) ? 1 : 3; + pl->lives = (ultimatemode) ? 1 : startinglivesbalance[numgameovers]; D_MapChange(gamemap, gametype, ultimatemode, false, 0, false, false); @@ -3469,59 +3548,6 @@ void G_SaveGameData(void) #define VERSIONSIZE 16 -#ifdef SAVEGAMES_OTHERVERSIONS -static INT16 startonmapnum = 0; - -// -// User wants to load a savegame from a different version? -// -static void M_ForceLoadGameResponse(INT32 ch) -{ - if (ch != 'y' && ch != KEY_ENTER) - { - //refused - Z_Free(savebuffer); - save_p = savebuffer = NULL; - startonmapnum = 0; - M_SetupNextMenu(&SP_LoadDef); - return; - } - - // pick up where we left off. - save_p += VERSIONSIZE; - if (!P_LoadGame(startonmapnum)) - { - M_ClearMenus(true); // so ESC backs out to title - M_StartMessage(M_GetText("Savegame file corrupted\n\nPress ESC\n"), NULL, MM_NOTHING); - Command_ExitGame_f(); - Z_Free(savebuffer); - save_p = savebuffer = NULL; - startonmapnum = 0; - - // no cheating! - memset(&savedata, 0, sizeof(savedata)); - return; - } - - // done - Z_Free(savebuffer); - save_p = savebuffer = NULL; - startonmapnum = 0; - - //set cursaveslot to -1 so nothing gets saved. - cursaveslot = -1; - - displayplayer = consoleplayer; - multiplayer = splitscreen = false; - - if (setsizeneeded) - R_ExecuteSetViewSize(); - - M_ClearMenus(true); - CON_ToggleOff(); -} -#endif - // // G_InitFromSavegame // Can be called by the startup code or the menu task. @@ -3614,13 +3640,13 @@ void G_LoadGame(UINT32 slot, INT16 mapoverride) // G_SaveGame // Saves your game. // -void G_SaveGame(UINT32 savegameslot) +void G_SaveGame(UINT32 slot) { boolean saved; char savename[256] = ""; const char *backup; - sprintf(savename, savegamename, savegameslot); + sprintf(savename, savegamename, slot); backup = va("%s",savename); // save during evaluation or credits? game's over, folks! @@ -3656,9 +3682,91 @@ void G_SaveGame(UINT32 savegameslot) if (cv_debug && saved) CONS_Printf(M_GetText("Game saved.\n")); else if (!saved) - CONS_Alert(CONS_ERROR, M_GetText("Error while writing to %s for save slot %u, base: %s\n"), backup, savegameslot, savegamename); + CONS_Alert(CONS_ERROR, M_GetText("Error while writing to %s for save slot %u, base: %s\n"), backup, slot, savegamename); } +#define BADSAVE goto cleanup; +#define CHECKPOS if (save_p >= end_p) BADSAVE +void G_SaveGameOver(UINT32 slot, boolean modifylives) +{ + boolean saved = false; + size_t length; + char vcheck[VERSIONSIZE]; + char savename[255]; + const char *backup; + + sprintf(savename, savegamename, slot); + backup = va("%s",savename); + + length = FIL_ReadFile(savename, &savebuffer); + if (!length) + { + CONS_Printf(M_GetText("Couldn't read file %s\n"), savename); + return; + } + + { + char temp[sizeof(timeattackfolder)]; + UINT8 *end_p = savebuffer + length; + UINT8 *lives_p; + SINT8 pllives; + + save_p = savebuffer; + // Version check + memset(vcheck, 0, sizeof (vcheck)); + sprintf(vcheck, "version %d", VERSION); + if (strcmp((const char *)save_p, (const char *)vcheck)) BADSAVE + save_p += VERSIONSIZE; + + // P_UnArchiveMisc() + (void)READINT16(save_p); + CHECKPOS + (void)READUINT16(save_p); // emeralds + CHECKPOS + READSTRINGN(save_p, temp, sizeof(temp)); // mod it belongs to + if (strcmp(temp, timeattackfolder)) BADSAVE + + // P_UnArchivePlayer() + CHECKPOS + (void)READUINT16(save_p); + CHECKPOS + + WRITEUINT8(save_p, numgameovers); + CHECKPOS + + lives_p = save_p; + pllives = READSINT8(save_p); // lives + CHECKPOS + if (modifylives && pllives < startinglivesbalance[numgameovers]) + { + pllives = startinglivesbalance[numgameovers]; + WRITESINT8(lives_p, pllives); + } + + (void)READINT32(save_p); // Score + CHECKPOS + (void)READINT32(save_p); // continues + + // File end marker check + CHECKPOS + if (READUINT8(save_p) != 0x1d) BADSAVE; + + // done + saved = FIL_WriteFile(backup, savebuffer, length); + } + +cleanup: + if (cv_debug && saved) + CONS_Printf(M_GetText("Game saved.\n")); + else if (!saved) + CONS_Alert(CONS_ERROR, M_GetText("Error while writing to %s for save slot %u, base: %s\n"), backup, slot, savegamename); + Z_Free(savebuffer); + save_p = savebuffer = NULL; + +} +#undef CHECKPOS +#undef BADSAVE + // // G_DeferedInitNew // Can be called by the startup code or the menu task, @@ -3666,7 +3774,7 @@ void G_SaveGame(UINT32 savegameslot) // void G_DeferedInitNew(boolean pultmode, const char *mapname, INT32 pickedchar, boolean SSSG, boolean FLS) { - UINT8 color = 0; + UINT8 color = skins[pickedchar].prefcolor; paused = false; if (demoplayback) @@ -3678,10 +3786,8 @@ void G_DeferedInitNew(boolean pultmode, const char *mapname, INT32 pickedchar, b if (savedata.lives > 0) { - color = savedata.skincolor; - botskin = savedata.botskin; - botcolor = savedata.botcolor; - botingame = (botskin != 0); + if ((botingame = ((botskin = savedata.botskin) != 0))) + botcolor = skins[botskin-1].prefcolor; } else if (splitscreen != SSSG) { @@ -3689,8 +3795,7 @@ void G_DeferedInitNew(boolean pultmode, const char *mapname, INT32 pickedchar, b SplitScreen_OnChange(); } - if (!color) - color = skins[pickedchar].prefcolor; + color = skins[pickedchar].prefcolor; SetPlayerSkinByNum(consoleplayer, pickedchar); CV_StealthSet(&cv_skin, skins[pickedchar].name); CV_StealthSetValue(&cv_playercolor, color); @@ -3722,7 +3827,7 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean if (resetplayer) { // Clear a bunch of variables - tokenlist = token = sstimer = redscore = bluescore = lastmap = 0; + numgameovers = tokenlist = token = sstimer = redscore = bluescore = lastmap = 0; countdown = countdown2 = 0; for (i = 0; i < MAXPLAYERS; i++) @@ -3737,22 +3842,17 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean players[i].lives = cv_startinglives.value; players[i].continues = 0; } - else if (pultmode) - { - players[i].lives = 1; - players[i].continues = 0; - } else { - players[i].lives = 3; - players[i].continues = 1; + players[i].lives = (pultmode) ? 1 : startinglivesbalance[0]; + players[i].continues = (pultmode) ? 0 : 1; } if (!((netgame || multiplayer) && (FLS))) players[i].score = 0; // The latter two should clear by themselves, but just in case - players[i].pflags &= ~(PF_TAGIT|PF_TAGGED|PF_FULLSTASIS); + players[i].pflags &= ~(PF_TAGIT|PF_GAMETYPEOVER|PF_FULLSTASIS); // Clear cheatcodes too, just in case. players[i].pflags &= ~(PF_GODMODE|PF_NOCLIP|PF_INVIS); diff --git a/src/g_game.h b/src/g_game.h index 72a6f3d6e..31eea061a 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -59,6 +59,8 @@ extern consvar_t cv_invertmouse, cv_alwaysfreelook, cv_mousemove; extern consvar_t cv_invertmouse2, cv_alwaysfreelook2, cv_mousemove2; extern consvar_t cv_useranalog, cv_useranalog2; extern consvar_t cv_analog, cv_analog2; +extern consvar_t cv_directionchar, cv_directionchar2; +extern consvar_t cv_autobrake, cv_autobrake2; extern consvar_t cv_sideaxis,cv_turnaxis,cv_moveaxis,cv_lookaxis,cv_fireaxis,cv_firenaxis; extern consvar_t cv_sideaxis2,cv_turnaxis2,cv_moveaxis2,cv_lookaxis2,cv_fireaxis2,cv_firenaxis2; extern consvar_t cv_ghost_bestscore, cv_ghost_besttime, cv_ghost_bestrings, cv_ghost_last, cv_ghost_guest; @@ -116,6 +118,8 @@ void G_SaveGameData(void); void G_SaveGame(UINT32 slot); +void G_SaveGameOver(UINT32 slot, boolean modifylives); + // Only called by startup code. void G_RecordDemo(const char *name); void G_RecordMetal(void); diff --git a/src/hardware/hw_data.h b/src/hardware/hw_data.h index a6525a2f5..d76fcc1c8 100644 --- a/src/hardware/hw_data.h +++ b/src/hardware/hw_data.h @@ -64,7 +64,7 @@ typedef struct GLMipmap_s GLMipmap_t; // struct GLTexture_s { - GLMipmap_t mipmap; + GLMipmap_t mipmap; float scaleX; //used for scaling textures on walls float scaleY; }; @@ -88,7 +88,7 @@ struct GLPatch_s UINT16 wadnum; // the software patch lump num for when the hardware patch UINT16 lumpnum; // was flushed, and we need to re-create it GLMipmap_t mipmap; -} ATTRPACK; +}; typedef struct GLPatch_s GLPatch_t; #endif //_HWR_DATA_ diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index d74cd0587..cc3f40402 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -4753,8 +4753,6 @@ static polyplaneinfo_t *polyplaneinfo = NULL; #ifndef SORTING size_t numfloors = 0; #else -//static floorinfo_t *floorinfo = NULL; -//static size_t numfloors = 0; //Hurdler: 3D water sutffs typedef struct gr_drawnode_s { @@ -5241,7 +5239,7 @@ static void HWR_ProjectSprite(mobj_t *thing) // Note: DO NOT do this in software mode version, it actually // makes papersprites look WORSE there (I know, I've tried) // Monster Iestyn - 13/05/17 - ang = dup_viewangle - thing->angle; + ang = dup_viewangle - (thing->player ? thing->player->drawangle : thing->angle); ang_scale = FIXED_TO_FLOAT(FINESINE(ang>>ANGLETOFINESHIFT)); ang_scalez = FIXED_TO_FLOAT(FINECOSINE(ang>>ANGLETOFINESHIFT)); @@ -5252,7 +5250,7 @@ static void HWR_ProjectSprite(mobj_t *thing) } } else if (sprframe->rotate != SRF_SINGLE) - ang = R_PointToAngle (thing->x, thing->y) - thing->angle; + ang = R_PointToAngle (thing->x, thing->y) - (thing->player ? thing->player->drawangle : thing->angle); if (sprframe->rotate == SRF_SINGLE) { diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index b0a14d3b5..cb49f817c 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -46,8 +46,7 @@ void HWR_SetViewSize(void); void HWR_DrawPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option); void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t scale, INT32 option, const UINT8 *colormap); void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t scale, 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, INT32 option, fixed_t scale, fixed_t sx, fixed_t sy, fixed_t w, fixed_t h); -void HWR_MakePatch (const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipmap, boolean makebitmap); +void HWR_MakePatch(const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipmap, boolean makebitmap); void HWR_CreatePlanePolygons(INT32 bspnum); void HWR_CreateStaticLightmaps(INT32 bspnum); void HWR_PrepLevelCache(size_t pnumtextures); @@ -104,13 +103,4 @@ extern float gr_viewwindowx, gr_basewindowcentery; extern fixed_t *hwbbox; extern FTransform atransform; -typedef struct -{ - wallVert3D floorVerts[4]; - FSurfaceInfo Surf; - INT32 texnum; - INT32 blend; - INT32 drawcount; -} floorinfo_t; - #endif diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index df2c9f59a..70a257c92 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -28,6 +28,7 @@ #include "../doomdef.h" #include "../doomstat.h" +#include "../fastcmp.h" #ifdef HWRENDER #include "hw_drv.h" @@ -265,6 +266,9 @@ static void md2_freeModel (md2_model_t *model) free(model->frames); } + if (model->spr2frames) + free(model->spr2frames); + if (model->glCommandBuffer) free(model->glCommandBuffer); @@ -395,6 +399,39 @@ static md2_model_t *md2_readModel(const char *filename) } strcpy(model->frames[i].name, frame->name); + if (frame->name[0] == 'S') + { + boolean super; + if ((super = (fastncmp("UPER", frame->name+1, 4))) // SUPER + || fastncmp("PR2_", frame->name+1, 4)) // SPR2_ + { + UINT8 spr2; + for (spr2 = 0; spr2 < free_spr2; spr2++) + if (fastncmp(frame->name+5,spr2names[spr2],3) + && ((frame->name[8] == spr2names[spr2][3]) + || (frame->name[8] == '.' && spr2names[spr2][3] == '_'))) + break; + + if (spr2 < free_spr2) + { + if (!model->spr2frames) + { + model->spr2frames = calloc(sizeof (size_t), 2*NUMPLAYERSPRITES*2); + if (!model->spr2frames) + { + md2_freeModel (model); + fclose(file); + return 0; + } + } + if (super) + spr2 |= FF_SPR2SUPER; + if (model->spr2frames[spr2*2 + 1]++ == 0) // numspr2frames + model->spr2frames[spr2*2] = i; // starting frame + CONS_Debug(DBG_RENDER, "frame %s, sprite2 %s - starting frame %s, number of frames %s\n", frame->name, spr2names[spr2 & ~FF_SPR2SUPER], sizeu1(model->spr2frames[spr2*2]), sizeu2(model->spr2frames[spr2*2 + 1])); + } + } + } for (j = 0; j < model->header.numVertices; j++) { model->frames[i].vertices[j].vertex[0] = (float) ((INT32) frame->alias_vertices[j].vertex[0]) * frame->scale[0] + frame->translate[0]; @@ -1078,6 +1115,51 @@ static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, con res? run? */ + +static UINT8 P_GetModelSprite2(md2_t *md2, skin_t *skin, UINT8 spr2, player_t *player) +{ + UINT8 super = 0, i = 0; + + if (!md2 || !skin) + return 0; + + while (!(md2->model->spr2frames[spr2*2 + 1]) + && spr2 != SPR2_STND + && ++i != 32) // recursion limiter + { + if (spr2 & FF_SPR2SUPER) + { + super = FF_SPR2SUPER; + spr2 &= ~FF_SPR2SUPER; + continue; + } + + switch(spr2) + { + + // Normal special cases. + case SPR2_JUMP: + spr2 = ((player + ? player->charflags + : skin->flags) + & SF_NOJUMPSPIN) ? SPR2_SPNG : SPR2_ROLL; + break; + case SPR2_TIRE: + spr2 = (player && player->charability == CA_SWIM) ? SPR2_SWIM : SPR2_FLY; + break; + + // Use the handy list, that's what it's there for! + default: + spr2 = spr2defaults[spr2]; + break; + } + + spr2 |= super; + } + + return spr2; +} + #define NORMALFOG 0x00000000 #define FADEFOG 0x19000000 void HWR_DrawMD2(gr_vissprite_t *spr) @@ -1225,31 +1307,70 @@ void HWR_DrawMD2(gr_vissprite_t *spr) tics = spr->mobj->anim_duration; } - //FIXME: this is not yet correct - frame = (spr->mobj->frame & FF_FRAMEMASK) % md2->model->header.numFrames; - buff = md2->model->glCommandBuffer; - curr = &md2->model->frames[frame]; - if (cv_grmd2.value == 1) +#define INTERPOLERATION_LIMIT TICRATE/4 + + if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY && md2->model->spr2frames) { - // frames are handled differently for states with FF_ANIMATE, so get the next frame differently for the interpolation - if (spr->mobj->frame & FF_ANIMATE) + UINT8 spr2 = P_GetModelSprite2(md2, spr->mobj->skin, spr->mobj->sprite2, spr->mobj->player); + UINT8 mod = md2->model->spr2frames[spr2*2 + 1] ? md2->model->spr2frames[spr2*2 + 1] : md2->model->header.numFrames; + if (mod > ((skin_t *)spr->mobj->skin)->sprites[spr2].numframes) + mod = ((skin_t *)spr->mobj->skin)->sprites[spr2].numframes; + //FIXME: this is not yet correct + frame = (spr->mobj->frame & FF_FRAMEMASK); + if (frame >= mod) + frame = 0; + buff = md2->model->glCommandBuffer; + curr = &md2->model->frames[md2->model->spr2frames[spr2*2] + frame]; + if (cv_grmd2.value == 1 && tics <= INTERPOLERATION_LIMIT) { - UINT32 nextframe = (spr->mobj->frame & FF_FRAMEMASK) + 1; - if (nextframe >= (UINT32)spr->mobj->state->var1) - nextframe = (spr->mobj->state->frame & FF_FRAMEMASK); - nextframe %= md2->model->header.numFrames; - next = &md2->model->frames[nextframe]; - } - else - { - if (spr->mobj->state->nextstate != S_NULL && states[spr->mobj->state->nextstate].sprite != SPR_NULL - && !(spr->mobj->player && spr->mobj->state->nextstate == S_PLAY_WAIT && spr->mobj->state == &states[S_PLAY_STND])) + if (durs > INTERPOLERATION_LIMIT) + durs = INTERPOLERATION_LIMIT; + + if (spr->mobj->frame & FF_ANIMATE + || (spr->mobj->state->nextstate != S_NULL + && states[spr->mobj->state->nextstate].sprite == spr->mobj->sprite + && (states[spr->mobj->state->nextstate].frame & FF_FRAMEMASK) == spr->mobj->sprite2)) { - const UINT32 nextframe = (states[spr->mobj->state->nextstate].frame & FF_FRAMEMASK) % md2->model->header.numFrames; - next = &md2->model->frames[nextframe]; + if (++frame >= mod) + frame = 0; + if (frame || !(spr->mobj->state->frame & FF_SPR2ENDSTATE)) + next = &md2->model->frames[md2->model->spr2frames[spr2*2] + frame]; } } } + else + { + //FIXME: this is not yet correct + frame = (spr->mobj->frame & FF_FRAMEMASK) % md2->model->header.numFrames; + buff = md2->model->glCommandBuffer; + curr = &md2->model->frames[frame]; + if (cv_grmd2.value == 1 && tics <= INTERPOLERATION_LIMIT) + { + if (durs > INTERPOLERATION_LIMIT) + durs = INTERPOLERATION_LIMIT; + + // frames are handled differently for states with FF_ANIMATE, so get the next frame differently for the interpolation + if (spr->mobj->frame & FF_ANIMATE) + { + UINT32 nextframe = (spr->mobj->frame & FF_FRAMEMASK) + 1; + if (nextframe >= (UINT32)spr->mobj->state->var1) + nextframe = (spr->mobj->state->frame & FF_FRAMEMASK); + nextframe %= md2->model->header.numFrames; + next = &md2->model->frames[nextframe]; + } + else + { + if (spr->mobj->state->nextstate != S_NULL + && states[spr->mobj->state->nextstate].sprite == spr->mobj->sprite) + { + const UINT32 nextframe = (states[spr->mobj->state->nextstate].frame & FF_FRAMEMASK) % md2->model->header.numFrames; + next = &md2->model->frames[nextframe]; + } + } + } + } + +#undef INTERPOLERATION_LIMIT //Hurdler: it seems there is still a small problem with mobj angle p.x = FIXED_TO_FLOAT(spr->mobj->x); @@ -1269,7 +1390,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr) if (sprframe->rotate) { - const fixed_t anglef = AngleFixed(spr->mobj->angle); + const fixed_t anglef = AngleFixed((spr->mobj->player ? spr->mobj->player->drawangle : spr->mobj->angle)); p.angley = FIXED_TO_FLOAT(anglef); } else diff --git a/src/hardware/hw_md2.h b/src/hardware/hw_md2.h index 299d12400..c7cda35af 100644 --- a/src/hardware/hw_md2.h +++ b/src/hardware/hw_md2.h @@ -22,6 +22,7 @@ #define _HW_MD2_H_ #include "hw_glob.h" +#include "../info.h" // magic number "IDP2" or 844121161 #define MD2_IDENT (INT32)(('2' << 24) + ('P' << 16) + ('D' << 8) + 'I') @@ -111,7 +112,8 @@ typedef struct md2_textureCoordinate_t *texCoords; md2_triangle_t *triangles; md2_frame_t *frames; - INT32 *glCommandBuffer; + size_t *spr2frames; // size_t spr2frames[2*NUMPLAYERSPRITES][2]; + INT32 *glCommandBuffer; } ATTRPACK md2_model_t; #if defined(_MSC_VER) diff --git a/src/hu_stuff.c b/src/hu_stuff.c index e92b96995..b49d3eb96 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -83,6 +83,7 @@ patch_t *rmatcico; patch_t *bmatcico; patch_t *tagico; patch_t *tallminus; +patch_t *tallinfin; //------------------------------------------- // coop hud @@ -235,6 +236,7 @@ void HU_LoadGraphics(void) // minus for negative tallnums tallminus = (patch_t *)W_CachePatchName("STTMINUS", PU_HUDGFX); + tallinfin = (patch_t *)W_CachePatchName("STTINFIN", PU_HUDGFX); // cache the crosshairs, don't bother to know which one is being used, // just cache all 3, they're so small anyway. @@ -1250,7 +1252,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I } } - if (G_GametypeUsesLives() && !(gametype == GT_COOP && (cv_cooplives.value == 0 || cv_cooplives.value == 3))) //show lives + if (G_GametypeUsesLives() && !(gametype == GT_COOP && (cv_cooplives.value == 0 || cv_cooplives.value == 3)) && (players[tab[i].num].lives != 0x7f)) //show lives V_DrawRightAlignedString(x, y+4, V_ALLOWLOWERCASE|(greycheck ? V_60TRANS : 0), va("%dx", players[tab[i].num].lives)); else if (G_TagGametype() && players[tab[i].num].pflags & PF_TAGIT) { @@ -1388,7 +1390,7 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline | (greycheck ? V_TRANSLUCENT : 0) | V_ALLOWLOWERCASE, name); - if (G_GametypeUsesLives() && !(gametype == GT_COOP && (cv_cooplives.value == 0 || cv_cooplives.value == 3))) //show lives + if (G_GametypeUsesLives() && !(gametype == GT_COOP && (cv_cooplives.value == 0 || cv_cooplives.value == 3)) && (players[tab[i].num].lives != 0x7f)) //show lives V_DrawRightAlignedString(x, y+4, V_ALLOWLOWERCASE, va("%dx", players[tab[i].num].lives)); else if (G_TagGametype() && players[tab[i].num].pflags & PF_TAGIT) V_DrawSmallScaledPatch(x-28, y-4, 0, tagico); diff --git a/src/hu_stuff.h b/src/hu_stuff.h index e757db85a..2dbeb556d 100644 --- a/src/hu_stuff.h +++ b/src/hu_stuff.h @@ -71,6 +71,7 @@ extern patch_t *rmatcico; extern patch_t *bmatcico; extern patch_t *tagico; extern patch_t *tallminus; +extern patch_t *tallinfin; extern patch_t *tokenicon; // set true when entering a chat message diff --git a/src/i_tcp.c b/src/i_tcp.c index c65a536a8..5681a9d44 100644 --- a/src/i_tcp.c +++ b/src/i_tcp.c @@ -97,7 +97,7 @@ #include #ifdef _arch_dreamcast -#include "sdl/SRB2DC/dchelp.h" +#include "sdl12/SRB2DC/dchelp.h" #endif #if (defined (__unix__) && !defined (MSDOS)) || defined(__APPLE__) || defined (UNIXCOMMON) @@ -192,7 +192,7 @@ static UINT8 UPNP_support = TRUE; #define close closesocket #ifdef _WIN32_WCE - #include "sdl/SRB2CE/cehelp.h" + #include "sdl12/SRB2CE/cehelp.h" #endif #endif diff --git a/src/info.c b/src/info.c index 2d6c9a3d1..d62111640 100644 --- a/src/info.c +++ b/src/info.c @@ -405,6 +405,7 @@ char spr2names[NUMPLAYERSPRITES][5] = "STND", "WAIT", "WALK", + "SKID", "RUN_", "DASH", "PAIN", @@ -481,7 +482,89 @@ char spr2names[NUMPLAYERSPRITES][5] = "SIGN", "LIFE" }; -enum playersprite free_spr2 = SPR2_FIRSTFREESLOT; +playersprite_t free_spr2 = SPR2_FIRSTFREESLOT; + +playersprite_t spr2defaults[NUMPLAYERSPRITES] = { + 0, // SPR2_STND, + 0, // SPR2_WAIT, + 0, // SPR2_WALK, + SPR2_WALK, // SPR2_SKID, + SPR2_WALK, // SPR2_RUN , + SPR2_FRUN, // SPR2_DASH, + 0, // SPR2_PAIN, + SPR2_PAIN, // SPR2_STUN, + SPR2_PAIN, // SPR2_DEAD, + SPR2_DEAD, // SPR2_DRWN, + 0, // SPR2_ROLL, + SPR2_SPNG, // SPR2_GASP, + 0, // SPR2_JUMP, (conditional) + SPR2_FALL, // SPR2_SPNG, + SPR2_WALK, // SPR2_FALL, + 0, // SPR2_EDGE, + SPR2_FALL, // SPR2_RIDE, + + SPR2_ROLL, // SPR2_SPIN, + + SPR2_SPNG, // SPR2_FLY , + SPR2_FLY , // SPR2_SWIM, + 0, // SPR2_TIRE, (conditional) + + SPR2_FLY , // SPR2_GLID, + SPR2_CLMB, // SPR2_CLNG, + SPR2_ROLL, // SPR2_CLMB, + + SPR2_WALK, // SPR2_FLT , + SPR2_RUN , // SPR2_FRUN, + + SPR2_FALL, // SPR2_BNCE, + SPR2_ROLL, // SPR2_BLND, + + 0, // SPR2_FIRE, + + SPR2_ROLL, // SPR2_TWIN, + + SPR2_TWIN, // SPR2_MLEE, + 0, // SPR2_MLEL, + + 0, // SPR2_TRNS, + + FF_SPR2SUPER|SPR2_STND, // SPR2_NSTD, + FF_SPR2SUPER|SPR2_FLT , // SPR2_NFLT, + FF_SPR2SUPER|SPR2_STUN, // SPR2_NSTN, + SPR2_NSTN, // SPR2_NPUL, + FF_SPR2SUPER|SPR2_ROLL, // SPR2_NATK, + + 0, // SPR2_NGT0, (should never be referenced) + SPR2_NGT0, // SPR2_NGT1, + SPR2_NGT1, // SPR2_NGT2, + SPR2_NGT2, // SPR2_NGT3, + SPR2_NGT3, // SPR2_NGT4, + SPR2_NGT4, // SPR2_NGT5, + SPR2_NGT5, // SPR2_NGT6, + SPR2_NGT0, // SPR2_NGT7, + SPR2_NGT7, // SPR2_NGT8, + SPR2_NGT8, // SPR2_NGT9, + SPR2_NGT9, // SPR2_NGTA, + SPR2_NGTA, // SPR2_NGTB, + SPR2_NGTB, // SPR2_NGTC, + + SPR2_NGT0, // SPR2_DRL0, + SPR2_NGT1, // SPR2_DRL1, + SPR2_NGT2, // SPR2_DRL2, + SPR2_NGT3, // SPR2_DRL3, + SPR2_NGT4, // SPR2_DRL4, + SPR2_NGT5, // SPR2_DRL5, + SPR2_NGT6, // SPR2_DRL6, + SPR2_NGT7, // SPR2_DRL7, + SPR2_NGT8, // SPR2_DRL8, + SPR2_NGT9, // SPR2_DRL9, + SPR2_NGTA, // SPR2_DRLA, + SPR2_NGTB, // SPR2_DRLB, + SPR2_NGTC, // SPR2_DRLC, + + 0, // SPR2_SIGN, + 0, // SPR2_LIFE +}; // Doesn't work with g++, needs actionf_p1 (don't modify this comment) state_t states[NUMSTATES] = @@ -512,6 +595,7 @@ state_t states[NUMSTATES] = {SPR_PLAY, SPR2_STND|FF_ANIMATE, 105, {NULL}, 0, 7, S_PLAY_WAIT}, // S_PLAY_STND {SPR_PLAY, SPR2_WAIT|FF_ANIMATE, -1, {NULL}, 0, 16, S_NULL}, // S_PLAY_WAIT {SPR_PLAY, SPR2_WALK, 4, {NULL}, 0, 0, S_PLAY_WALK}, // S_PLAY_WALK + {SPR_PLAY, SPR2_SKID, 1, {NULL}, 0, 0, S_PLAY_WALK}, // S_PLAY_SKID {SPR_PLAY, SPR2_RUN , 2, {NULL}, 0, 0, S_PLAY_RUN}, // S_PLAY_RUN {SPR_PLAY, SPR2_DASH, 2, {NULL}, 0, 0, S_PLAY_DASH}, // S_PLAY_DASH {SPR_PLAY, SPR2_PAIN|FF_ANIMATE, 350, {NULL}, 0, 4, S_PLAY_FALL}, // S_PLAY_PAIN diff --git a/src/info.h b/src/info.h index cd79b12a9..7bc7e673a 100644 --- a/src/info.h +++ b/src/info.h @@ -604,11 +604,12 @@ typedef enum sprite // Make sure to be conscious of FF_FRAMEMASK and the fact sprite2 is stored as a UINT8 whenever you change this table. // Currently, FF_FRAMEMASK is 0xff, or 255 - but the second half is used by FF_SPR2SUPER, so the limitation is 0x7f. // Since this is zero-based, there can be at most 128 different SPR2_'s without changing that. -enum playersprite +typedef enum playersprite { SPR2_STND = 0, SPR2_WAIT, SPR2_WALK, + SPR2_SKID, SPR2_RUN , SPR2_DASH, SPR2_PAIN, @@ -690,7 +691,7 @@ enum playersprite SPR2_FIRSTFREESLOT, SPR2_LASTFREESLOT = 0x7f, NUMPLAYERSPRITES -}; +} playersprite_t; typedef enum state { @@ -713,6 +714,7 @@ typedef enum state S_PLAY_STND, S_PLAY_WAIT, S_PLAY_WALK, + S_PLAY_SKID, S_PLAY_RUN, S_PLAY_DASH, S_PLAY_PAIN, @@ -3193,8 +3195,9 @@ typedef struct extern state_t states[NUMSTATES]; extern char sprnames[NUMSPRITES + 1][5]; extern char spr2names[NUMPLAYERSPRITES][5]; +extern playersprite_t spr2defaults[NUMPLAYERSPRITES]; extern state_t *astate; -extern enum playersprite free_spr2; +extern playersprite_t free_spr2; typedef enum mobj_type { diff --git a/src/lua_baselib.c b/src/lua_baselib.c index be1455415..4d845df52 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -135,7 +135,7 @@ static const struct { }; // goes through the above list and returns the utype string for the userdata type -// returns "unknown" instead if we couldn't find the right userdata type +// returns "unknown" instead if we couldn't find the right userdata type static const char *GetUserdataUType(lua_State *L) { UINT8 i; @@ -462,6 +462,8 @@ static int lib_pSpawnLockOn(lua_State *L) return LUA_ErrInvalid(L, "mobj_t"); if (!player) return LUA_ErrInvalid(L, "player_t"); + if (state >= NUMSTATES) + return luaL_error(L, "state %d out of range (0 - %d)", state, NUMSTATES-1); if (P_IsLocalPlayer(player)) // Only display it on your own view. { mobj_t *visual = P_SpawnMobj(lockon->x, lockon->y, lockon->z, MT_LOCKON); // positioning, flip handled in P_SceneryThinker diff --git a/src/lua_blockmaplib.c b/src/lua_blockmaplib.c index ccd90f993..ebfd6a2df 100644 --- a/src/lua_blockmaplib.c +++ b/src/lua_blockmaplib.c @@ -254,7 +254,7 @@ static int lib_searchBlockmap(lua_State *L) if (P_MobjWasRemoved(mobj)){ // ...unless the original object was removed lua_pushboolean(L, false); // in which case we have to stop now regardless return 1; - } + } } lua_pushboolean(L, retval); return 1; diff --git a/src/lua_hud.h b/src/lua_hud.h index ba0a1d894..beaca7883 100644 --- a/src/lua_hud.h +++ b/src/lua_hud.h @@ -42,3 +42,4 @@ boolean LUA_HudEnabled(enum hud option); void LUAh_GameHUD(player_t *stplyr); void LUAh_ScoresHUD(void); +void LUAh_TitleHUD(void); diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 8175f1b9b..68a69cd1d 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -88,11 +88,13 @@ static const char *const patch_opt[] = { enum hudhook { hudhook_game = 0, - hudhook_scores + hudhook_scores, + hudhook_title }; static const char *const hudhook_opt[] = { "game", "scores", + "title", NULL}; // alignment types for v.drawString @@ -808,6 +810,9 @@ int LUA_HudLib(lua_State *L) lua_newtable(L); lua_rawseti(L, -2, 3); // HUD[2] = scores rendering functions array + + lua_newtable(L); + lua_rawseti(L, -2, 4); // HUD[3] = title rendering functions array lua_setfield(L, LUA_REGISTRYINDEX, "HUD"); luaL_newmetatable(L, META_HUDINFO); @@ -920,4 +925,29 @@ void LUAh_ScoresHUD(void) hud_running = false; } +void LUAh_TitleHUD(void) +{ + if (!gL || !(hudAvailable & (1<= free_spr2) + return 0; + + lua_pushinteger(L, spr2defaults[i]); + return 1; +} + +static int lib_setSpr2default(lua_State *L) +{ + UINT32 i; + UINT8 j = 0; + + lua_remove(L, 1); // don't care about spr2defaults[] dummy userdata. + + if (lua_isnumber(L, 1)) + i = lua_tonumber(L, 1); + else if (lua_isstring(L, 1)) + { + const char *name = lua_tostring(L, 1); + for (i = 0; i < free_spr2; i++) + { + if (fastcmp(name, spr2names[i])) + break; + } + if (i == free_spr2) + return luaL_error(L, "spr2defaults[] invalid index"); + } + else + return luaL_error(L, "spr2defaults[] invalid index"); + + if (i < SPR2_FIRSTFREESLOT || i >= free_spr2) + return luaL_error(L, "spr2defaults[] index %d out of range (%d - %d)", i, SPR2_FIRSTFREESLOT, free_spr2-1); + + if (lua_isnumber(L, 2)) + j = lua_tonumber(L, 2); + else if (lua_isstring(L, 2)) + { + const char *name = lua_tostring(L, 2); + for (j = 0; j < free_spr2; j++) + { + if (fastcmp(name, spr2names[j])) + break; + } + if (j == free_spr2) + return luaL_error(L, "spr2defaults[] invalid index"); + } + + if (j >= free_spr2) + j = 0; // return luaL_error(L, "spr2defaults[] set %d out of range (%d - %d)", j, 0, free_spr2-1); + + spr2defaults[i] = j; + return 0; +} + static int lib_spr2namelen(lua_State *L) { lua_pushinteger(L, free_spr2); @@ -984,6 +1056,19 @@ int LUA_InfoLib(lua_State *L) lua_setmetatable(L, -2); lua_setglobal(L, "spr2names"); + lua_newuserdata(L, 0); + lua_createtable(L, 0, 2); + lua_pushcfunction(L, lib_getSpr2default); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, lib_setSpr2default); + lua_setfield(L, -2, "__newindex"); + + lua_pushcfunction(L, lib_spr2namelen); + lua_setfield(L, -2, "__len"); + lua_setmetatable(L, -2); + lua_setglobal(L, "spr2defaults"); + lua_newuserdata(L, 0); lua_createtable(L, 0, 2); lua_pushcfunction(L, lib_getState); diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index b8a6ea4fd..7c55012d2 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -126,6 +126,8 @@ static int player_get(lua_State *L) lua_pushfixed(L, plr->bob); else if (fastcmp(field,"aiming")) lua_pushangle(L, plr->aiming); + else if (fastcmp(field,"drawangle")) + lua_pushangle(L, plr->drawangle); else if (fastcmp(field,"rings")) lua_pushinteger(L, plr->rings); else if (fastcmp(field,"pity")) @@ -386,6 +388,8 @@ static int player_set(lua_State *L) else if (plr == &players[secondarydisplayplayer]) localaiming2 = plr->aiming; } + else if (fastcmp(field,"drawangle")) + plr->drawangle = luaL_checkangle(L, 3); else if (fastcmp(field,"rings")) plr->rings = (INT32)luaL_checkinteger(L, 3); else if (fastcmp(field,"pity")) diff --git a/src/m_cheat.c b/src/m_cheat.c index f988c0fd5..3308f721c 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -61,7 +61,7 @@ static UINT8 cheatf_ultimate(void) if (menuactive && (currentMenu != &MainDef && currentMenu != &SP_LoadDef)) return 0; // Only on the main menu, or the save select! - S_StartSound(0, sfx_itemup); + BwehHehHe(); ultimate_selectable = (!ultimate_selectable); // If on the save select, move to what is now Ultimate Mode! @@ -1093,7 +1093,7 @@ void OP_ObjectplaceMovement(player_t *player) ticcmd_t *cmd = &player->cmd; if (!player->climbing && (netgame || !cv_analog.value || (player->pflags & PF_SPINNING))) - player->mo->angle = (cmd->angleturn<<16 /* not FRACBITS */); + player->drawangle = player->mo->angle = (cmd->angleturn<<16 /* not FRACBITS */); ticruned++; if (!(cmd->angleturn & TICCMD_RECEIVED)) diff --git a/src/m_cond.c b/src/m_cond.c index 9339c4989..e9d655694 100644 --- a/src/m_cond.c +++ b/src/m_cond.c @@ -980,18 +980,18 @@ UINT8 M_CompletionEmblems(void) // Bah! Duplication sucks, but it's for a separa levelnum = emblemlocations[i].level; embtype = emblemlocations[i].var; flags = MV_BEATEN; - + if (embtype & ME_ALLEMERALDS) flags |= MV_ALLEMERALDS; - + if (embtype & ME_ULTIMATE) flags |= MV_ULTIMATE; - + if (embtype & ME_PERFECT) flags |= MV_PERFECT; - + res = ((mapvisited[levelnum - 1] & flags) == flags); - + emblemlocations[i].collected = res; if (res) ++somethingUnlocked; diff --git a/src/m_fixed.h b/src/m_fixed.h index 1cf9abbae..773823988 100644 --- a/src/m_fixed.h +++ b/src/m_fixed.h @@ -20,9 +20,10 @@ #include #endif -#ifdef _WIN32_WCE -#include "sdl/SRB2CE/cehelp.h" -#endif +// Was this just for the #define USEASM? +//#ifdef _WIN32_WCE +//#include "sdl12/SRB2CE/cehelp.h" +//#endif /*! \brief bits of the fraction diff --git a/src/m_menu.c b/src/m_menu.c index 64255e71a..748c78ad1 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -172,7 +172,9 @@ static char joystickInfo[8][25]; static UINT32 serverlistpage; #endif -static saveinfo_t savegameinfo[MAXSAVEGAMES]; // Extra info about the save games. +static UINT8 numsaves = 0; +static saveinfo_t* savegameinfo = NULL; // Extra info about the save games. +static patch_t *savselp[7]; INT16 startmap; // Mario, NiGHTS, or just a plain old normal game? @@ -222,7 +224,7 @@ static INT32 lsoffs[2]; #define lshli levelselectselect[2] #define lshseperation 101 -#define lsbasevseperation 62 +#define lsbasevseperation (62*vid.height)/(BASEVIDHEIGHT*vid.dupy) //62 #define lsheadingheight 16 #define getheadingoffset(row) (levelselect.rows[row].header[0] ? lsheadingheight : 0) #define lsvseperation(row) lsbasevseperation + getheadingoffset(row) @@ -1061,7 +1063,9 @@ static menuitem_t OP_P1ControlsMenu[] = {IT_STRING | IT_CVAR, NULL, "Flip Camera with Gravity" , &cv_flipcam , 60}, {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair, 70}, - {IT_STRING | IT_CVAR, NULL, "Analog Control", &cv_useranalog, 90}, + //{IT_STRING | IT_CVAR, NULL, "Analog Control", &cv_useranalog, 90}, + {IT_STRING | IT_CVAR, NULL, "Character angle", &cv_directionchar, 90}, + {IT_STRING | IT_CVAR, NULL, "Automatic braking", &cv_autobrake, 100}, }; static menuitem_t OP_P2ControlsMenu[] = @@ -1074,7 +1078,9 @@ static menuitem_t OP_P2ControlsMenu[] = {IT_STRING | IT_CVAR, NULL, "Flip Camera with Gravity" , &cv_flipcam2 , 60}, {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair2, 70}, - {IT_STRING | IT_CVAR, NULL, "Analog Control", &cv_useranalog2, 90}, + //{IT_STRING | IT_CVAR, NULL, "Analog Control", &cv_useranalog2, 90}, + {IT_STRING | IT_CVAR, NULL, "Character angle", &cv_directionchar2, 90}, + {IT_STRING | IT_CVAR, NULL, "Automatic braking", &cv_autobrake2, 100}, }; static menuitem_t OP_ChangeControlsMenu[] = @@ -2580,7 +2586,7 @@ boolean M_Responder(event_t *ev) { if (((currentMenu->menuitems[itemOn].status & IT_CALLTYPE) & IT_CALL_NOTMODIFIED) && modifiedgame && !savemoddata) { - S_StartSound(NULL, sfx_menu1); + S_StartSound(NULL, sfx_skid); M_StartMessage(M_GetText("This cannot be done in a modified game.\n\n(Press a key)\n"), NULL, MM_NOTHING); return true; } @@ -3247,6 +3253,7 @@ static void M_DrawGenericMenu(void) W_CachePatchName(currentMenu->menuitems[i].patch, PU_CACHE)); } } + /* FALLTHRU */ case IT_NOTHING: case IT_DYBIGSPACE: y += LINEHEIGHT; @@ -3305,6 +3312,7 @@ static void M_DrawGenericMenu(void) break; case IT_STRING2: V_DrawString(x, y, 0, currentMenu->menuitems[i].text); + /* FALLTHRU */ case IT_DYLITLSPACE: y += SMALLLINEHEIGHT; break; @@ -3317,6 +3325,7 @@ static void M_DrawGenericMenu(void) case IT_TRANSTEXT: if (currentMenu->menuitems[i].alphaKey) y = currentMenu->y+currentMenu->menuitems[i].alphaKey; + /* FALLTHRU */ case IT_TRANSTEXT2: V_DrawString(x, y, V_TRANSLUCENT, currentMenu->menuitems[i].text); y += SMALLLINEHEIGHT; @@ -3666,6 +3675,7 @@ static void M_DrawCenteredMenu(void) W_CachePatchName(currentMenu->menuitems[i].patch, PU_CACHE)); } } + /* FALLTHRU */ case IT_NOTHING: case IT_DYBIGSPACE: y += LINEHEIGHT; @@ -3723,6 +3733,7 @@ static void M_DrawCenteredMenu(void) break; case IT_STRING2: V_DrawCenteredString(x, y, 0, currentMenu->menuitems[i].text); + /* FALLTHRU */ case IT_DYLITLSPACE: y += SMALLLINEHEIGHT; break; @@ -4061,10 +4072,10 @@ static boolean M_PrepareLevelPlatter(INT32 gt) if (actnum) sprintf(mapname, "%s %d", mapheaderinfo[mapnum]->lvlttl, actnum); else - sprintf(mapname, "%s", mapheaderinfo[mapnum]->lvlttl); + strcpy(mapname, mapheaderinfo[mapnum]->lvlttl); if (strlen(mapname) >= 17) - sprintf(mapname+17-3, "..."); + strcpy(mapname+17-3, "..."); strcpy(levelselect.rows[row].mapnames[col], (const char *)mapname); } @@ -4093,6 +4104,24 @@ static boolean M_PrepareLevelPlatter(INT32 gt) mapnum++; } +#ifdef SYMMETRICAL_PLATTER + // horizontally space out rows with missing right sides + for (; row >= 0; row--) + { + if (!levelselect.rows[row].maplist[2] // no right side + && levelselect.rows[row].maplist[0] && levelselect.rows[row].maplist[1]) // all the left filled in + { + levelselect.rows[row].maplist[2] = levelselect.rows[row].maplist[1]; + STRBUFCPY(levelselect.rows[row].mapnames[2], levelselect.rows[row].mapnames[1]); + levelselect.rows[row].mapavailable[2] = levelselect.rows[row].mapavailable[1]; + + levelselect.rows[row].maplist[1] = -1; // diamond + levelselect.rows[row].mapnames[1][0] = '\0'; + levelselect.rows[row].mapavailable[1] = false; + } + } +#endif + if (levselp[0][0]) // never going to have some provided but not all, saves individually checking { W_UnlockCachedPatch(levselp[0][0]); @@ -4230,7 +4259,7 @@ static void M_HandleLevelPlatter(INT32 choice) else if (!lsoffs[0]) // prevent sound spam { lsoffs[0] = -8; - S_StartSound(NULL,sfx_s3kb2); + S_StartSound(NULL,sfx_lose); } break; @@ -4261,14 +4290,10 @@ void M_DrawLevelPlatterHeader(INT32 y, const char *header, boolean headerhighlig y += lsheadingheight - 12; V_DrawString(19, y, (headerhighlight ? V_YELLOWMAP : 0)|(allowlowercase ? V_ALLOWLOWERCASE : 0), header); y += 9; - if ((y >= 0) && (y < 200)) - { - V_DrawFill(19, y, 281, 1, (headerhighlight ? yellowmap[3] : 3)); - V_DrawFill(300, y, 1, 1, 26); - } + V_DrawFill(19, y, 281, 1, (headerhighlight ? yellowmap[3] : 3)); + V_DrawFill(300, y, 1, 1, 26); y++; - if ((y >= 0) && (y < 200)) - V_DrawFill(19, y, 282, 1, 26); + V_DrawFill(19, y, 282, 1, 26); } static void M_DrawLevelPlatterWideMap(UINT8 row, UINT8 col, INT32 x, INT32 y, boolean highlight) @@ -4276,7 +4301,7 @@ static void M_DrawLevelPlatterWideMap(UINT8 row, UINT8 col, INT32 x, INT32 y, bo patch_t *patch; INT32 map = levelselect.rows[row].maplist[col]; - if (!map) + if (map <= 0) return; // A 564x100 image of the level as entry MAPxxW @@ -4292,22 +4317,9 @@ static void M_DrawLevelPlatterWideMap(UINT8 row, UINT8 col, INT32 x, INT32 y, bo V_DrawSmallScaledPatch(x, y, 0, patch); } - if ((y+50) < 200) - { - INT32 topy = (y+50), h = 8; - - if (topy < 0) - { - h += topy; - topy = 0; - } - else if (topy + h >= 200) - h = 200 - y; - if (h > 0) - V_DrawFill(x, topy, 282, h, - ((mapheaderinfo[map-1]->unlockrequired < 0) - ? 159 : 63)); - } + V_DrawFill(x, y+50, 282, 8, + ((mapheaderinfo[map-1]->unlockrequired < 0) + ? 159 : 63)); V_DrawString(x, y+50, (highlight ? V_YELLOWMAP : 0), levelselect.rows[row].mapnames[col]); } @@ -4317,7 +4329,7 @@ static void M_DrawLevelPlatterMap(UINT8 row, UINT8 col, INT32 x, INT32 y, boolea patch_t *patch; INT32 map = levelselect.rows[row].maplist[col]; - if (!map) + if (map <= 0) return; // A 160x100 image of the level as entry MAPxxP @@ -4333,22 +4345,9 @@ static void M_DrawLevelPlatterMap(UINT8 row, UINT8 col, INT32 x, INT32 y, boolea V_DrawSmallScaledPatch(x, y, 0, patch); } - if ((y+50) < 200) - { - INT32 topy = (y+50), h = 8; - - if (topy < 0) - { - h += topy; - topy = 0; - } - else if (topy + h >= 200) - h = 200 - y; - if (h > 0) - V_DrawFill(x, topy, 80, h, - ((mapheaderinfo[map-1]->unlockrequired < 0) - ? 159 : 63)); - } + V_DrawFill(x, y+50, 80, 8, + ((mapheaderinfo[map-1]->unlockrequired < 0) + ? 159 : 63)); if (strlen(levelselect.rows[row].mapnames[col]) > 6) // "AERIAL GARDEN" vs "ACT 18" - "THE ACT" intentionally compressed V_DrawThinString(x, y+50, (highlight ? V_YELLOWMAP : 0), levelselect.rows[row].mapnames[col]); @@ -4402,16 +4401,16 @@ static void M_DrawLevelPlatterMenu(void) // draw cursor box V_DrawSmallScaledPatch(lsbasex + cursorx + lsoffs[1], lsbasey, 0, (levselp[sizeselect][((skullAnimCounter/4) ? 1 : 0)])); - if (levelselect.rows[lsrow].maplist[lscol]) + if (levelselect.rows[lsrow].maplist[lscol] > 0) V_DrawScaledPatch(lsbasex + cursorx-17, lsbasey+50+lsoffs[0], 0, W_CachePatchName("M_CURSOR", PU_CACHE)); // handle movement of cursor box - if (abs(lsoffs[0]) > 1) + if (lsoffs[0] > 1 || lsoffs[0] < -1) lsoffs[0] = 2*lsoffs[0]/3; else lsoffs[0] = 0; - if (abs(lsoffs[1]) > 1) + if (lsoffs[1] > 1 || lsoffs[1] < -1) lsoffs[1] = 2*lsoffs[1]/3; else lsoffs[1] = 0; @@ -4885,6 +4884,10 @@ static boolean M_AddonsRefresh(void) #define offs 1 +#ifdef __GNUC__ +#pragma GCC optimize ("0") +#endif + static void M_DrawAddons(void) { INT32 x, y; @@ -5006,6 +5009,10 @@ static void M_DrawAddons(void) #undef CANSAVE } +#ifdef __GNUC__ +#pragma GCC reset_options +#endif + #undef offs static void M_AddonExec(INT32 ch) @@ -5395,7 +5402,7 @@ static void M_LevelSelectWarp(INT32 choice) G_LoadGame((UINT32)cursaveslot, startmap); else { - cursaveslot = -1; + cursaveslot = 0; M_SetupChoosePlayer(0); } } @@ -5970,7 +5977,7 @@ static void M_CustomWarp(INT32 choice) static void M_Credits(INT32 choice) { (void)choice; - cursaveslot = -2; + cursaveslot = -1; M_ClearMenus(true); F_StartCredits(); } @@ -6028,149 +6035,285 @@ static void M_LoadGameLevelSelect(INT32 choice) // LOAD GAME MENU // ============== -static INT32 saveSlotSelected = 0; -static short menumovedir = 0; +static INT32 saveSlotSelected = 1; +static INT32 loadgamescroll = 0; +static UINT8 loadgameoffset = 0; static void M_DrawLoadGameData(void) { - INT32 ecks; - INT32 i; + INT32 i, savetodraw, x, y, hsep = 90; + skin_t *charskin = NULL; - ecks = SP_LoadDef.x + 24; - M_DrawTextBox(SP_LoadDef.x-12,144, 24, 4); + if (vid.width != BASEVIDWIDTH*vid.dupx) + hsep = (hsep*vid.width)/(BASEVIDWIDTH*vid.dupx); - if (saveSlotSelected == NOSAVESLOT) // last slot is play without saving + for (i = -2; i <= 2; i++) { - if (ultimate_selectable) + savetodraw = (saveSlotSelected + i + numsaves)%numsaves; + x = (BASEVIDWIDTH/2 - 42 + loadgamescroll) + (i*hsep); + y = 33 + 9; + { - V_DrawCenteredString(ecks + 68, 144, V_ORANGEMAP, "ULTIMATE MODE"); - V_DrawCenteredString(ecks + 68, 156, 0, "NO RINGS, NO ONE-UPS,"); - V_DrawCenteredString(ecks + 68, 164, 0, "NO CONTINUES, ONE LIFE,"); - V_DrawCenteredString(ecks + 68, 172, 0, "FINAL DESTINATION."); + INT32 diff = x - (BASEVIDWIDTH/2 - 42); + if (diff < 0) + diff = -diff; + diff = (42 - diff)/3 - loadgameoffset; + if (diff < 0) + diff = 0; + y -= diff; } - else - { - V_DrawCenteredString(ecks + 68, 144, V_ORANGEMAP, "PLAY WITHOUT SAVING"); - V_DrawCenteredString(ecks + 68, 156, 0, "THIS GAME WILL NOT BE"); - V_DrawCenteredString(ecks + 68, 164, 0, "SAVED, BUT YOU CAN STILL"); - V_DrawCenteredString(ecks + 68, 172, 0, "GET EMBLEMS AND SECRETS."); - } - return; - } - - if (savegameinfo[saveSlotSelected].lives == -42) // Empty - { - V_DrawCenteredString(ecks + 68, 160, 0, "NO DATA"); - return; - } - - if (savegameinfo[saveSlotSelected].lives == -666) // savegame is bad - { - V_DrawCenteredString(ecks + 68, 144, V_REDMAP, "CORRUPT SAVE FILE"); - V_DrawCenteredString(ecks + 68, 156, 0, "THIS SAVE FILE"); - V_DrawCenteredString(ecks + 68, 164, 0, "CAN NOT BE LOADED."); - V_DrawCenteredString(ecks + 68, 172, 0, "DELETE USING BACKSPACE."); - return; - } - - // Draw the back sprite, it looks ugly if we don't - V_DrawScaledPatch(SP_LoadDef.x, 144+8, 0, livesback); - if (savegameinfo[saveSlotSelected].skincolor == 0) - V_DrawScaledPatch(SP_LoadDef.x,144+8,0,W_CachePatchName(skins[savegameinfo[saveSlotSelected].skinnum].face, PU_CACHE)); - else - { - UINT8 *colormap = R_GetTranslationColormap(savegameinfo[saveSlotSelected].skinnum, savegameinfo[saveSlotSelected].skincolor, 0); - V_DrawMappedPatch(SP_LoadDef.x,144+8,0,W_CachePatchName(skins[savegameinfo[saveSlotSelected].skinnum].face, PU_CACHE), colormap); - } - - V_DrawString(ecks + 12, 152, 0, savegameinfo[saveSlotSelected].playername); - -#ifdef SAVEGAMES_OTHERVERSIONS - if (savegameinfo[saveSlotSelected].gamemap & 16384) - V_DrawCenteredString(ecks + 68, 144, V_REDMAP, "OUTDATED SAVE FILE!"); -#endif - - if (savegameinfo[saveSlotSelected].gamemap & 8192) - V_DrawString(ecks + 12, 160, V_GREENMAP, "CLEAR!"); - else - V_DrawString(ecks + 12, 160, 0, va("%s", savegameinfo[saveSlotSelected].levelname)); - - // Use the big face pic for lives, duh. :3 - V_DrawScaledPatch(ecks + 12, 175, 0, W_CachePatchName("STLIVEX", PU_HUDGFX)); - V_DrawTallNum(ecks + 40, 172, 0, savegameinfo[saveSlotSelected].lives); - - // Absolute ridiculousness, condensed into another function. - V_DrawContinueIcon(ecks + 58, 182, 0, savegameinfo[saveSlotSelected].skinnum, savegameinfo[saveSlotSelected].skincolor); - V_DrawScaledPatch(ecks + 68, 175, 0, W_CachePatchName("STLIVEX", PU_HUDGFX)); - V_DrawTallNum(ecks + 96, 172, 0, savegameinfo[saveSlotSelected].continues); - - for (i = 0; i < 7; ++i) - { - if (savegameinfo[saveSlotSelected].numemeralds & (1 << i)) - V_DrawScaledPatch(ecks + 104 + (i * 8), 172, 0, tinyemeraldpics[i]); - } -} - -#define LOADBARHEIGHT SP_LoadDef.y + (LINEHEIGHT * (j+1)) + ymod -#define CURSORHEIGHT SP_LoadDef.y + (LINEHEIGHT*3) - 1 -static void M_DrawLoad(void) -{ - INT32 i, j; - INT32 ymod = 0, offset = 0; - - M_DrawMenuTitle(); - - if (menumovedir != 0) //movement illusion - { - ymod = (-(LINEHEIGHT/4))*menumovedir; - offset = ((menumovedir > 0) ? -1 : 1); - } - - V_DrawCenteredString(BASEVIDWIDTH/2, 40, 0, "Press backspace to delete a save."); - - for (i = MAXSAVEGAMES + saveSlotSelected - 2 + offset, j = 0;i <= MAXSAVEGAMES + saveSlotSelected + 2 + offset; i++, j++) - { - if ((menumovedir < 0 && j == 4) || (menumovedir > 0 && j == 0)) - continue; //this helps give the illusion of movement - - M_DrawSaveLoadBorder(SP_LoadDef.x, LOADBARHEIGHT); - - if ((i%MAXSAVEGAMES) == NOSAVESLOT) // play without saving + + if (savetodraw == 0) { + V_DrawSmallScaledPatch(x, y, 0, + savselp[((ultimate_selectable) ? 2 : 1)]); + x += 2; + y += 1; + V_DrawString(x, y, + ((savetodraw == saveSlotSelected) ? V_YELLOWMAP : 0), + "NO FILE"); + if (savetodraw == saveSlotSelected) + V_DrawFill(x, y+9, 80, 1, yellowmap[3]); + y += 11; + V_DrawSmallScaledPatch(x, y, V_STATIC, savselp[4]); + y += 41; if (ultimate_selectable) - V_DrawCenteredString(SP_LoadDef.x+92, LOADBARHEIGHT - 1, V_ORANGEMAP, "ULTIMATE MODE"); + V_DrawRightAlignedThinString(x + 79, y, V_REDMAP, "ULTIMATE."); else - V_DrawCenteredString(SP_LoadDef.x+92, LOADBARHEIGHT - 1, V_ORANGEMAP, "PLAY WITHOUT SAVING"); + V_DrawRightAlignedThinString(x + 79, y, V_GRAYMAP, "DON'T SAVE!"); continue; } - if (savegameinfo[i%MAXSAVEGAMES].lives == -42) - V_DrawString(SP_LoadDef.x-6, LOADBARHEIGHT - 1, V_TRANSLUCENT, "NO DATA"); - else if (savegameinfo[i%MAXSAVEGAMES].lives == -666) - V_DrawString(SP_LoadDef.x-6, LOADBARHEIGHT - 1, V_REDMAP, "CORRUPT SAVE FILE"); - else if (savegameinfo[i%MAXSAVEGAMES].gamemap & 8192) - V_DrawString(SP_LoadDef.x-6, LOADBARHEIGHT - 1, V_GREENMAP, "CLEAR!"); - else - V_DrawString(SP_LoadDef.x-6, LOADBARHEIGHT - 1, 0, va("%s", savegameinfo[i%MAXSAVEGAMES].levelname)); + savetodraw--; - //Draw the save slot number on the right side - V_DrawRightAlignedString(SP_LoadDef.x+192, LOADBARHEIGHT - 1, 0, va("%d",(i%MAXSAVEGAMES) + 1)); + if (savegameinfo[savetodraw].lives > 0) + charskin = &skins[savegameinfo[savetodraw].skinnum]; + + // signpost background + { + UINT8 col; + if (savegameinfo[savetodraw].lives == -666) + { + V_DrawSmallScaledPatch(x+2, y+64, 0, savselp[5]); + } +#ifndef PERFECTSAVE // disabled, don't touch + else if ((savegameinfo[savetodraw].skinnum == 1) + && (savegameinfo[savetodraw].lives == 99) + && (savegameinfo[savetodraw].gamemap & 8192) + && (savegameinfo[savetodraw].numgameovers == 0) + && (savegameinfo[savetodraw].numemeralds == ((1<<7) - 1))) // perfect save + { + V_DrawFill(x+6, y+64, 72, 50, 134); + V_DrawFill(x+6, y+74, 72, 30, 201); + V_DrawFill(x+6, y+84, 72, 10, 1); + } +#endif + else + { + if (savegameinfo[savetodraw].lives == -42) + col = 26; + else if (savegameinfo[savetodraw].botskin == 3) // & knuckles + col = 105; + else if (savegameinfo[savetodraw].botskin) // tailsbot or custom + col = 134; + else + { + col = (charskin->prefcolor - 1)*2; + col = Color_Index[Color_Opposite[col]-1][Color_Opposite[col+1]]; + } + + V_DrawFill(x+6, y+64, 72, 50, col); + } + } + + V_DrawSmallScaledPatch(x, y, 0, savselp[0]); + x += 2; + y += 1; + V_DrawString(x, y, + ((savetodraw == saveSlotSelected-1) ? V_YELLOWMAP : 0), + va("FILE %d", savetodraw+1)); + if (savetodraw == saveSlotSelected-1) + V_DrawFill(x, y+9, 80, 1, yellowmap[3]); + y += 11; + + // level image area + { + patch_t *patch; + INT32 flags = 0; + + if ((savegameinfo[savetodraw].lives == -42) + || (savegameinfo[savetodraw].lives == -666)) + { + patch = savselp[3]; + flags = V_STATIC; + } + else if (savegameinfo[savetodraw].gamemap & 8192) + patch = savselp[6]; + else + { + lumpnum_t lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName((savegameinfo[savetodraw].gamemap) & 8191))); + if (lumpnum != LUMPERROR) + patch = W_CachePatchNum(lumpnum, PU_CACHE); + else + patch = savselp[5]; + } + + V_DrawSmallScaledPatch(x, y, flags, patch); + + y += 41; + + if (savegameinfo[savetodraw].lives == -42) + V_DrawRightAlignedThinString(x + 79, y, V_GRAYMAP, "NEW GAME"); + else if (savegameinfo[savetodraw].lives == -666) + V_DrawRightAlignedThinString(x + 79, y, V_REDMAP, "CAN'T LOAD!"); + else if (savegameinfo[savetodraw].gamemap & 8192) + V_DrawRightAlignedThinString(x + 79, y, V_GREENMAP, "CLEAR!"); + else + V_DrawRightAlignedThinString(x + 79, y, V_YELLOWMAP, savegameinfo[savetodraw].levelname); + } + + if ((savegameinfo[savetodraw].lives == -42) + || (savegameinfo[savetodraw].lives == -666)) + continue; + + y += 64; + + // tiny emeralds + { + INT32 j, workx = x + 6; + for (j = 0; j < 7; ++j) + { + if (savegameinfo[savetodraw].numemeralds & (1 << j)) + V_DrawScaledPatch(workx, y, 0, tinyemeraldpics[j]); + workx += 10; + } + } + + y -= 13; + + // character heads, lives, and continues + { + spritedef_t *sprdef; + spriteframe_t *sprframe; + patch_t *patch; + UINT8 *colormap = NULL; + + INT32 tempx = (x+40)<sprites[SPR2_SIGN]; + if (!sprdef->numframes) + goto skipbot; + colormap = R_GetTranslationColormap(savegameinfo[savetodraw].botskin, charbotskin->prefcolor, 0); + sprframe = &sprdef->spriteframes[0]; + patch = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE); + + V_DrawFixedPatch( + tempx + (18<highresscale, + 0, patch, colormap); + + Z_Free(colormap); + + tempx -= (15<sprites[SPR2_SIGN]; + colormap = R_GetTranslationColormap(savegameinfo[savetodraw].skinnum, charskin->prefcolor, 0); + if (!sprdef->numframes) + goto skipsign; + sprframe = &sprdef->spriteframes[0]; + patch = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE); + if ((calc = SHORT(patch->topoffset) - 42) > 0) + tempy += ((4+calc)<highresscale, + flip, patch, colormap); + +skipsign: + y += 25; + + tempx = x + 10; + if (savegameinfo[savetodraw].lives != 0x7f + && savegameinfo[savetodraw].lives > 9) + tempx -= 4; + + if (!charskin) // shut up compiler + goto skiplife; + + // lives + sprdef = &charskin->sprites[SPR2_LIFE]; + if (!sprdef->numframes) + goto skiplife; + sprframe = &sprdef->spriteframes[0]; + patch = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE); + + V_DrawFixedPatch( + (tempx + 4)<highresscale/2, + 0, patch, colormap); +skiplife: + if (colormap) + Z_Free(colormap); + + patch = W_CachePatchName("STLIVEX", PU_CACHE); + + V_DrawScaledPatch(tempx + 9, y + 2, 0, patch); + tempx += 16; + if (savegameinfo[savetodraw].lives == 0x7f) + V_DrawCharacter(tempx, y + 1, '\x16', false); + else + V_DrawString(tempx, y, 0, va("%d", savegameinfo[savetodraw].lives)); + + tempx = x + 47; + if (savegameinfo[savetodraw].continues > 9) + tempx -= 4; + + // continues + if (savegameinfo[savetodraw].continues > 0) + { + V_DrawSmallScaledPatch(tempx, y, 0, W_CachePatchName("CONTSAVE", PU_CACHE)); + V_DrawScaledPatch(tempx + 9, y + 2, 0, patch); + V_DrawString(tempx + 16, y, 0, va("%d", savegameinfo[savetodraw].continues)); + } + else + { + V_DrawSmallScaledPatch(tempx, y, 0, W_CachePatchName("CONTNONE", PU_CACHE)); + V_DrawScaledPatch(tempx + 9, y + 2, 0, W_CachePatchName("STNONEX", PU_CACHE)); + V_DrawString(tempx + 16, y, V_GRAYMAP, "0"); + } + } } +} - //Draw cursors on both sides. - V_DrawScaledPatch( 32, CURSORHEIGHT, 0, W_CachePatchName("M_CURSOR", PU_CACHE)); - V_DrawScaledPatch(274, CURSORHEIGHT, 0, W_CachePatchName("M_CURSOR", PU_CACHE)); +static void M_DrawLoad(void) +{ + M_DrawMenuTitle(); + + if (loadgamescroll > 1 || loadgamescroll < -1) + loadgamescroll = 2*loadgamescroll/3; + else + loadgamescroll = 0; + + if (loadgameoffset > 1) + loadgameoffset = 2*loadgameoffset/3; + else + loadgameoffset = 0; M_DrawLoadGameData(); - - //finishing the movement illusion - if (menumovedir) - menumovedir += ((menumovedir > 0) ? 1 : -1); - if (abs(menumovedir) > 3) - menumovedir = 0; } -#undef LOADBARHEIGHT -#undef CURSORHEIGHT // // User wants to load this game @@ -6182,7 +6325,7 @@ static void M_LoadSelect(INT32 choice) if (saveSlotSelected == NOSAVESLOT) //last slot is play without saving { M_NewGame(); - cursaveslot = -1; + cursaveslot = 0; return; } @@ -6191,8 +6334,8 @@ static void M_LoadSelect(INT32 choice) // This slot is empty, so start a new game here. M_NewGame(); } - else if (savegameinfo[saveSlotSelected].gamemap & 8192) // Completed - M_LoadGameLevelSelect(saveSlotSelected + 1); + else if (savegameinfo[saveSlotSelected-1].gamemap & 8192) // Completed + M_LoadGameLevelSelect(0); else G_LoadGame((UINT32)saveSlotSelected, 0); @@ -6214,12 +6357,11 @@ static void M_ReadSavegameInfo(UINT32 slot) INT32 fake; // Dummy variable char temp[sizeof(timeattackfolder)]; char vcheck[VERSIONSIZE]; -#ifdef SAVEGAMES_OTHERVERSIONS - boolean oldversion = false; -#endif sprintf(savename, savegamename, slot); + slot--; + length = FIL_ReadFile(savename, &savebuffer); if (length == 0) { @@ -6235,14 +6377,7 @@ static void M_ReadSavegameInfo(UINT32 slot) // Version check memset(vcheck, 0, sizeof (vcheck)); sprintf(vcheck, "version %d", VERSION); - if (strcmp((const char *)save_p, (const char *)vcheck)) - { -#ifdef SAVEGAMES_OTHERVERSIONS - oldversion = true; -#else - BADSAVE // Incompatible versions? -#endif - } + if (strcmp((const char *)save_p, (const char *)vcheck)) BADSAVE save_p += VERSIONSIZE; // dearchive all the modifications @@ -6254,30 +6389,19 @@ static void M_ReadSavegameInfo(UINT32 slot) if (((fake-1) & 8191) >= NUMMAPS) BADSAVE if(!mapheaderinfo[(fake-1) & 8191]) - { savegameinfo[slot].levelname[0] = '\0'; - savegameinfo[slot].actnum = 0; - } else { - strcpy(savegameinfo[slot].levelname, mapheaderinfo[(fake-1) & 8191]->lvlttl); - savegameinfo[slot].actnum = mapheaderinfo[(fake-1) & 8191]->actnum; + strlcpy(savegameinfo[slot].levelname, mapheaderinfo[(fake-1) & 8191]->lvlttl, 17+1); + + if (strlen(mapheaderinfo[(fake-1) & 8191]->lvlttl) >= 17) + strcpy(savegameinfo[slot].levelname+17-3, "..."); } -#ifdef SAVEGAMES_OTHERVERSIONS - if (oldversion) - { - if (fake == 24) //meh, let's count old Clear! saves too - fake |= 8192; - fake |= 16384; // marker for outdated version - } -#endif savegameinfo[slot].gamemap = fake; CHECKPOS - fake = READUINT16(save_p)-357; // emeralds - - savegameinfo[slot].numemeralds = (UINT8)fake; + savegameinfo[slot].numemeralds = READUINT16(save_p)-357; // emeralds CHECKPOS READSTRINGN(save_p, temp, sizeof(temp)); // mod it belongs to @@ -6286,39 +6410,25 @@ static void M_ReadSavegameInfo(UINT32 slot) // P_UnArchivePlayer() CHECKPOS - savegameinfo[slot].skincolor = READUINT8(save_p); - CHECKPOS - savegameinfo[slot].skinnum = READUINT8(save_p); + fake = READUINT16(save_p); + savegameinfo[slot].skinnum = fake & ((1<<5) - 1); + if (savegameinfo[slot].skinnum >= numskins + || !R_SkinUsable(-1, savegameinfo[slot].skinnum)) + BADSAVE + savegameinfo[slot].botskin = fake >> 5; + if (savegameinfo[slot].botskin-1 >= numskins + || !R_SkinUsable(-1, savegameinfo[slot].botskin-1)) + BADSAVE + CHECKPOS + savegameinfo[slot].numgameovers = READUINT8(save_p); // numgameovers + CHECKPOS + savegameinfo[slot].lives = READSINT8(save_p); // lives CHECKPOS (void)READINT32(save_p); // Score - - CHECKPOS - savegameinfo[slot].lives = READINT32(save_p); // lives CHECKPOS savegameinfo[slot].continues = READINT32(save_p); // continues - if (fake & (1<<10)) - { - CHECKPOS - savegameinfo[slot].botskin = READUINT8(save_p); - if (savegameinfo[slot].botskin-1 >= numskins) - savegameinfo[slot].botskin = 0; - CHECKPOS - savegameinfo[slot].botcolor = READUINT8(save_p); // because why not. - } - else - savegameinfo[slot].botskin = 0; - - if (savegameinfo[slot].botskin) - snprintf(savegameinfo[slot].playername, 32, "%s & %s", - skins[savegameinfo[slot].skinnum].realname, - skins[savegameinfo[slot].botskin-1].realname); - else - strcpy(savegameinfo[slot].playername, skins[savegameinfo[slot].skinnum].realname); - - savegameinfo[slot].playername[31] = 0; - // File end marker check CHECKPOS if (READUINT8(save_p) != 0x1d) BADSAVE; @@ -6337,23 +6447,80 @@ static void M_ReadSavegameInfo(UINT32 slot) static void M_ReadSaveStrings(void) { FILE *handle; - UINT32 i; + SINT8 i; char name[256]; + boolean nofile[MAXSAVEGAMES-1]; + SINT8 tolerance = 3; // empty slots at any time + UINT8 lastseen = 0; - for (i = 0; i < MAXSAVEGAMES; i++) + loadgamescroll = 0; + loadgameoffset = 14; + + for (i = 1; (i < MAXSAVEGAMES); i++) // slot 0 is no save { snprintf(name, sizeof name, savegamename, i); name[sizeof name - 1] = '\0'; handle = fopen(name, "rb"); - if (handle == NULL) + if ((nofile[i-1] = (handle == NULL))) + continue; + fclose(handle); + lastseen = i; + } + + if (savegameinfo) + Z_Free(savegameinfo); + savegameinfo = NULL; + + if (lastseen < saveSlotSelected) + lastseen = saveSlotSelected; + + i = lastseen; + + for (; (lastseen > 0 && tolerance); lastseen--) + { + if (nofile[lastseen-1]) + tolerance--; + } + + if ((i += tolerance+1) > MAXSAVEGAMES) // show 3 empty slots at minimum + i = MAXSAVEGAMES; + + numsaves = i; + savegameinfo = Z_Realloc(savegameinfo, numsaves*sizeof(saveinfo_t), PU_STATIC, NULL); + if (!savegameinfo) + I_Error("Insufficient memory to prepare save platter"); + + for (; i > 0; i--) + { + if (nofile[i-1] == true) { - savegameinfo[i].lives = -42; + savegameinfo[i-1].lives = -42; continue; } - fclose(handle); M_ReadSavegameInfo(i); } + + if (savselp[0]) // never going to have some provided but not all, saves individually checking + { + W_UnlockCachedPatch(savselp[0]); + W_UnlockCachedPatch(savselp[1]); + W_UnlockCachedPatch(savselp[2]); + + W_UnlockCachedPatch(savselp[3]); + W_UnlockCachedPatch(savselp[4]); + W_UnlockCachedPatch(savselp[5]); + W_UnlockCachedPatch(savselp[6]); + } + + savselp[0] = W_CachePatchName("SAVEBACK", PU_STATIC); + savselp[1] = W_CachePatchName("SAVENONE", PU_STATIC); + savselp[2] = W_CachePatchName("ULTIMATE", PU_STATIC); + + savselp[3] = W_CachePatchName("BLACKLVL", PU_STATIC); + savselp[4] = W_CachePatchName("BLACXLVL", PU_STATIC); + savselp[5] = W_CachePatchName("BLANKLVL", PU_STATIC); + savselp[6] = W_CachePatchName("GAMEDONE", PU_STATIC); } // @@ -6371,8 +6538,19 @@ static void M_SaveGameDeleteResponse(INT32 ch) name[sizeof name - 1] = '\0'; remove(name); - // Refresh savegame menu info - M_ReadSaveStrings(); + BwehHehHe(); + M_ReadSaveStrings(); // reload the menu +} + +static void M_SaveGameUltimateResponse(INT32 ch) +{ + if (ch != 'y' && ch != KEY_ENTER) + return; + + S_StartSound(NULL, sfx_menu1); + M_LoadSelect(saveSlotSelected); + SP_PlayerDef.prevMenu = MessageDef.prevMenu; + MessageDef.prevMenu = &SP_PlayerDef; } static void M_HandleLoadSave(INT32 choice) @@ -6381,26 +6559,46 @@ static void M_HandleLoadSave(INT32 choice) switch (choice) { - case KEY_DOWNARROW: - S_StartSound(NULL, sfx_menu1); + case KEY_RIGHTARROW: + S_StartSound(NULL, sfx_s3kb7); ++saveSlotSelected; - if (saveSlotSelected >= MAXSAVEGAMES) - saveSlotSelected -= MAXSAVEGAMES; - menumovedir = 1; + if (saveSlotSelected >= numsaves) + saveSlotSelected -= numsaves; + loadgamescroll = 90; break; - case KEY_UPARROW: - S_StartSound(NULL, sfx_menu1); + case KEY_LEFTARROW: + S_StartSound(NULL, sfx_s3kb7); --saveSlotSelected; if (saveSlotSelected < 0) - saveSlotSelected += MAXSAVEGAMES; - menumovedir = -1; + saveSlotSelected += numsaves; + loadgamescroll = -90; break; case KEY_ENTER: - S_StartSound(NULL, sfx_menu1); - if (savegameinfo[saveSlotSelected].lives != -666) // don't allow loading of "bad saves" + if (ultimate_selectable && saveSlotSelected == NOSAVESLOT) + { + loadgamescroll = 0; + S_StartSound(NULL, sfx_skid); + M_StartMessage("Are you sure you want to play\n\x85ultimate mode\x80? It isn't remotely fair,\nand you don't even get an emblem for it.\n\n(Press 'Y' to confirm)\n",M_SaveGameUltimateResponse,MM_YESNO); + } + else if (saveSlotSelected != NOSAVESLOT && savegameinfo[saveSlotSelected-1].lives == -42 && !(!modifiedgame || savemoddata)) + { + loadgamescroll = 0; + S_StartSound(NULL, sfx_skid); + M_StartMessage(M_GetText("This cannot be done in a modified game.\n\n(Press a key)\n"), NULL, MM_NOTHING); + } + else if (saveSlotSelected == NOSAVESLOT || savegameinfo[saveSlotSelected-1].lives != -666) // don't allow loading of "bad saves" + { + loadgamescroll = 0; + S_StartSound(NULL, sfx_menu1); M_LoadSelect(saveSlotSelected); + } + else if (!loadgameoffset) + { + S_StartSound(NULL, sfx_lose); + loadgameoffset = 14; + } break; case KEY_ESCAPE: @@ -6408,11 +6606,25 @@ static void M_HandleLoadSave(INT32 choice) break; case KEY_BACKSPACE: - S_StartSound(NULL, sfx_menu1); // Don't allow people to 'delete' "Play without Saving." // Nor allow people to 'delete' slots with no saves in them. - if (saveSlotSelected != NOSAVESLOT && savegameinfo[saveSlotSelected].lives != -42) - M_StartMessage(M_GetText("Are you sure you want to delete\nthis save game?\n\n(Press 'Y' to confirm)\n"),M_SaveGameDeleteResponse,MM_YESNO); + if (saveSlotSelected != NOSAVESLOT && savegameinfo[saveSlotSelected-1].lives != -42) + { + loadgamescroll = 0; + S_StartSound(NULL, sfx_skid); + M_StartMessage(va("Are you sure you want to delete\nsave file %d?\n\n(Press 'Y' to confirm)\n", saveSlotSelected),M_SaveGameDeleteResponse,MM_YESNO); + } + else if (!loadgameoffset) + { + if (saveSlotSelected == NOSAVESLOT && ultimate_selectable) + { + ultimate_selectable = false; + S_StartSound(NULL, sfx_strpst); + } + else + S_StartSound(NULL, sfx_lose); + loadgameoffset = 14; + } break; } if (exitmenu) @@ -6421,6 +6633,8 @@ static void M_HandleLoadSave(INT32 choice) M_SetupNextMenu(currentMenu->prevMenu); else M_ClearMenus(true); + Z_Free(savegameinfo); + savegameinfo = NULL; } } @@ -6440,14 +6654,15 @@ static void M_LoadGame(INT32 choice) // void M_ForceSaveSlotSelected(INT32 sslot) { - // Already there? Out of bounds? Whatever, then! - if (sslot == saveSlotSelected || sslot >= MAXSAVEGAMES) + loadgameoffset = 14; + + // Already there? Whatever, then! + if (sslot == saveSlotSelected) return; - // Figure out whether to display up movement or down movement - menumovedir = (saveSlotSelected - sslot) > 0 ? -1 : 1; - if (abs(saveSlotSelected - sslot) > (MAXSAVEGAMES>>1)) - menumovedir *= -1; + loadgamescroll = 90; + if (saveSlotSelected <= numsaves/2) + loadgamescroll = -loadgamescroll; saveSlotSelected = sslot; } @@ -6718,7 +6933,7 @@ static void M_ChoosePlayer(INT32 choice) } if (startmap != spstage_start) - cursaveslot = -1; + cursaveslot = 0; //lastmapsaved = 0; gamecomplete = false; @@ -6729,6 +6944,10 @@ static void M_ChoosePlayer(INT32 choice) if (levelselect.rows) Z_Free(levelselect.rows); levelselect.rows = NULL; + + if (savegameinfo) + Z_Free(savegameinfo); + savegameinfo = NULL; } // =============== @@ -8508,6 +8727,7 @@ static void M_HandleSetupMultiPlayer(INT32 choice) COM_BufAddText (va("%s %s\n",setupm_cvdefaultname->name,setupm_name)); break; } + /* FALLTHRU */ case KEY_RIGHTARROW: if (itemOn == 1) //player skin { @@ -8687,7 +8907,7 @@ static void M_EraseDataResponse(INT32 ch) totalplaytime = 0; F_StartIntro(); } - S_StartSound(NULL, sfx_bewar1+M_RandomKey(4)); // Bweh heh he + BwehHehHe(); M_ClearMenus(true); } @@ -8954,7 +9174,7 @@ static void M_DrawControl(void) y += SMALLLINEHEIGHT; } - + V_DrawScaledPatch(currentMenu->x - 20, cursory, 0, W_CachePatchName("M_CURSOR", PU_CACHE)); } diff --git a/src/m_menu.h b/src/m_menu.h index 53dc266d1..8040b63e6 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -215,18 +215,14 @@ typedef struct // savegame struct for save game menu typedef struct { - char playername[32]; char levelname[32]; - UINT8 actnum; - UINT8 skincolor; UINT8 skinnum; UINT8 botskin; - UINT8 botcolor; UINT8 numemeralds; + UINT8 numgameovers; INT32 lives; INT32 continues; INT32 gamemap; - UINT8 netgame; } saveinfo_t; extern description_t description[32]; @@ -238,7 +234,9 @@ extern INT16 startmap; extern INT32 ultimate_selectable; #define MAXSAVEGAMES 31 //note: last save game is "no save" -#define NOSAVESLOT MAXSAVEGAMES-1 //slot where Play Without Saving appears +#define NOSAVESLOT 0 //slot where Play Without Saving appears + +#define BwehHehHe() S_StartSound(NULL, sfx_bewar1+M_RandomKey(4)) // Bweh heh he void M_ForceSaveSlotSelected(INT32 sslot); diff --git a/src/m_misc.c b/src/m_misc.c index d271558fb..fdbb19fa7 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -1086,7 +1086,7 @@ void M_StartMovie(void) moviemode = M_StartMovieGIF(pathname); break; } - // fall thru + /* FALLTHRU */ case MM_APNG: moviemode = M_StartMovieAPNG(pathname); break; diff --git a/src/mserv.c b/src/mserv.c index a8e43bbf8..76fba835b 100644 --- a/src/mserv.c +++ b/src/mserv.c @@ -65,7 +65,7 @@ #endif #ifdef _arch_dreamcast -#include "sdl/SRB2DC/dchelp.h" +#include "sdl12/SRB2DC/dchelp.h" #endif #include // timeval,... (TIMEOUT) @@ -92,7 +92,7 @@ #include "m_misc.h" // GetRevisionString() #ifdef _WIN32_WCE -#include "sdl/SRB2CE/cehelp.h" +#include "sdl12/SRB2CE/cehelp.h" #endif #include "i_addrinfo.h" diff --git a/src/p_ceilng.c b/src/p_ceilng.c index db30b5cac..27d739414 100644 --- a/src/p_ceilng.c +++ b/src/p_ceilng.c @@ -79,7 +79,7 @@ void T_MoveCeiling(ceiling_t *ceiling) P_LinedefExecute((INT16)(ceiling->texture + INT16_MAX + 2), NULL, NULL); if (ceiling->texture > -1) // flat changing ceiling->sector->ceilingpic = ceiling->texture; - // don't break + /* FALLTHRU */ case raiseToHighest: // case raiseCeilingByLine: case moveCeilingByFrontTexture: @@ -182,6 +182,7 @@ void T_MoveCeiling(ceiling_t *ceiling) // except generalized ones, reset speed, start back up case crushAndRaise: ceiling->speed = CEILSPEED; + /* FALLTHRU */ case fastCrushAndRaise: ceiling->direction = 1; break; @@ -200,6 +201,7 @@ void T_MoveCeiling(ceiling_t *ceiling) if (ceiling->texture > -1) // flat changing ceiling->sector->ceilingpic = ceiling->texture; // don't break + /* FALLTHRU */ // in all other cases, just remove the active ceiling case lowerAndCrush: @@ -427,6 +429,7 @@ INT32 EV_DoCeiling(line_t *line, ceiling_e type) case crushAndRaise: ceiling->crush = true; ceiling->topheight = sec->ceilingheight; + /* FALLTHRU */ case lowerAndCrush: ceiling->bottomheight = sec->floorheight; ceiling->bottomheight += 4*FRACUNIT; diff --git a/src/p_enemy.c b/src/p_enemy.c index 0cf86b1ec..4d80ea479 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -4644,6 +4644,7 @@ void A_CapeChase(mobj_t *actor) fixed_t foffsetx, foffsety, boffsetx, boffsety; INT32 locvar1 = var1; INT32 locvar2 = var2; + angle_t angle; #ifdef HAVE_BLUA if (LUA_CallAction("A_CapeChase", actor)) return; @@ -4665,11 +4666,13 @@ void A_CapeChase(mobj_t *actor) return; } - foffsetx = P_ReturnThrustX(chaser, chaser->angle, FixedMul((locvar2 >> 16)*FRACUNIT, actor->scale)); - foffsety = P_ReturnThrustY(chaser, chaser->angle, FixedMul((locvar2 >> 16)*FRACUNIT, actor->scale)); + angle = (chaser->player ? chaser->player->drawangle : chaser->angle); - boffsetx = P_ReturnThrustX(chaser, chaser->angle-ANGLE_90, FixedMul((locvar2 & 65535)*FRACUNIT, actor->scale)); - boffsety = P_ReturnThrustY(chaser, chaser->angle-ANGLE_90, FixedMul((locvar2 & 65535)*FRACUNIT, actor->scale)); + foffsetx = P_ReturnThrustX(chaser, angle, FixedMul((locvar2 >> 16)*FRACUNIT, actor->scale)); + foffsety = P_ReturnThrustY(chaser, angle, FixedMul((locvar2 >> 16)*FRACUNIT, actor->scale)); + + boffsetx = P_ReturnThrustX(chaser, angle-ANGLE_90, FixedMul((locvar2 & 65535)*FRACUNIT, actor->scale)); + boffsety = P_ReturnThrustY(chaser, angle-ANGLE_90, FixedMul((locvar2 & 65535)*FRACUNIT, actor->scale)); P_UnsetThingPosition(actor); actor->x = chaser->x + foffsetx + boffsetx; @@ -4686,7 +4689,7 @@ void A_CapeChase(mobj_t *actor) actor->flags2 &= ~MF2_OBJECTFLIP; actor->z = chaser->z + FixedMul((locvar1 >> 16)*FRACUNIT, actor->scale); } - actor->angle = chaser->angle; + actor->angle = angle; P_SetThingPosition(actor); } @@ -4821,9 +4824,11 @@ void A_UnidusBall(mobj_t *actor) case 0: // at least one frame where not dashing if (!skull) ++actor->extravalue2; else break; + /* FALLTHRU */ case 1: // at least one frame where ARE dashing if (skull) ++actor->extravalue2; else break; + /* FALLTHRU */ case 2: // not dashing again? if (skull) break; // launch. @@ -6062,7 +6067,7 @@ void A_Boss7Chase(mobj_t *actor) break; } actor->threshold++; - // fall into... + /* FALLTHRU */ case 1: // Chaingun Goop A_FaceTarget(actor); P_SetMobjState(actor, S_BLACKEGG_SHOOT1); @@ -10184,7 +10189,7 @@ void A_FlickyAim(mobj_t *actor) { angle_t posvar; fixed_t chasevar, chasex, chasey; - + if (flickyhitwall) actor->movedir *= -1; diff --git a/src/p_floor.c b/src/p_floor.c index ef94bb95d..9ac6a3896 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -316,6 +316,7 @@ void T_MoveFloor(floormove_t *movefloor) case moveFloorByFrontSector: if (movefloor->texture < -1) // chained linedef executing P_LinedefExecute((INT16)(movefloor->texture + INT16_MAX + 2), NULL, NULL); + /* FALLTHRU */ case instantMoveFloorByFrontSector: if (movefloor->texture > -1) // flat changing movefloor->sector->floorpic = movefloor->texture; @@ -364,6 +365,7 @@ void T_MoveFloor(floormove_t *movefloor) case moveFloorByFrontSector: if (movefloor->texture < -1) // chained linedef executing P_LinedefExecute((INT16)(movefloor->texture + INT16_MAX + 2), NULL, NULL); + /* FALLTHRU */ case instantMoveFloorByFrontSector: if (movefloor->texture > -1) // flat changing movefloor->sector->floorpic = movefloor->texture; diff --git a/src/p_inter.c b/src/p_inter.c index d2101ca57..ba27dab63 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -483,9 +483,11 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) case MT_REDTEAMRING: if (player->ctfteam != 1) return; + /* FALLTHRU */ case MT_BLUETEAMRING: // Yes, I'm lazy. Oh well, deal with it. if (special->type == MT_BLUETEAMRING && player->ctfteam != 2) return; + /* FALLTHRU */ case MT_RING: case MT_FLINGRING: if (!(P_CanPickupItem(player, false))) @@ -1532,30 +1534,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) P_SetMobjState(special, special->info->deathstate); return; case MT_SPECIALSPIKEBALL: - if (!(!useNightsSS && G_IsSpecialStage(gamemap))) // Only for old special stages - { - P_DamageMobj(toucher, special, special, 1, 0); - return; - } - - if (player->powers[pw_invulnerability] || player->powers[pw_flashing] - || player->powers[pw_super]) - return; - if (player->powers[pw_shield] || player->bot) //If One-Hit Shield - { - P_RemoveShield(player); - S_StartSound(toucher, sfx_shldls); // Ba-Dum! Shield loss. - } + if (!useNightsSS && G_IsSpecialStage(gamemap)) // Only for old special stages + P_SpecialStageDamage(player, special, NULL); else - { - P_PlayRinglossSound(toucher); - if (player->rings >= 10) - player->rings -= 10; - else - player->rings = 0; - } - - P_DoPlayerPain(player, special, NULL); + P_DamageMobj(toucher, special, special, 1, 0); return; case MT_EGGMOBILE2_POGO: // sanity checks @@ -1871,7 +1853,7 @@ void P_CheckTimeLimit(void) for (i = 0; i < MAXPLAYERS; i++) { if (!playeringame[i] || players[i].spectator - || (players[i].pflags & PF_TAGGED) || (players[i].pflags & PF_TAGIT)) + || (players[i].pflags & PF_GAMETYPEOVER) || (players[i].pflags & PF_TAGIT)) continue; CONS_Printf(M_GetText("%s received double points for surviving the round.\n"), player_names[i]); @@ -2018,7 +2000,7 @@ void P_CheckSurvivors(void) spectators++; else if (players[i].pflags & PF_TAGIT) taggers++; - else if (!(players[i].pflags & PF_TAGGED)) + else if (!(players[i].pflags & PF_GAMETYPEOVER)) { survivorarray[survivors] = i; survivors++; @@ -2259,7 +2241,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget if ((target->player->lives <= 1) && (netgame || multiplayer) && (gametype == GT_COOP) && (cv_cooplives.value == 0)) ; - else if (!target->player->bot && !target->player->spectator && !G_IsSpecialStage(gamemap) + else if (!target->player->bot && !target->player->spectator && !G_IsSpecialStage(gamemap) && (target->player->lives != 0x7f) && G_GametypeUsesLives()) { target->player->lives -= 1; // Lose a life Tails 03-11-2000 @@ -2289,6 +2271,13 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget S_StopMusic(); // Stop the Music! Tails 03-14-2000 S_ChangeMusicInternal("_gover", false); // Yousa dead now, Okieday? Tails 03-14-2000 } + + if (!(netgame || multiplayer || demoplayback || demorecording || metalrecording || modeattacking) && numgameovers < maxgameovers) + { + numgameovers++; + if ((!modifiedgame || savemoddata) && cursaveslot > 0) + G_SaveGameOver((UINT32)cursaveslot, (target->player->continues <= 0)); + } } } target->player->playerstate = PST_DEAD; @@ -2325,7 +2314,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget } else { - if (!(target->player->pflags & PF_TAGGED)) + if (!(target->player->pflags & PF_GAMETYPEOVER)) { //otherwise, increment the tagger's score. //in hide and seek, suiciding players are counted as found. @@ -2337,7 +2326,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget P_AddPlayerScore(&players[w], 100); } - target->player->pflags |= PF_TAGGED; + target->player->pflags |= PF_GAMETYPEOVER; CONS_Printf(M_GetText("%s was found!\n"), player_names[target->player-players]); P_CheckSurvivors(); } @@ -2793,7 +2782,7 @@ static inline boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *sou } else { - player->pflags |= PF_TAGGED; //in hide and seek, the player is tagged and stays stationary. + player->pflags |= PF_GAMETYPEOVER; //in hide and seek, the player is tagged and stays stationary. CONS_Printf(M_GetText("%s was found!\n"), player_names[player-players]); // Tell everyone who is it! } @@ -2979,7 +2968,17 @@ void P_RemoveShield(player_t *player) else player->powers[pw_shield] &= SH_STACK; } - else if ((player->powers[pw_shield] & SH_NOSTACK) == SH_NONE) + else if (player->powers[pw_shield] & SH_NOSTACK) + { // First layer shields + if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ARMAGEDDON) // Give them what's coming to them! + { + P_BlackOw(player); // BAM! + player->pflags |= PF_JUMPDOWN; + } + else + player->powers[pw_shield] &= SH_STACK; + } + else { // Second layer shields if (((player->powers[pw_shield] & SH_STACK) == SH_FIREFLOWER) && !(player->powers[pw_super] || (mariomode && player->powers[pw_invulnerability]))) { @@ -2988,13 +2987,6 @@ void P_RemoveShield(player_t *player) } player->powers[pw_shield] = SH_NONE; } - else if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ARMAGEDDON) // Give them what's coming to them! - { - P_BlackOw(player); // BAM! - player->pflags |= PF_JUMPDOWN; - } - else - player->powers[pw_shield] = player->powers[pw_shield] & SH_STACK; } static void P_ShieldDamage(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype) @@ -3064,6 +3056,38 @@ static void P_RingDamage(player_t *player, mobj_t *inflictor, mobj_t *source, IN player->rings = 0; } +// +// P_SpecialStageDamage +// +// Do old special stage-style damaging +// Removes 10 rings from the player, or knocks off their shield if they have one. +// If they don't have anything, just knock the player back anyway (this doesn't kill them). +// +void P_SpecialStageDamage(player_t *player, mobj_t *inflictor, mobj_t *source) +{ + if (player->powers[pw_invulnerability] || player->powers[pw_flashing] || player->powers[pw_super]) + return; + + if (player->powers[pw_shield] || player->bot) //If One-Hit Shield + { + P_RemoveShield(player); + S_StartSound(player->mo, sfx_shldls); // Ba-Dum! Shield loss. + } + else + { + P_PlayRinglossSound(player->mo); + if (player->rings >= 10) + player->rings -= 10; + else + player->rings = 0; + } + + P_DoPlayerPain(player, inflictor, source); + + if (gametype == GT_CTF && player->gotflag & (GF_REDFLAG|GF_BLUEFLAG)) + P_PlayerFlagBurst(player, false); +} + /** Damages an object, which may or may not be a player. * For melee attacks, source and inflictor are the same. * @@ -3208,7 +3232,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da if (player->pflags & PF_GODMODE) return false; - if (!(target->player->powers[pw_carry] == CR_NIGHTSMODE || target->player->pflags & PF_NIGHTSFALL) && (maptol & TOL_NIGHTS)) + if ((maptol & TOL_NIGHTS) && target->player->powers[pw_carry] != CR_NIGHTSMODE && target->player->powers[pw_carry] != CR_NIGHTSFALL) return false; switch (damagetype) @@ -3368,7 +3392,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da P_SetMobjState(target, target->info->meleestate); // go to pinch pain state break; } - // fallthrough + /* FALLTHRU */ default: P_SetMobjState(target, target->info->painstate); break; @@ -3409,7 +3433,7 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings) if (player->rings <= 0) num_rings = 0; - if (num_rings > 32 && !(player->pflags & PF_NIGHTSFALL)) + if (num_rings > 32 && player->powers[pw_carry] != CR_NIGHTSFALL) num_rings = 32; if (player->powers[pw_emeralds]) @@ -3441,7 +3465,7 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings) // Make rings spill out around the player in 16 directions like SA, but spill like Sonic 2. // Technically a non-SA way of spilling rings. They just so happen to be a little similar. - if (player->pflags & PF_NIGHTSFALL) + if (player->powers[pw_carry] == CR_NIGHTSFALL) { ns = FixedMul(((i*FRACUNIT)/16)+2*FRACUNIT, mo->scale); mo->momx = FixedMul(FINECOSINE(fa),ns); @@ -3481,13 +3505,13 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings) } if (player->mo->eflags & MFE_VERTICALFLIP) mo->momz *= -1; + + if (P_IsObjectOnGround(player->mo)) + player->powers[pw_carry] = CR_NONE; } player->losstime += 10*TICRATE; - if (P_IsObjectOnGround(player->mo)) - player->pflags &= ~PF_NIGHTSFALL; - return; } diff --git a/src/p_local.h b/src/p_local.h index b1bfc6456..91ee0c496 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -140,6 +140,7 @@ boolean P_IsObjectOnGround(mobj_t *mo); boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec); boolean P_InSpaceSector(mobj_t *mo); boolean P_InQuicksand(mobj_t *mo); +boolean P_PlayerHitFloor(player_t *player); void P_SetObjectMomZ(mobj_t *mo, fixed_t value, boolean relative); void P_RestoreMusic(player_t *player); @@ -417,6 +418,7 @@ void P_ForceFeed(const player_t *player, INT32 attack, INT32 fade, tic_t duratio void P_ForceConstant(const BasicFF_t *FFInfo); void P_RampConstant(const BasicFF_t *FFInfo, INT32 Start, INT32 End); void P_RemoveShield(player_t *player); +void P_SpecialStageDamage(player_t *player, mobj_t *inflictor, mobj_t *source); boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype); void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damagetype); void P_PlayerRingBurst(player_t *player, INT32 num_rings); /// \todo better fit in p_user.c diff --git a/src/p_map.c b/src/p_map.c index 38c310d0b..6d1760596 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -195,16 +195,20 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) if (spring->flags & MF_ENEMY) // Spring shells P_SetTarget(&spring->target, object); - if (horizspeed && object->player->cmd.forwardmove == 0 && object->player->cmd.sidemove == 0) + if (horizspeed) { - object->angle = spring->angle; - - if (!demoplayback || P_AnalogMove(object->player)) + object->player->drawangle = spring->angle; + if (object->player->cmd.forwardmove == 0 && object->player->cmd.sidemove == 0) { - if (object->player == &players[consoleplayer]) - localangle = spring->angle; - else if (object->player == &players[secondarydisplayplayer]) - localangle2 = spring->angle; + object->angle = spring->angle; + + if (!demoplayback || P_AnalogMove(object->player)) + { + if (object->player == &players[consoleplayer]) + localangle = spring->angle; + else if (object->player == &players[secondarydisplayplayer]) + localangle2 = spring->angle; + } } } diff --git a/src/p_mobj.c b/src/p_mobj.c index 8f9c44fdb..10bdee2bc 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -34,6 +34,7 @@ #ifdef ESLOPE #include "p_slopes.h" #endif +#include "f_finale.h" // protos. static CV_PossibleValue_t viewheight_cons_t[] = {{16, "MIN"}, {56, "MAX"}, {0, NULL}}; @@ -250,6 +251,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) player->panim = PA_EDGE; break; case S_PLAY_WALK: + case S_PLAY_SKID: case S_PLAY_FLOAT: player->panim = PA_WALK; break; @@ -1964,6 +1966,8 @@ void P_XYMovement(mobj_t *mo) #endif P_SlideMove(mo); + if (player) + player->powers[pw_pushing] = 3; xmove = ymove = 0; #ifdef ESLOPE @@ -3040,110 +3044,9 @@ static void P_PlayerZMovement(mobj_t *mo) } } - if (mo->health && !mo->player->spectator && !P_CheckDeathPitCollide(mo)) - { - if ((mo->player->charability2 == CA2_SPINDASH) && !(mo->player->pflags & PF_THOKKED) && (mo->player->cmd.buttons & BT_USE) && (FixedHypot(mo->momx, mo->momy) > (5*mo->scale))) - { - mo->player->pflags |= PF_SPINNING; - P_SetPlayerMobjState(mo, S_PLAY_ROLL); - S_StartSound(mo, sfx_spin); - } - else - mo->player->pflags &= ~PF_SPINNING; - - if (mo->player->pflags & PF_GLIDING) // ground gliding - { - mo->player->skidtime = TICRATE; - mo->tics = -1; - } - else if (mo->player->charability2 == CA2_MELEE && (mo->player->panim == PA_ABILITY2 && mo->state-states != S_PLAY_MELEE_LANDING)) - { - P_SetPlayerMobjState(mo, S_PLAY_MELEE_LANDING); - mo->tics = (mo->movefactor == FRACUNIT) ? TICRATE/2 : (FixedDiv(35<<(FRACBITS-1), FixedSqrt(mo->movefactor)))>>FRACBITS; - S_StartSound(mo, sfx_s3k8b); - mo->player->pflags |= PF_FULLSTASIS; - } - else if (mo->player->pflags & PF_JUMPED || !(mo->player->pflags & PF_SPINNING) - || mo->player->powers[pw_tailsfly] || mo->state-states == S_PLAY_FLY_TIRED) - { - if (mo->player->cmomx || mo->player->cmomy) - { - if (mo->player->charflags & SF_DASHMODE && mo->player->dashmode >= 3*TICRATE && mo->player->panim != PA_DASH) - P_SetPlayerMobjState(mo, S_PLAY_DASH); - else if (mo->player->speed >= FixedMul(mo->player->runspeed, mo->scale) - && (mo->player->panim != PA_RUN || mo->state-states == S_PLAY_FLOAT_RUN)) - P_SetPlayerMobjState(mo, S_PLAY_RUN); - else if ((mo->player->rmomx || mo->player->rmomy) - && (mo->player->panim != PA_WALK || mo->state-states == S_PLAY_FLOAT)) - P_SetPlayerMobjState(mo, S_PLAY_WALK); - else if (!mo->player->rmomx && !mo->player->rmomy && mo->player->panim != PA_IDLE) - P_SetPlayerMobjState(mo, S_PLAY_STND); - } - else - { - if (mo->player->charflags & SF_DASHMODE && mo->player->dashmode >= 3*TICRATE && mo->player->panim != PA_DASH) - P_SetPlayerMobjState(mo, S_PLAY_DASH); - else if (mo->player->speed >= FixedMul(mo->player->runspeed, mo->scale) - && (mo->player->panim != PA_RUN || mo->state-states == S_PLAY_FLOAT_RUN)) - P_SetPlayerMobjState(mo, S_PLAY_RUN); - else if ((mo->momx || mo->momy) - && (mo->player->panim != PA_WALK || mo->state-states == S_PLAY_FLOAT)) - P_SetPlayerMobjState(mo, S_PLAY_WALK); - else if (!mo->momx && !mo->momy && mo->player->panim != PA_IDLE) - P_SetPlayerMobjState(mo, S_PLAY_STND); - } - } - - if (!(mo->player->pflags & PF_GLIDING)) - mo->player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE); - - mo->player->pflags &= ~(PF_STARTJUMP|PF_THOKKED|PF_CANCARRY/*|PF_GLIDING*/); - mo->player->secondjump = 0; - mo->player->glidetime = 0; - mo->player->climbing = 0; - mo->player->powers[pw_tailsfly] = 0; - - if (mo->player->pflags & PF_SHIELDABILITY) - { - mo->player->pflags &= ~PF_SHIELDABILITY; - - if ((mo->player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL) // Elemental shield's stomp attack. - { - if (mo->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER)) // play a blunt sound - S_StartSound(mo, sfx_s3k4c); - else // create a fire pattern on the ground - { - S_StartSound(mo, sfx_s3k47); - P_ElementalFire(mo->player, true); - } - P_SetObjectMomZ(mo, - (mo->eflags & MFE_UNDERWATER) - ? 6*FRACUNIT/5 - : 5*FRACUNIT/2, - false); - P_SetPlayerMobjState(mo, S_PLAY_FALL); - mo->momx = mo->momy = 0; - clipmomz = false; - } - else if ((mo->player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP) // Bubble shield's bounce attack. - { - P_DoBubbleBounce(mo->player); - clipmomz = false; - } - } - - if (mo->player->pflags & PF_BOUNCING) - { - P_MobjCheckWater(mo); - mo->momz *= -1; - P_DoAbilityBounce(mo->player, true); - if (mo->player->scoreadd) - mo->player->scoreadd--; - clipmomz = false; - } - } + clipmomz = P_PlayerHitFloor(mo->player); } - if (!(mo->player->pflags & PF_SPINNING)) + if (!(mo->player->pflags & PF_SPINNING) && mo->player->powers[pw_carry] != CR_NIGHTSMODE) mo->player->pflags &= ~PF_STARTDASH; if (clipmomz) @@ -6878,6 +6781,7 @@ void P_MobjThinker(mobj_t *mobj) whoosh->momz = mobj->target->momz; // Stay reasonably centered for a few frames mobj->target->player->pflags &= ~PF_SHIELDABILITY; // prevent eternal whoosh } + /* FALLTHRU */ case MT_FLAMEAURA_ORB: if (!(mobj->flags2 & MF2_SHIELD)) return; @@ -7365,7 +7269,7 @@ void P_MobjThinker(mobj_t *mobj) break; case MT_AQUABUZZ: P_MobjCheckWater(mobj); // solely for MFE_UNDERWATER for A_FlickySpawn - // no break here on purpose + /* FALLTHRU */ case MT_BIGAIRMINE: { if (mobj->tracer && mobj->tracer->player && mobj->tracer->health > 0 @@ -7849,7 +7753,7 @@ void P_MobjThinker(mobj_t *mobj) else mobj->z = mobj->floorz; } - // THERE IS NO BREAK HERE ON PURPOSE + /* FALLTHRU */ default: // check mobj against possible water content, before movement code P_MobjCheckWater(mobj); @@ -8415,6 +8319,9 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) #endif switch (mobj->type) { + case MT_ALTVIEWMAN: + if (titlemapinaction) mobj->flags &= ~MF_NOTHINK; + break; case MT_CYBRAKDEMON_NAPALM_BOMB_LARGE: mobj->fuse = mobj->info->mass; break; @@ -8883,6 +8790,7 @@ void P_PrecipitationEffects(void) { case PRECIP_RAIN: // no lightning or thunder whatsoever sounds_thunder = false; + /* FALLTHRU */ case PRECIP_STORM_NOSTRIKES: // no lightning strikes specifically effects_lightning = false; break; @@ -9199,6 +9107,7 @@ void P_AfterPlayerSpawn(INT32 playernum) } SV_SpawnPlayer(playernum, mobj->x, mobj->y, mobj->angle); + p->drawangle = mobj->angle; if (camera.chase) { @@ -11404,4 +11313,4 @@ mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zo newmobj->destscale = mobj->destscale; P_SetScale(newmobj, mobj->scale); return newmobj; -} \ No newline at end of file +} diff --git a/src/p_saveg.c b/src/p_saveg.c index 2d3412e65..8efe7027b 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -64,22 +64,16 @@ typedef enum static inline void P_ArchivePlayer(void) { const player_t *player = &players[consoleplayer]; - INT32 pllives = player->lives; - if (pllives < 3) // Bump up to 3 lives if the player - pllives = 3; // has less than that. - - WRITEUINT8(save_p, player->skincolor); - WRITEUINT8(save_p, player->skin); + INT16 skininfo = player->skin + (botskin<<5); + SINT8 pllives = player->lives; + if (pllives < startinglivesbalance[numgameovers]) // Bump up to 3 lives if the player + pllives = startinglivesbalance[numgameovers]; // has less than that. + WRITEUINT16(save_p, skininfo); + WRITEUINT8(save_p, numgameovers); + WRITESINT8(save_p, pllives); WRITEUINT32(save_p, player->score); - WRITEINT32(save_p, pllives); WRITEINT32(save_p, player->continues); - - if (botskin) - { - WRITEUINT8(save_p, botskin); - WRITEUINT8(save_p, botcolor); - } } // @@ -87,22 +81,14 @@ static inline void P_ArchivePlayer(void) // static inline void P_UnArchivePlayer(void) { - savedata.skincolor = READUINT8(save_p); - savedata.skin = READUINT8(save_p); + INT16 skininfo = READUINT16(save_p); + savedata.skin = skininfo & ((1<<5) - 1); + savedata.botskin = skininfo >> 5; - savedata.score = READINT32(save_p); - savedata.lives = READINT32(save_p); + savedata.numgameovers = READUINT8(save_p); + savedata.lives = READSINT8(save_p); + savedata.score = READUINT32(save_p); savedata.continues = READINT32(save_p); - - if (savedata.botcolor) - { - savedata.botskin = READUINT8(save_p); - if (savedata.botskin-1 >= numskins) - savedata.botskin = 0; - savedata.botcolor = READUINT8(save_p); - } - else - savedata.botskin = 0; } // @@ -126,6 +112,7 @@ static void P_NetArchivePlayers(void) // no longer send ticcmds, player name, skin, or color WRITEANGLE(save_p, players[i].aiming); + WRITEANGLE(save_p, players[i].drawangle); WRITEANGLE(save_p, players[i].awayviewaiming); WRITEINT32(save_p, players[i].awayviewtics); WRITEINT32(save_p, players[i].rings); @@ -305,6 +292,7 @@ static void P_NetUnArchivePlayers(void) // (that data is handled in the server config now) players[i].aiming = READANGLE(save_p); + players[i].drawangle = READANGLE(save_p); players[i].awayviewaiming = READANGLE(save_p); players[i].awayviewtics = READINT32(save_p); players[i].rings = READINT32(save_p); @@ -1682,12 +1670,18 @@ static inline void SaveWhatThinker(const thinker_t *th, const UINT8 type) static void P_NetArchiveThinkers(void) { const thinker_t *th; + UINT32 numsaved = 0; WRITEUINT32(save_p, ARCHIVEBLOCK_THINKERS); // save off the current thinkers for (th = thinkercap.next; th != &thinkercap; th = th->next) { + if (!(th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed + || th->function.acp1 == (actionf_p1)P_RainThinker + || th->function.acp1 == (actionf_p1)P_SnowThinker)) + numsaved++; + if (th->function.acp1 == (actionf_p1)P_MobjThinker) { SaveMobjThinker(th, tc_mobj); @@ -1881,6 +1875,8 @@ static void P_NetArchiveThinkers(void) #endif } + CONS_Debug(DBG_NETPLAY, "%u thinkers saved\n", numsaved); + WRITEUINT8(save_p, tc_end); } @@ -2668,6 +2664,7 @@ static void P_NetUnArchiveThinkers(void) UINT8 tclass; UINT8 restoreNum = false; UINT32 i; + UINT32 numloaded = 0; if (READUINT32(save_p) != ARCHIVEBLOCK_THINKERS) I_Error("Bad $$$.sav at archive block Thinkers"); @@ -2701,6 +2698,7 @@ static void P_NetUnArchiveThinkers(void) if (tclass == tc_end) break; // leave the saved thinker reading loop + numloaded++; switch (tclass) { @@ -2856,6 +2854,8 @@ static void P_NetUnArchiveThinkers(void) } } + CONS_Debug(DBG_NETPLAY, "%u thinkers loaded\n", numloaded); + if (restoreNum) { executor_t *delay = NULL; @@ -3162,7 +3162,7 @@ static inline void P_ArchiveMisc(void) //lastmapsaved = gamemap; lastmaploaded = gamemap; - WRITEUINT16(save_p, (botskin ? (emeralds|(1<<10)) : emeralds)+357); + WRITEUINT16(save_p, emeralds+357); WRITESTRINGN(save_p, timeattackfolder, sizeof(timeattackfolder)); } @@ -3192,9 +3192,6 @@ static inline void P_UnArchiveSPGame(INT16 mapoverride) token = 0; savedata.emeralds = READUINT16(save_p)-357; - if (savedata.emeralds & (1<<10)) - savedata.botcolor = 0xFF; - savedata.emeralds &= 0xff; READSTRINGN(save_p, testname, sizeof(testname)); diff --git a/src/p_saveg.h b/src/p_saveg.h index 3670d3503..5960660ab 100644 --- a/src/p_saveg.h +++ b/src/p_saveg.h @@ -30,14 +30,13 @@ mobj_t *P_FindNewPosition(UINT32 oldposition); typedef struct { - UINT8 skincolor; UINT8 skin; UINT8 botskin; - UINT8 botcolor; INT32 score; INT32 lives; INT32 continues; UINT16 emeralds; + UINT8 numgameovers; } savedata_t; extern savedata_t savedata; diff --git a/src/p_setup.c b/src/p_setup.c index fb9842399..753c4f6e0 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2285,7 +2285,7 @@ static void P_LevelInitStuff(void) players[i].xtralife = players[i].deadtimer = players[i].numboxes = players[i].totalring = players[i].laps = 0; players[i].rings = 0; players[i].aiming = 0; - players[i].pflags &= ~PF_TIMEOVER; + players[i].pflags &= ~PF_GAMETYPEOVER; players[i].losstime = 0; players[i].timeshit = 0; @@ -2710,7 +2710,9 @@ boolean P_SetupLevel(boolean skipprecip) // As oddly named as this is, this handles music only. // We should be fine starting it here. - S_Start(); + /// ... as long as this isn't a titlemap transition, that is + if (!titlemapinaction) + S_Start(); // Let's fade to black here // But only if we didn't do the special stage wipe @@ -2724,7 +2726,7 @@ boolean P_SetupLevel(boolean skipprecip) } // Print "SPEEDING OFF TO [ZONE] [ACT 1]..." - if (rendermode != render_none) + if (!titlemapinaction && rendermode != render_none) { // Don't include these in the fade! char tx[64]; @@ -3110,19 +3112,19 @@ boolean P_SetupLevel(boolean skipprecip) P_RunCachedActions(); if (!(netgame || multiplayer || demoplayback || demorecording || metalrecording || modeattacking || players[consoleplayer].lives <= 0) - && (!modifiedgame || savemoddata) && cursaveslot >= 0 && CanSaveLevel(gamemap)) + && (!modifiedgame || savemoddata) && cursaveslot > 0 && CanSaveLevel(gamemap)) G_SaveGame((UINT32)cursaveslot); lastmaploaded = gamemap; // HAS to be set after saving!! if (savedata.lives > 0) { + numgameovers = savedata.numgameovers; players[consoleplayer].continues = savedata.continues; players[consoleplayer].lives = savedata.lives; players[consoleplayer].score = savedata.score; - botskin = savedata.botskin; - botcolor = savedata.botcolor; - botingame = (savedata.botskin != 0); + if ((botingame = ((botskin = savedata.botskin) != 0))) + botcolor = skins[botskin-1].prefcolor; emeralds = savedata.emeralds; savedata.lives = 0; } @@ -3404,8 +3406,8 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname) ST_Start(); // Prevent savefile cheating - if (cursaveslot >= 0) - cursaveslot = -1; + if (cursaveslot > 0) + cursaveslot = 0; if (replacedcurrentmap && gamestate == GS_LEVEL && (netgame || multiplayer)) { diff --git a/src/p_spec.c b/src/p_spec.c index 8f01fbfe4..97990eb26 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3663,31 +3663,14 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers S_StartSound(player->mo, sfx_itemup); } break; - case 11: // Special Stage Damage - Kind of like a mini-P_DamageMobj() - if (player->powers[pw_invulnerability] || player->powers[pw_flashing] || player->powers[pw_super] || player->exiting || player->bot) + case 11: // Special Stage Damage + if (player->exiting || player->bot) // Don't do anything for bots or players who have just finished break; if (!(player->powers[pw_shield] || player->rings > 0)) // Don't do anything if no shield or rings anyway break; - if (player->powers[pw_shield]) - { - P_RemoveShield(player); - S_StartSound(player->mo, sfx_shldls); // Ba-Dum! Shield loss. - } - else if (player->rings > 0) - { - P_PlayRinglossSound(player->mo); - if (player->rings >= 10) - player->rings -= 10; - else - player->rings = 0; - } - - P_DoPlayerPain(player, NULL, NULL); // this does basically everything that was here before - - if (gametype == GT_CTF && player->gotflag & (GF_REDFLAG|GF_BLUEFLAG)) - P_PlayerFlagBurst(player, false); + P_SpecialStageDamage(player, NULL, NULL); break; case 12: // Space Countdown if (!(player->powers[pw_shield] & SH_PROTECTWATER) && !player->powers[pw_spacetime]) @@ -3763,6 +3746,7 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers goto DoneSection2; } } + /* FALLTHRU */ case 4: // Linedef executor that doesn't require touching floor case 5: // Linedef executor case 6: // Linedef executor (7 Emeralds) @@ -4123,7 +4107,7 @@ DoneSection2: player->powers[pw_carry] = CR_ZOOMTUBE; player->speed = speed; player->pflags |= PF_SPINNING; - player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE|PF_GLIDING|PF_SLIDING|PF_CANCARRY); + player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE|PF_GLIDING|PF_BOUNCING|PF_SLIDING|PF_CANCARRY); player->climbing = 0; if (player->mo->state-states != S_PLAY_ROLL) @@ -4203,7 +4187,7 @@ DoneSection2: player->powers[pw_carry] = CR_ZOOMTUBE; player->speed = speed; player->pflags |= PF_SPINNING; - player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE|PF_GLIDING|PF_SLIDING|PF_CANCARRY); + player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE|PF_GLIDING|PF_BOUNCING|PF_SLIDING|PF_CANCARRY); player->climbing = 0; if (player->mo->state-states != S_PLAY_ROLL) @@ -4511,7 +4495,7 @@ DoneSection2: S_StartSound(player->mo, sfx_s3k4a); - player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE|PF_GLIDING|PF_SLIDING|PF_CANCARRY); + player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE|PF_GLIDING|PF_BOUNCING|PF_SLIDING|PF_CANCARRY); player->climbing = 0; P_SetThingPosition(player->mo); P_SetPlayerMobjState(player->mo, S_PLAY_RIDE); @@ -4805,6 +4789,8 @@ static void P_RunSpecialSectorCheck(player_t *player, sector_t *sector) // requires touching floor. break; } + /* FALLTHRU */ + case 1: // Starpost activator case 5: // Fan sector case 6: // Super Sonic Transform @@ -5961,6 +5947,8 @@ void P_SpawnSpecials(INT32 fromnetsave) EV_DoFloor(&lines[i], bounceFloor); if (lines[i].special == 54) break; + /* FALLTHRU */ + case 55: // New super cool and awesome moving ceiling type if (lines[i].backsector) EV_DoCeiling(&lines[i], bounceCeiling); @@ -5972,7 +5960,8 @@ void P_SpawnSpecials(INT32 fromnetsave) EV_DoFloor(&lines[i], bounceFloorCrush); if (lines[i].special == 57) - break; //only move the floor + break; //only move the floor + /* FALLTHRU */ case 58: // New super cool and awesome moving ceiling crush type if (lines[i].backsector) @@ -7060,6 +7049,7 @@ static void P_SpawnScrollers(void) Add_Scroller(sc_ceiling, -dx, dy, control, s, accel, l->flags & ML_NOCLIMB); if (special != 533) break; + /* FALLTHRU */ case 523: // carry objects on ceiling dx = FixedMul(dx, CARRYFACTOR); @@ -7074,6 +7064,7 @@ static void P_SpawnScrollers(void) Add_Scroller(sc_floor, -dx, dy, control, s, accel, l->flags & ML_NOCLIMB); if (special != 530) break; + /* FALLTHRU */ case 520: // carry objects on floor dx = FixedMul(dx, CARRYFACTOR); diff --git a/src/p_tick.c b/src/p_tick.c index a79d71ef4..658b1e4ea 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -533,7 +533,7 @@ static inline void P_DoTagStuff(void) for (i=0; i < MAXPLAYERS; i++) { if (playeringame[i] && !players[i].spectator && players[i].playerstate == PST_LIVE - && !(players[i].pflags & (PF_TAGIT|PF_TAGGED))) + && !(players[i].pflags & (PF_TAGIT|PF_GAMETYPEOVER))) //points given is the number of participating players divided by two. P_AddPlayerScore(&players[i], participants/2); } diff --git a/src/p_user.c b/src/p_user.c index 09cafa0b3..cfe9b334b 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -165,7 +165,7 @@ fixed_t P_ReturnThrustY(mobj_t *mo, angle_t angle, fixed_t move) boolean P_AutoPause(void) { // Don't pause even on menu-up or focus-lost in netgames or record attack - if (netgame || modeattacking) + if (netgame || modeattacking || gamestate == GS_TITLESCREEN) return false; return (menuactive || window_notinfocus); @@ -576,7 +576,7 @@ static void P_DeNightserizePlayer(player_t *player) thinker_t *th; mobj_t *mo2; - player->powers[pw_carry] = CR_NONE; + player->powers[pw_carry] = CR_NIGHTSFALL; player->powers[pw_underwater] = 0; player->pflags &= ~(PF_USEDOWN|PF_JUMPDOWN|PF_ATTACKDOWN|PF_STARTDASH|PF_GLIDING|PF_STARTJUMP|PF_JUMPED|PF_NOJUMPDAMAGE|PF_THOKKED|PF_SPINNING|PF_DRILLING|PF_TRANSFERTOCLOSEST); @@ -603,7 +603,6 @@ static void P_DeNightserizePlayer(player_t *player) player->marescore = 0; P_SetPlayerMobjState(player->mo, S_PLAY_FALL); - player->pflags |= PF_NIGHTSFALL; // If in a special stage, add some preliminary exit time. if (G_IsSpecialStage(gamemap)) @@ -857,12 +856,13 @@ void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor) fallbackspeed = FixedMul(4*FRACUNIT, player->mo->scale); } + player->drawangle = ang + ANGLE_180; P_InstaThrust(player->mo, ang, fallbackspeed); } // Point penalty for hitting a hazard during tag. // Discourages players from intentionally hurting themselves to avoid being tagged. - if (gametype == GT_TAG && (!(player->pflags & PF_TAGGED) && !(player->pflags & PF_TAGIT))) + if (gametype == GT_TAG && (!(player->pflags & PF_GAMETYPEOVER) && !(player->pflags & PF_TAGIT))) { if (player->score >= 50) player->score -= 50; @@ -884,7 +884,7 @@ void P_ResetPlayer(player_t *player) { player->pflags &= ~(PF_SPINNING|PF_STARTDASH|PF_STARTJUMP|PF_JUMPED|PF_NOJUMPDAMAGE|PF_GLIDING|PF_THOKKED|PF_CANCARRY|PF_SHIELDABILITY|PF_BOUNCING); - if (!(player->powers[pw_carry] == CR_NIGHTSMODE || player->powers[pw_carry] == CR_BRAKGOOP)) + if (!(player->powers[pw_carry] == CR_NIGHTSMODE || player->powers[pw_carry] == CR_NIGHTSFALL || player->powers[pw_carry] == CR_BRAKGOOP)) player->powers[pw_carry] = CR_NONE; player->secondjump = 0; @@ -950,6 +950,8 @@ void P_GivePlayerRings(player_t *player, INT32 num_rings) // void P_GivePlayerLives(player_t *player, INT32 numlives) { + if (player->lives == 0x7f) return; + player->lives += numlives; if (player->lives > 99) @@ -1153,7 +1155,9 @@ void P_PlayLivesJingle(player_t *player) if (player && !P_IsLocalPlayer(player)) return; - if (gametype == GT_COOP && (netgame || multiplayer) && cv_cooplives.value == 0) + if ((player && player->lives == 0x7f) + || (!player && &players[consoleplayer] && players[consoleplayer].lives == 0x7f) + || (gametype == GT_COOP && (netgame || multiplayer) && cv_cooplives.value == 0)) S_StartSound(NULL, sfx_lose); else if (use1upSound) S_StartSound(NULL, sfx_oneup); @@ -1562,7 +1566,7 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj) ghost->color = mobj->color; - ghost->angle = mobj->angle; + ghost->angle = (mobj->player ? mobj->player->drawangle : mobj->angle); ghost->sprite = mobj->sprite; ghost->sprite2 = mobj->sprite2; ghost->frame = mobj->frame; @@ -1612,7 +1616,7 @@ void P_SpawnThokMobj(player_t *player) mobj = P_SpawnMobj(player->mo->x, player->mo->y, zheight, type); // set to player's angle, just in case - mobj->angle = player->mo->angle; + mobj->angle = player->drawangle; // color and skin mobj->color = player->mo->color; @@ -1672,7 +1676,7 @@ void P_SpawnSpinMobj(player_t *player, mobjtype_t type) mobj = P_SpawnMobj(player->mo->x, player->mo->y, zheight, type); // set to player's angle, just in case - mobj->angle = player->mo->angle; + mobj->angle = player->drawangle; // color and skin mobj->color = player->mo->color; @@ -1777,6 +1781,122 @@ boolean P_InSpaceSector(mobj_t *mo) // Returns true if you are in space return false; // No vacuum here, Captain! } +// +// P_PlayerHitFloor +// +// Handles player hitting floor surface. +// Returns whether to clip momz. +boolean P_PlayerHitFloor(player_t *player) +{ + boolean clipmomz; + + I_Assert(player->mo != NULL); + + if ((clipmomz = !(P_CheckDeathPitCollide(player->mo))) && player->mo->health && !player->spectator) + { + if ((player->charability2 == CA2_SPINDASH) && !(player->pflags & PF_THOKKED) && (player->cmd.buttons & BT_USE) && (FixedHypot(player->mo->momx, player->mo->momy) > (5*player->mo->scale))) + { + player->pflags |= PF_SPINNING; + P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); + S_StartSound(player->mo, sfx_spin); + } + else + player->pflags &= ~PF_SPINNING; + + if (player->pflags & PF_GLIDING) // ground gliding + { + player->skidtime = TICRATE; + player->mo->tics = -1; + } + else if (player->charability2 == CA2_MELEE && (player->panim == PA_ABILITY2 && player->mo->state-states != S_PLAY_MELEE_LANDING)) + { + P_SetPlayerMobjState(player->mo, S_PLAY_MELEE_LANDING); + player->mo->tics = (player->mo->movefactor == FRACUNIT) ? TICRATE/2 : (FixedDiv(35<<(FRACBITS-1), FixedSqrt(player->mo->movefactor)))>>FRACBITS; + S_StartSound(player->mo, sfx_s3k8b); + player->pflags |= PF_FULLSTASIS; + } + else if (player->pflags & PF_JUMPED || !(player->pflags & PF_SPINNING) + || player->powers[pw_tailsfly] || player->mo->state-states == S_PLAY_FLY_TIRED) + { + if (player->cmomx || player->cmomy) + { + if (player->charflags & SF_DASHMODE && player->dashmode >= 3*TICRATE && player->panim != PA_DASH) + P_SetPlayerMobjState(player->mo, S_PLAY_DASH); + else if (player->speed >= FixedMul(player->runspeed, player->mo->scale) + && (player->panim != PA_RUN || player->mo->state-states == S_PLAY_FLOAT_RUN)) + P_SetPlayerMobjState(player->mo, S_PLAY_RUN); + else if ((player->rmomx || player->rmomy) + && (player->panim != PA_WALK || player->mo->state-states == S_PLAY_FLOAT)) + P_SetPlayerMobjState(player->mo, S_PLAY_WALK); + else if (!player->rmomx && !player->rmomy && player->panim != PA_IDLE) + P_SetPlayerMobjState(player->mo, S_PLAY_STND); + } + else + { + if (player->charflags & SF_DASHMODE && player->dashmode >= 3*TICRATE && player->panim != PA_DASH) + P_SetPlayerMobjState(player->mo, S_PLAY_DASH); + else if (player->speed >= FixedMul(player->runspeed, player->mo->scale) + && (player->panim != PA_RUN || player->mo->state-states == S_PLAY_FLOAT_RUN)) + P_SetPlayerMobjState(player->mo, S_PLAY_RUN); + else if ((player->mo->momx || player->mo->momy) + && (player->panim != PA_WALK || player->mo->state-states == S_PLAY_FLOAT)) + P_SetPlayerMobjState(player->mo, S_PLAY_WALK); + else if (!player->mo->momx && !player->mo->momy && player->panim != PA_IDLE) + P_SetPlayerMobjState(player->mo, S_PLAY_STND); + } + } + + if (!(player->pflags & PF_GLIDING)) + player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE); + player->pflags &= ~(PF_STARTJUMP|PF_THOKKED|PF_CANCARRY/*|PF_GLIDING*/); + player->secondjump = 0; + player->glidetime = 0; + player->climbing = 0; + player->powers[pw_tailsfly] = 0; + + if (player->pflags & PF_SHIELDABILITY) + { + player->pflags &= ~PF_SHIELDABILITY; + + if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL) // Elemental shield's stomp attack. + { + if (player->mo->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER)) // play a blunt sound + S_StartSound(player->mo, sfx_s3k4c); + else // create a fire pattern on the ground + { + S_StartSound(player->mo, sfx_s3k47); + P_ElementalFire(player, true); + } + P_SetObjectMomZ(player->mo, + (player->mo->eflags & MFE_UNDERWATER) + ? 6*FRACUNIT/5 + : 5*FRACUNIT/2, + false); + P_SetPlayerMobjState(player->mo, S_PLAY_FALL); + player->mo->momx = player->mo->momy = 0; + clipmomz = false; + } + else if ((player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP) // Bubble shield's bounce attack. + { + P_DoBubbleBounce(player); + clipmomz = false; + } + } + + if (player->pflags & PF_BOUNCING) + { + P_MobjCheckWater(player->mo); + player->mo->momz *= -1; + P_DoAbilityBounce(player, true); + if (player->scoreadd) + player->scoreadd--; + clipmomz = false; + } + } + + return clipmomz; +} + boolean P_InQuicksand(mobj_t *mo) // Returns true if you are in quicksand { sector_t *sector = mo->subsector->sector; @@ -2152,6 +2272,9 @@ static void P_CheckQuicksand(player_t *player) if (player->mo->z + player->mo->height >= ceilingheight) player->mo->z = ceilingheight - player->mo->height; + + if (player->mo->momz <= 0) + P_PlayerHitFloor(player); } else { @@ -2161,6 +2284,9 @@ static void P_CheckQuicksand(player_t *player) if (player->mo->z <= floorheight) player->mo->z = floorheight; + + if (player->mo->momz >= 0) + P_PlayerHitFloor(player); } friction = abs(rover->master->v1->y - rover->master->v2->y)>>6; @@ -3667,7 +3793,7 @@ void P_DoJump(player_t *player, boolean soundandstate) else player->mo->momz = 15*(FRACUNIT/4); - player->mo->angle = player->mo->angle - ANGLE_180; // Turn around from the wall you were climbing. + player->drawangle = player->mo->angle = player->mo->angle - ANGLE_180; // Turn around from the wall you were climbing. if (!demoplayback || P_AnalogMove(player)) { @@ -3825,7 +3951,7 @@ static void P_DoSpinDashDust(player_t *player) prandom[2] = P_RandomFixed()<<3; // P_RandomByte()<<11 P_SetObjectMomZ(particle, player->dashspeed/50 + prandom[0], false); P_InstaThrust(particle, - player->mo->angle + (prandom[1]*ANG1), + player->drawangle + (prandom[1]*ANG1), -FixedMul(player->dashspeed/12 + FRACUNIT + prandom[2], player->mo->scale)); P_TryMove(particle, particle->x+particle->momx, particle->y+particle->momy, true); } @@ -3980,6 +4106,7 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) bullet->momy >>= 1; } } + player->drawangle = player->mo->angle; #undef zpos P_SetTarget(&player->mo->tracer, NULL); @@ -4015,7 +4142,10 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) if (player->mo->eflags & MFE_UNDERWATER) player->mo->momz >>= 1; if (FixedMul(player->speed, FINECOSINE(((player->mo->angle - R_PointToAngle2(0, 0, player->rmomx, player->rmomy)) >> ANGLETOFINESHIFT) & FINEMASK)) < FixedMul(player->maxdash, player->mo->scale)) + { + player->drawangle = player->mo->angle; P_InstaThrust(player->mo, player->mo->angle, FixedMul(player->maxdash, player->mo->scale)); + } player->mo->momx += player->cmomx; player->mo->momy += player->cmomy; P_SetPlayerMobjState(player->mo, S_PLAY_MELEE); @@ -4280,6 +4410,8 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) P_InstaThrust(player->mo, player->mo->angle, FixedMul(player->normalspeed, player->mo->scale)*(80-player->flyangle - (player->actionspd>>FRACBITS)/2)/80); else P_InstaThrust(player->mo, player->mo->angle, ((FixedMul(player->normalspeed - player->actionspd/4, player->mo->scale))*2)/3); + + player->drawangle = player->mo->angle; } } } @@ -4353,6 +4485,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) } P_InstaThrust(player->mo, player->mo->angle, FixedMul(actionspd, player->mo->scale)); + player->drawangle = player->mo->angle; if (maptol & TOL_2D) { @@ -4370,6 +4503,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) P_SetTarget(&player->mo->target, P_SetTarget(&player->mo->tracer, lockon)); if (lockon) { + P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); player->mo->angle = R_PointToAngle2(player->mo->x, player->mo->y, lockon->x, lockon->y); player->homing = 3*TICRATE; } @@ -6274,7 +6408,7 @@ static void P_NiGHTSMovement(player_t *player) && ((cmd->buttons & (BT_CAMLEFT|BT_CAMRIGHT)) == (BT_CAMLEFT|BT_CAMRIGHT) || (cmd->buttons & BT_USE))) { - if (!(player->pflags & PF_SKIDDOWN)) + if (!(player->pflags & PF_STARTDASH)) S_StartSound(player->mo, sfx_ngskid); // You can tap the button to only slow down a bit, @@ -6292,10 +6426,10 @@ static void P_NiGHTSMovement(player_t *player) } } - player->pflags |= PF_SKIDDOWN; + player->pflags |= PF_STARTDASH; } else - player->pflags &= ~PF_SKIDDOWN; + player->pflags &= ~PF_STARTDASH; { const angle_t fa = (FixedAngle(player->flyangle*FRACUNIT)>>ANGLETOFINESHIFT) & FINEMASK; @@ -6674,8 +6808,8 @@ static void P_SkidStuff(player_t *player) // If your push angle is more than this close to a full 180 degrees, trigger a skid. if (dang > ANGLE_157h) { - if (player->panim != PA_WALK) - P_SetPlayerMobjState(player->mo, S_PLAY_WALK); + if (player->mo->state-states != S_PLAY_SKID) + P_SetPlayerMobjState(player->mo, S_PLAY_SKID); player->mo->tics = player->skidtime = (player->mo->movefactor == FRACUNIT) ? TICRATE/2 : (FixedDiv(35<<(FRACBITS-1), FixedSqrt(player->mo->movefactor)))>>FRACBITS; S_StartSound(player->mo, sfx_skid); } @@ -6741,7 +6875,7 @@ static void P_MovePlayer(player_t *player) if (!(player->pflags & PF_TAGIT)) { forcestasis = true; - if (player->pflags & PF_TAGGED) // Already hit. + if (player->pflags & PF_GAMETYPEOVER) // Already hit. player->powers[pw_flashing] = 5; } } @@ -6811,8 +6945,7 @@ static void P_MovePlayer(player_t *player) P_CheckQuicksand(player); return; } - - if (player->pflags & PF_NIGHTSFALL && P_IsObjectOnGround(player->mo)) + else if (player->powers[pw_carry] == CR_NIGHTSFALL && P_IsObjectOnGround(player->mo)) { if (G_IsSpecialStage(gamemap)) { @@ -6824,7 +6957,7 @@ static void P_MovePlayer(player_t *player) } else if (player->rings > 0) P_DamageMobj(player->mo, NULL, NULL, 1, 0); - player->pflags &= ~PF_NIGHTSFALL; + player->powers[pw_carry] = CR_NONE; } } @@ -6917,8 +7050,6 @@ static void P_MovePlayer(player_t *player) if (!player->mo->momx && !player->mo->momy && !player->mo->momz && player->panim == PA_WALK) P_SetPlayerMobjState(player->mo, S_PLAY_STND); - player->mo->movefactor = FRACUNIT; // We're not going to do any more with this, so let's change it back for the next frame. - ////////////////// //GAMEPLAY STUFF// ////////////////// @@ -7186,7 +7317,7 @@ static void P_MovePlayer(player_t *player) //////////////////////////// // If the player isn't on the ground, make sure they aren't in a "starting dash" position. - if (!onground) + if (!onground && player->powers[pw_carry] != CR_NIGHTSMODE) { player->pflags &= ~PF_STARTDASH; player->dashspeed = 0; @@ -7203,7 +7334,7 @@ static void P_MovePlayer(player_t *player) P_DoJumpStuff(player, cmd); // If you're not spinning, you'd better not be spindashing! - if (!(player->pflags & PF_SPINNING)) + if (!(player->pflags & PF_SPINNING) && player->powers[pw_carry] != CR_NIGHTSMODE) player->pflags &= ~PF_STARTDASH; ////////////////// @@ -7365,6 +7496,7 @@ static void P_MovePlayer(player_t *player) case SH_FLAMEAURA: player->pflags |= PF_THOKKED|PF_SHIELDABILITY; P_Thrust(player->mo, player->mo->angle, FixedMul(30*FRACUNIT - FixedSqrt(FixedDiv(player->speed, player->mo->scale)), player->mo->scale)); + player->drawangle = player->mo->angle; S_StartSound(player->mo, sfx_s3k43); default: break; @@ -7418,6 +7550,8 @@ static void P_MovePlayer(player_t *player) if (!(player->mo->tracer->flags & MF_BOSS)) player->pflags &= ~PF_THOKKED; + + // P_SetPlayerMobjState(player->mo, S_PLAY_SPRING); -- Speed didn't like it, RIP } } @@ -8084,12 +8218,16 @@ void P_HomingAttack(mobj_t *source, mobj_t *enemy) // Home in on your target // change angle source->angle = R_PointToAngle2(source->x, source->y, enemy->x, enemy->y); - if (source->player && (!demoplayback || P_AnalogMove(source->player))) + if (source->player) { - if (source->player == &players[consoleplayer]) - localangle = source->angle; - else if (source->player == &players[secondarydisplayplayer]) - localangle2 = source->angle; + source->player->drawangle = source->angle; + if (!demoplayback || P_AnalogMove(source->player)) + { + if (source->player == &players[consoleplayer]) + localangle = source->angle; + else if (source->player == &players[secondarydisplayplayer]) + localangle2 = source->angle; + } } // change slope @@ -8160,7 +8298,8 @@ boolean P_GetLives(player_t *player) INT32 i, maxlivesplayer = -1, livescheck = 1; if (!(netgame || multiplayer) || (gametype != GT_COOP) - || (cv_cooplives.value == 1)) + || (cv_cooplives.value == 1) + || (player->lives == 0x7f)) return true; if ((cv_cooplives.value == 2 || cv_cooplives.value == 0) && player->lives > 0) @@ -8187,7 +8326,8 @@ boolean P_GetLives(player_t *player) { if (cv_cooplives.value == 2 && (P_IsLocalPlayer(player) || P_IsLocalPlayer(&players[maxlivesplayer]))) S_StartSound(NULL, sfx_jshard); // placeholder - players[maxlivesplayer].lives--; + if (players[maxlivesplayer].lives != 0x7f) + players[maxlivesplayer].lives--; player->lives++; if (player->lives < 1) player->lives = 1; @@ -8379,7 +8519,7 @@ static void P_DeathThink(player_t *player) if (gametype == GT_RACE || gametype == GT_COMPETITION || (gametype == GT_COOP && (multiplayer || netgame))) { // Keep time rolling in race mode - if (!(countdown2 && !countdown) && !player->exiting && !(player->pflags & PF_TIMEOVER)) + if (!(countdown2 && !countdown) && !player->exiting && !(player->pflags & PF_GAMETYPEOVER)) { if (gametype == GT_RACE || gametype == GT_COMPETITION) { @@ -8679,7 +8819,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall // x1.2 dist for analog if (P_AnalogMove(player)) dist = FixedMul(dist, 6*FRACUNIT/5); - + if (player->climbing || player->exiting || player->playerstate == PST_DEAD || (player->powers[pw_carry] == CR_ROPEHANG || player->powers[pw_carry] == CR_GENERIC || player->powers[pw_carry] == CR_MACESPIN)) dist <<= 1; } @@ -9404,7 +9544,7 @@ void P_PlayerThink(player_t *player) if (netgame && player->mo->health > 0) CONS_Printf(M_GetText("%s ran out of time.\n"), player_names[player-players]); - player->pflags |= PF_TIMEOVER; + player->pflags |= PF_GAMETYPEOVER; if (player->powers[pw_carry] == CR_NIGHTSMODE) { @@ -9603,6 +9743,136 @@ void P_PlayerThink(player_t *player) if (!player->mo) return; // P_MovePlayer removed player->mo. + // deez New User eXperiences. + { + // Directionchar! + // Camera angle stuff. + if (player->exiting) // no control, no modification + ; + else if (!(player->pflags & PF_DIRECTIONCHAR) + || (player->climbing // stuff where the direction is forced at all times + || (player->pflags & PF_GLIDING)) + || (player->powers[pw_carry] == CR_NIGHTSMODE) + || (P_AnalogMove(player) || twodlevel || player->mo->flags2 & MF2_TWOD) // keep things synchronised up there, since the camera IS seperate from player motion when that happens + || G_RingSlingerGametype()) // no firing rings in directions your player isn't aiming + player->drawangle = player->mo->angle; + else if (P_PlayerInPain(player)) + ; + else if (player->powers[pw_carry] && player->mo->tracer) // carry + { + switch (player->powers[pw_carry]) + { + case CR_PLAYER: + player->drawangle = (player->mo->tracer->player ? player->mo->tracer->player->drawangle : player->mo->tracer->angle); + break; + /* -- in case we wanted to have the camera freely movable during zoom tubes + case CR_ZOOMTUBE:*/ + case CR_ROPEHANG: + if (player->mo->momx || player->mo->momy) + { + player->drawangle = R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy); + break; + } + /* FALLTHRU */ + default: + player->drawangle = player->mo->angle; + break; + } + } + else if ((player->skidtime > (TICRATE/2 - 2) || ((player->pflags & (PF_SPINNING|PF_STARTDASH)) == PF_SPINNING)) && (abs(player->rmomx) > 5*player->mo->scale || abs(player->rmomy) > 5*player->mo->scale)) // spin/skid force + player->drawangle = R_PointToAngle2(0, 0, player->rmomx, player->rmomy); + else if (((player->charability2 == CA2_GUNSLINGER || player->charability2 == CA2_MELEE) && player->panim == PA_ABILITY2) || player->pflags & PF_STASIS || player->skidtime) + ; + else + { + angle_t diff; + UINT8 factor; + + if (player->pflags & PF_SLIDING) + { +#if 0 // fun hydrocity style horizontal spin + if (player->mo->eflags & MFE_TOUCHWATER || player->powers[pw_flashing] > (flashingtics/4)*3) + { + diff = (player->mo->angle - player->drawangle); + factor = 4; + } + else + { + diff = factor = 0; + player->drawangle += ANGLE_22h; + } +#else + diff = (player->mo->angle - player->drawangle); + factor = 4; +#endif + } + else if (player->pflags & PF_STARTDASH) + { + diff = (player->mo->angle - player->drawangle); + factor = 4; + } + else if (cmd->forwardmove || cmd->sidemove) // only when you're pressing movement keys + { + diff = ((player->mo->angle + R_PointToAngle2(0, 0, cmd->forwardmove<sidemove<drawangle); + factor = 4; + } + else if (player->rmomx || player->rmomy) + diff = factor = 0; + else + { + diff = (player->mo->angle - player->drawangle); + factor = 8; + } + + if (diff) + { + if (diff > ANGLE_180) + diff = InvAngle(InvAngle(diff)/factor); + else + diff /= factor; + player->drawangle += diff; + } + } + + // Autobrake! + { + boolean currentlyonground = P_IsObjectOnGround(player->mo); + + if (!player->powers[pw_carry] + && ((player->pflags & (PF_AUTOBRAKE|PF_APPLYAUTOBRAKE)) == (PF_AUTOBRAKE|PF_APPLYAUTOBRAKE)) + && !(cmd->forwardmove || cmd->sidemove) + && (player->rmomx || player->rmomy)) + { + fixed_t acceleration = (player->accelstart + (FixedDiv(player->speed, player->mo->scale)>>FRACBITS) * player->acceleration) * player->thrustfactor * 20; + angle_t moveAngle = R_PointToAngle2(0, 0, player->rmomx, player->rmomy); + + if (!currentlyonground) + acceleration /= 2; + + if (player->mo->movefactor != FRACUNIT) // Friction-scaled acceleration... + acceleration = FixedMul(acceleration<mo->movefactor)>>FRACBITS; + + P_Thrust(player->mo, moveAngle, -acceleration); + } + + if (!(player->pflags & PF_AUTOBRAKE) + || player->powers[pw_carry] + || player->panim == PA_SPRING + || player->panim == PA_PAIN + || !player->mo->health + || player->climbing + || player->pflags & (PF_SPINNING|PF_SLIDING)) + player->pflags &= ~PF_APPLYAUTOBRAKE; + else if (currentlyonground) + player->pflags |= PF_APPLYAUTOBRAKE; + } + } + + if (player->powers[pw_pushing]) + player->powers[pw_pushing]--; + + player->mo->movefactor = FRACUNIT; // We're not going to do any more with this, so let's change it back for the next frame. + // Unset statis flags after moving. // In other words, if you manually set stasis via code, // it lasts for one tic. diff --git a/src/r_main.c b/src/r_main.c index c998a7d93..cabefed14 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -914,7 +914,7 @@ void R_SetupFrame(player_t *player, boolean skybox) chasecam = (cv_chasecam.value != 0); } - if (player->climbing || (player->powers[pw_carry] == CR_NIGHTSMODE) || player->playerstate == PST_DEAD) + if (player->climbing || (player->powers[pw_carry] == CR_NIGHTSMODE) || player->playerstate == PST_DEAD || gamestate == GS_TITLESCREEN) chasecam = true; // force chasecam on else if (player->spectator) // no spectator chasecam chasecam = false; // force chasecam off diff --git a/src/r_sky.c b/src/r_sky.c index 5162518cb..898424a99 100644 --- a/src/r_sky.c +++ b/src/r_sky.c @@ -64,10 +64,6 @@ void R_SetupSkyDraw(void) // the horizon line in a 256x128 sky texture skytexturemid = (textures[skytexture]->height/2)<rotate != SRF_SINGLE || papersprite) { - ang = R_PointToAngle (thing->x, thing->y) - thing->angle; + ang = R_PointToAngle (thing->x, thing->y) - (thing->player ? thing->player->drawangle : thing->angle); if (papersprite) ang_scale = abs(FINESINE(ang>>ANGLETOFINESHIFT)); } @@ -2440,176 +2440,39 @@ CV_PossibleValue_t skin_cons_t[MAXSKINS+1]; UINT8 P_GetSkinSprite2(skin_t *skin, UINT8 spr2, player_t *player) { - UINT8 super = (spr2 & FF_SPR2SUPER); + UINT8 super = 0, i = 0; if (!skin) return 0; while (!(skin->sprites[spr2].numframes) - && spr2 != SPR2_STND) + && spr2 != SPR2_STND + && ++i != 32) // recursion limiter { if (spr2 & FF_SPR2SUPER) { + super = FF_SPR2SUPER; spr2 &= ~FF_SPR2SUPER; continue; } switch(spr2) { - case SPR2_RUN: - spr2 = SPR2_WALK; - break; - case SPR2_STUN: - spr2 = SPR2_PAIN; - break; - case SPR2_DRWN: - spr2 = SPR2_DEAD; - break; - case SPR2_SPIN: - spr2 = SPR2_ROLL; - break; - case SPR2_GASP: - spr2 = SPR2_SPNG; - break; + + // Normal special cases. case SPR2_JUMP: spr2 = ((player ? player->charflags : skin->flags) & SF_NOJUMPSPIN) ? SPR2_SPNG : SPR2_ROLL; break; - case SPR2_SPNG: // spring - spr2 = SPR2_FALL; - break; - case SPR2_FALL: - spr2 = SPR2_WALK; - break; - case SPR2_RIDE: - spr2 = SPR2_FALL; - break; - - case SPR2_FLY : - spr2 = SPR2_SPNG; - break; - case SPR2_SWIM: - spr2 = SPR2_FLY ; - break; case SPR2_TIRE: spr2 = (player && player->charability == CA_SWIM) ? SPR2_SWIM : SPR2_FLY; break; - case SPR2_GLID: - spr2 = SPR2_FLY; - break; - case SPR2_CLMB: - spr2 = SPR2_ROLL; - break; - case SPR2_CLNG: - spr2 = SPR2_CLMB; - break; - - case SPR2_FLT : - spr2 = SPR2_WALK; - break; - case SPR2_FRUN: - spr2 = SPR2_RUN ; - break; - - case SPR2_DASH: - spr2 = SPR2_FRUN; - break; - - case SPR2_BNCE: - spr2 = SPR2_FALL; - break; - case SPR2_BLND: - spr2 = SPR2_ROLL; - break; - - case SPR2_TWIN: - spr2 = SPR2_ROLL; - break; - - case SPR2_MLEE: - spr2 = SPR2_TWIN; - break; - - // NiGHTS sprites. - case SPR2_NSTD: - spr2 = SPR2_STND; - super = FF_SPR2SUPER; - break; - case SPR2_NFLT: - spr2 = SPR2_FLT ; - super = FF_SPR2SUPER; - break; - case SPR2_NSTN: - spr2 = SPR2_STUN; - break; - case SPR2_NPUL: - spr2 = SPR2_NSTN; - break; - case SPR2_NATK: - spr2 = SPR2_ROLL; - super = FF_SPR2SUPER; - break; - /*case SPR2_NGT0: - spr2 = SPR2_NFLT; - break;*/ - case SPR2_NGT1: - case SPR2_NGT7: - case SPR2_DRL0: - spr2 = SPR2_NGT0; - break; - case SPR2_NGT2: - case SPR2_DRL1: - spr2 = SPR2_NGT1; - break; - case SPR2_NGT3: - case SPR2_DRL2: - spr2 = SPR2_NGT2; - break; - case SPR2_NGT4: - case SPR2_DRL3: - spr2 = SPR2_NGT3; - break; - case SPR2_NGT5: - case SPR2_DRL4: - spr2 = SPR2_NGT4; - break; - case SPR2_NGT6: - case SPR2_DRL5: - spr2 = SPR2_NGT5; - break; - case SPR2_DRL6: - spr2 = SPR2_NGT6; - break; - case SPR2_NGT8: - case SPR2_DRL7: - spr2 = SPR2_NGT7; - break; - case SPR2_NGT9: - case SPR2_DRL8: - spr2 = SPR2_NGT8; - break; - case SPR2_NGTA: - case SPR2_DRL9: - spr2 = SPR2_NGT9; - break; - case SPR2_NGTB: - case SPR2_DRLA: - spr2 = SPR2_NGTA; - break; - case SPR2_NGTC: - case SPR2_DRLB: - spr2 = SPR2_NGTB; - break; - case SPR2_DRLC: - spr2 = SPR2_NGTC; - break; - - // Dunno? Just go to standing then. + // Use the handy list, that's what it's there for! default: - spr2 = SPR2_STND; + spr2 = spr2defaults[spr2]; break; } diff --git a/src/screen.c b/src/screen.c index 2e3d2e0f4..8c1811d5d 100644 --- a/src/screen.c +++ b/src/screen.c @@ -173,6 +173,9 @@ void SCR_SetMode(void) if (SCR_IsAspectCorrect(vid.width, vid.height)) CONS_Alert(CONS_WARNING, M_GetText("Resolution is not aspect-correct!\nUse a multiple of %dx%d\n"), BASEVIDWIDTH, BASEVIDHEIGHT); #endif*/ + + wallcolfunc = walldrawerfunc; + // set the apprpriate drawer for the sky (tall or INT16) setmodeneeded = 0; } diff --git a/src/sdl/MakeNIX.cfg b/src/sdl/MakeNIX.cfg index 1a0b54210..47c944eb5 100644 --- a/src/sdl/MakeNIX.cfg +++ b/src/sdl/MakeNIX.cfg @@ -65,37 +65,6 @@ ifdef MACOSX LIBS+=-framework CoreFoundation endif -# -#here is GP2x (arm-gp2x-linux) -# -ifdef GP2X - PNG_CONFIG?=$(PREFIX)-libpng12-config -ifdef STATIC #need a better setting name - CFLAGS+=-I$(OPEN2X)/include -ifndef NOMIXER - LIBS+=-lvorbisidec -ifdef MIKMOD - LIBS+=-lmikmod -endif -ifdef SMPEGLIB - LIBS+=-lsmpeg - LD=$(CXX) -endif -endif - NONET=1 -endif -ifndef ARCHNAME -"error" -endif - NONX86=1 - NOHW=1 - NOHS=1 - NOMD5=1 - WFLAGS+=-O0 - OPTS+=-DGP2X -ffast-math -mcpu=arm920t - EXENAME?=SRB2GP2X.gpe -endif - ifndef NOHW OPTS+=-I/usr/X11R6/include LDFLAGS+=-L/usr/X11R6/lib diff --git a/src/sdl/Makefile.cfg b/src/sdl/Makefile.cfg index b54f7057c..58c4d0861 100644 --- a/src/sdl/Makefile.cfg +++ b/src/sdl/Makefile.cfg @@ -14,26 +14,6 @@ ifdef PANDORA include sdl/SRB2Pandora/Makefile.cfg endif #ifdef PANDORA -ifdef DC -include sdl/SRB2DC/Makefile.cfg -endif #ifdef DC - -ifdef PS3N -include sdl/SRB2PS3/Makefile.cfg -endif #ifdef PS3N - -ifdef PSP -include sdl/SRB2PSP/Makefile.cfg -endif #ifdef PSP - -ifdef XBOX -include sdl/SRB2XBOX/Makefile.cfg -endif #ifdef XBOX - -ifdef WINCE -include sdl/SRB2CE/Makefile.cfg -endif #ifef WINCE - ifdef CYGWIN32 include sdl/MakeCYG.cfg endif #ifdef CYGWIN32 @@ -150,15 +130,8 @@ endif endif endif -# FIXME: DevkitPPC and ready-compiled SDL Wii require these things to be in a silly order -ifdef WII -include sdl/SRB2WII/Makefile.cfg -endif #ifdef WII - CFLAGS+=$(SDL_CFLAGS) LIBS:=$(SDL_LDFLAGS) $(LIBS) -ifndef WII ifdef STATIC LIBS+=$(shell $(SDL_CONFIG) --static-libs) endif -endif diff --git a/src/sdl/endtxt.c b/src/sdl/endtxt.c index 1d7756b4d..1e72ca9a8 100644 --- a/src/sdl/endtxt.c +++ b/src/sdl/endtxt.c @@ -33,7 +33,6 @@ void ShowEndTxt(void) { -#if !(defined (_WIN32_WCE) || defined (_XBOX) || defined (_arch_dreamcast)) INT32 i; UINT16 j, att = 0; INT32 nlflag = 1; @@ -232,5 +231,4 @@ void ShowEndTxt(void) printf("\n"); Z_Free(data); -#endif } diff --git a/src/sdl/hwsym_sdl.c b/src/sdl/hwsym_sdl.c index 54f5da3a0..f4686d2bf 100644 --- a/src/sdl/hwsym_sdl.c +++ b/src/sdl/hwsym_sdl.c @@ -37,14 +37,8 @@ #pragma warning(default : 4214 4244) #endif -#if defined (_XBOX) || defined (_arch_dreamcast) || defined(GP2X) -#define NOLOADSO -#endif - -#if SDL_VERSION_ATLEAST(1,2,6) && !defined (NOLOADSO) -#include "SDL_loadso.h" // 1.2.6+ -#elif !defined (NOLOADSO) -#define NOLOADSO +#ifndef NOLOADSO +#include "SDL_loadso.h" #endif #define _CREATE_DLL_ // necessary for Unix AND Windows diff --git a/src/sdl/i_main.c b/src/sdl/i_main.c index 25fccb9f9..f1cecad4d 100644 --- a/src/sdl/i_main.c +++ b/src/sdl/i_main.c @@ -26,28 +26,6 @@ #include #endif -#ifdef _WII -#include -#include -#include -#ifdef REMOTE_DEBUGGING -#include -#endif -static char wiicwd[PATH_MAX] = "sd:/"; -static char localip[16] = {0}; -static char gateway[16] = {0}; -static char netmask[16] = {0}; -#endif - -#ifdef _PSP -#include -#include -PSP_HEAP_SIZE_KB(24*1024); -PSP_MAIN_THREAD_ATTR(PSP_THREAD_ATTR_USER | PSP_THREAD_ATTR_VFPU); -PSP_MAIN_THREAD_NAME("SRB2"); -PSP_MAIN_THREAD_STACK_SIZE_KB(256); -#endif - #ifdef HAVE_SDL #ifdef HAVE_TTF @@ -79,23 +57,12 @@ FILE *logstream = NULL; #endif #endif -#if defined (_WIN32) && !defined (_XBOX) +#if defined (_WIN32) #include "../win32/win_dbg.h" typedef BOOL (WINAPI *p_IsDebuggerPresent)(VOID); #endif -#ifdef _arch_dreamcast -#include -KOS_INIT_FLAGS(INIT_DEFAULT -//| INIT_NET -//| INIT_MALLOCSTATS -//| INIT_QUIET -//| INIT_OCRAM -//| INIT_NO_DCLOAD -); -#endif - -#if defined (_WIN32) && !defined (_XBOX) && !defined (_WIN32_WCE) +#if defined (_WIN32) static inline VOID MakeCodeWritable(VOID) { #ifdef USEASM // Disable write-protection of code segment @@ -136,13 +103,6 @@ static inline VOID MakeCodeWritable(VOID) \return int */ -#if defined (_XBOX) && defined (__GNUC__) -void XBoxStartup() -{ - const char *logdir = NULL; - myargc = -1; - myargv = NULL; -#else #ifdef FORCESDLMAIN int SDL_main(int argc, char **argv) #else @@ -152,56 +112,19 @@ int main(int argc, char **argv) const char *logdir = NULL; myargc = argc; myargv = argv; /// \todo pull out path to exe from this string -#endif #ifdef HAVE_TTF -#ifdef _PS3 - // apparently there is a bug in SDL_PSL1GHT which needs this to be set to work around - SDL_setenv("SDL_VIDEODRIVER", "psl1ght", 1); - I_StartupTTF(FONTPOINTSIZE, SDL_INIT_VIDEO, SDL_SWSURFACE|SDL_DOUBLEBUF); -#elif defined(_WIN32) +#ifdef _WIN32 I_StartupTTF(FONTPOINTSIZE, SDL_INIT_VIDEO|SDL_INIT_AUDIO, SDL_SWSURFACE); #else I_StartupTTF(FONTPOINTSIZE, SDL_INIT_VIDEO, SDL_SWSURFACE); #endif #endif -#ifdef _PS3 - // initialise controllers. - //ioPadInit(7); -#endif - -// init Wii-specific stuff -#ifdef _WII - // Start network - if_config(localip, netmask, gateway, TRUE); - -#ifdef REMOTE_DEBUGGING -#if REMOTE_DEBUGGING == 0 - DEBUG_Init(GDBSTUB_DEVICE_TCP, GDBSTUB_DEF_TCPPORT); // Port 2828 -#elif REMOTE_DEBUGGING > 2 - DEBUG_Init(GDBSTUB_DEVICE_TCP, REMOTE_DEBUGGING); // Custom Port -#elif REMOTE_DEBUGGING < 0 - DEBUG_Init(GDBSTUB_DEVICE_USB, GDBSTUB_DEF_CHANNEL); // Slot 1 -#else - DEBUG_Init(GDBSTUB_DEVICE_USB, REMOTE_DEBUGGING-1); // Custom Slot -#endif -#endif - // Start FAT filesystem - fatInitDefault(); - - if (getcwd(wiicwd, PATH_MAX)) - I_PutEnv(va("HOME=%ssrb2wii", wiicwd)); -#endif - logdir = D_Home(); #ifdef LOGMESSAGES -#if defined(_WIN32_WCE) || defined(GP2X) - logstream = fopen(va("%s.log",argv[0]), "wt"); -#elif defined (_WII) - logstream = fopen(va("%s/log.txt",logdir), "wt"); -#elif defined (DEFAULTDIR) +#ifdef DEFAULTDIR if (logdir) logstream = fopen(va("%s/"DEFAULTDIR"/log.txt",logdir), "wt"); else @@ -211,8 +134,7 @@ int main(int argc, char **argv) //I_OutputMsg("I_StartupSystem() ...\n"); I_StartupSystem(); -#if defined (_WIN32) && !defined (_XBOX) -#ifndef _WIN32_WCE +#if defined (_WIN32) { #if 0 // just load the DLL p_IsDebuggerPresent pfnIsDebuggerPresent = (p_IsDebuggerPresent)GetProcAddress(GetModuleHandleA("kernel32.dll"), "IsDebuggerPresent"); @@ -226,11 +148,8 @@ int main(int argc, char **argv) LoadLibraryA("exchndl.dll"); } } -#endif prevExceptionFilter = SetUnhandledExceptionFilter(RecordExceptionInfo); -#ifndef _WIN32_WCE MakeCodeWritable(); -#endif #endif // startup SRB2 CONS_Printf("Setting up SRB2...\n"); diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index fdf96bae7..f46cec2af 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -26,19 +26,12 @@ #include "../config.h.in" #endif -#ifndef _WIN32_WCE #include -#endif -#ifdef _XBOX -#include "SRB2XBOX/xboxhelp.h" -#endif - -#if defined (_WIN32) && !defined (_XBOX) +#ifdef _WIN32 #define RPC_NO_WINDOWS_H #include #include "../doomtype.h" -#ifndef _WIN32_WCE typedef BOOL (WINAPI *p_GetDiskFreeSpaceExA)(LPCSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER); typedef BOOL (WINAPI *p_IsProcessorFeaturePresent) (DWORD); typedef DWORD (WINAPI *p_timeGetTime) (void); @@ -46,7 +39,6 @@ typedef UINT (WINAPI *p_timeEndPeriod) (UINT); typedef HANDLE (WINAPI *p_OpenFileMappingA) (DWORD, BOOL, LPCSTR); typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); #endif -#endif #include #include #include @@ -59,18 +51,10 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); #include #endif -#ifdef _arch_dreamcast -#include -#include -#include -#include -void __set_fpscr(long); // in libgcc / kernel's startup.s? -#else #include -#if defined (_WIN32) && !defined (_WIN32_WCE) && !defined (_XBOX) +#ifdef _WIN32 #include #endif -#endif #ifdef _MSC_VER #pragma warning(disable : 4214 4244) @@ -88,15 +72,10 @@ void __set_fpscr(long); // in libgcc / kernel's startup.s? #pragma warning(default : 4214 4244) #endif -#if SDL_VERSION_ATLEAST(1,2,7) && !defined (DC) -#include "SDL_cpuinfo.h" // 1.2.7 or greater +#include "SDL_cpuinfo.h" #define HAVE_SDLCPUINFO -#endif -#ifdef _PSP -//#include -#elif !defined(_PS3) -#if defined (__unix__) || defined(__APPLE__) || (defined (UNIXCOMMON) && !defined (_arch_dreamcast) && !defined (__HAIKU__) && !defined (_WII)) +#if defined (__unix__) || defined(__APPLE__) || (defined (UNIXCOMMON) && !defined (__HAIKU__)) #if defined (__linux__) #include #else @@ -111,20 +90,17 @@ void __set_fpscr(long); // in libgcc / kernel's startup.s? #include #endif #endif -#endif -#ifndef _PS3 -#if defined (__linux__) || (defined (UNIXCOMMON) && !defined (_arch_dreamcast) && !defined (_PSP) && !defined (__HAIKU__) && !defined (_WII)) +#if defined (__linux__) || (defined (UNIXCOMMON) && !defined (__HAIKU__)) #ifndef NOTERMIOS #include #include // ioctl #define HAVE_TERMIOS #endif #endif -#endif #ifndef NOMUMBLE -#if defined (__linux__) && !defined(_PS3) // need -lrt +#ifdef __linux__ // need -lrt #include #ifdef MAP_FAILED #define HAVE_SHM @@ -132,7 +108,7 @@ void __set_fpscr(long); // in libgcc / kernel's startup.s? #include #endif -#if defined (_WIN32) && !defined (_WIN32_WCE) && !defined (_XBOX) +#ifdef _WIN32 #define HAVE_MUMBLE #define WINMUMBLE #elif defined (HAVE_SHM) @@ -140,10 +116,6 @@ void __set_fpscr(long); // in libgcc / kernel's startup.s? #endif #endif // NOMUMBLE -#ifdef _WIN32_WCE -#include "SRB2CE/cehelp.h" -#endif - #ifndef O_BINARY #define O_BINARY 0 #endif @@ -153,44 +125,7 @@ void __set_fpscr(long); // in libgcc / kernel's startup.s? #endif // Locations for searching the srb2.srb -#ifdef _arch_dreamcast -#define DEFAULTWADLOCATION1 "/cd" -#define DEFAULTWADLOCATION2 "/pc" -#define DEFAULTWADLOCATION3 "/pc/home/alam/srb2code/data" -#define DEFAULTSEARCHPATH1 "/cd" -#define DEFAULTSEARCHPATH2 "/pc" -//#define DEFAULTSEARCHPATH3 "/pc/home/alam/srb2code/data" -#elif defined (GP2X) -#define DEFAULTWADLOCATION1 "/mnt/sd" -#define DEFAULTWADLOCATION2 "/mnt/sd/SRB2" -#define DEFAULTWADLOCATION3 "/tmp/mnt/sd" -#define DEFAULTWADLOCATION4 "/tmp/mnt/sd/SRB2" -#define DEFAULTSEARCHPATH1 "/mnt/sd" -#define DEFAULTSEARCHPATH2 "/tmp/mnt/sd" -#elif defined (_WII) -#define NOCWD -#define NOHOME -#define NEED_SDL_GETENV -#define DEFAULTWADLOCATION1 "sd:/srb2wii" -#define DEFAULTWADLOCATION2 "usb:/srb2wii" -#define DEFAULTSEARCHPATH1 "sd:/srb2wii" -#define DEFAULTSEARCHPATH2 "usb:/srb2wii" -// PS3: TODO: this will need modification most likely -#elif defined (_PS3) -#define NOCWD -#define NOHOME -#define DEFAULTWADLOCATION1 "/dev_hdd0/game/SRB2-PS3_/USRDIR/etc" -#define DEFAULTWADLOCATION2 "/dev_usb/SRB2PS3" -#define DEFAULTSEARCHPATH1 "/dev_hdd0/game/SRB2-PS3_/USRDIR/etc" -#define DEFAULTSEARCHPATH2 "/dev_usb/SRB2PS3" -#elif defined (_PSP) -#define NOCWD -#define NOHOME -#define DEFAULTWADLOCATION1 "host0:/bin/Resources" -#define DEFAULTWADLOCATION2 "ms0:/PSP/GAME/SRB2PSP" -#define DEFAULTSEARCHPATH1 "host0:/" -#define DEFAULTSEARCHPATH2 "ms0:/PSP/GAME/SRB2PSP" -#elif defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) +#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) #define DEFAULTWADLOCATION1 "/usr/local/share/games/SRB2" #define DEFAULTWADLOCATION2 "/usr/local/games/SRB2" #define DEFAULTWADLOCATION3 "/usr/share/games/SRB2" @@ -198,23 +133,6 @@ void __set_fpscr(long); // in libgcc / kernel's startup.s? #define DEFAULTSEARCHPATH1 "/usr/local/games" #define DEFAULTSEARCHPATH2 "/usr/games" #define DEFAULTSEARCHPATH3 "/usr/local" -#elif defined (_XBOX) -#define NOCWD -#ifdef __GNUC__ -#include -#endif -#define DEFAULTWADLOCATION1 "c:\\srb2" -#define DEFAULTWADLOCATION2 "d:\\srb2" -#define DEFAULTWADLOCATION3 "e:\\srb2" -#define DEFAULTWADLOCATION4 "f:\\srb2" -#define DEFAULTWADLOCATION5 "g:\\srb2" -#define DEFAULTWADLOCATION6 "h:\\srb2" -#define DEFAULTWADLOCATION7 "i:\\srb2" -#elif defined (_WIN32_WCE) -#define NOCWD -#define NOHOME -#define DEFAULTWADLOCATION1 "\\Storage Card\\SRB2DEMO" -#define DEFAULTSEARCHPATH1 "\\Storage Card" #elif defined (_WIN32) #define DEFAULTWADLOCATION1 "c:\\games\\srb2" #define DEFAULTWADLOCATION2 "\\games\\srb2" @@ -270,9 +188,6 @@ static void JoyReset(SDLJoyInfo_t *JoySet) { if (JoySet->dev) { -#ifdef GP2X //GP2X's SDL does an illegal free on the 1st joystick... - if (SDL_JoystickIndex(JoySet->dev) != 0) -#endif SDL_JoystickClose(JoySet->dev); } JoySet->dev = NULL; @@ -308,7 +223,6 @@ SDL_bool framebuffer = SDL_FALSE; UINT8 keyboard_started = false; -#if !defined (DC) FUNCNORETURN static ATTRNORETURN void signal_handler(INT32 num) { //static char msg[] = "oh no! back to reality!\r\n"; @@ -362,7 +276,6 @@ FUNCNORETURN static ATTRNORETURN void quit_handler(int num) raise(num); I_Quit(); } -#endif #ifdef HAVE_TERMIOS // TERMIOS console code from Quake3: thank you! @@ -487,9 +400,7 @@ static void I_StartupConsole(void) signal(SIGTTIN, SIG_IGN); signal(SIGTTOU, SIG_IGN); -#if !defined(GP2X) //read is bad on GP2X consolevent = !M_CheckParm("-noconsole"); -#endif framebuffer = M_CheckParm("-framebuffer"); if (framebuffer) @@ -577,7 +488,7 @@ void I_GetConsoleEvents(void) (void)d; } -#elif defined (_WIN32) && !(defined (_XBOX) || defined (_WIN32_WCE)) +#elif defined (_WIN32) static BOOL I_ReadyConsole(HANDLE ci) { DWORD gotinput; @@ -716,17 +627,6 @@ static inline void I_ShutdownConsole(void){} void I_GetConsoleEvents(void){} static inline void I_StartupConsole(void) { -#ifdef _arch_dreamcast - char title[] = "SRB2 for Dreamcast!\n"; - __set_fpscr(0x00040000); /* ignore FPU underflow */ - //printf("\nHello world!\n\n"); - pvr_init_defaults(); - conio_init(CONIO_TTY_PVR, CONIO_INPUT_LINE); - conio_set_theme(CONIO_THEME_MATRIX); - conio_clear(); - conio_putstr(title); - //printf("\nHello world!\n\n"); -#endif #ifdef _DEBUG consolevent = !M_CheckParm("-noconsole"); #else @@ -746,7 +646,6 @@ static inline void I_ShutdownConsole(void){} // void I_StartupKeyboard (void) { -#if !defined (DC) #ifdef SIGINT signal(SIGINT , quit_handler); #endif @@ -763,7 +662,6 @@ void I_StartupKeyboard (void) signal(SIGSEGV , signal_handler); signal(SIGABRT , signal_handler); signal(SIGFPE , signal_handler); -#endif } // @@ -775,10 +673,6 @@ void I_OutputMsg(const char *fmt, ...) XBOXSTATIC char txt[8192]; va_list argptr; -#ifdef _arch_dreamcast - if (!keyboard_started) conio_printf(fmt); -#endif - va_start(argptr,fmt); vsprintf(txt, fmt, argptr); va_end(argptr); @@ -788,7 +682,7 @@ void I_OutputMsg(const char *fmt, ...) DEFAULTFONTBGR, DEFAULTFONTBGG, DEFAULTFONTBGB, DEFAULTFONTBGA, txt); #endif -#if defined (_WIN32) && !defined (_XBOX) && defined (_MSC_VER) +#if defined (_WIN32) && defined (_MSC_VER) OutputDebugStringA(txt); #endif @@ -803,7 +697,7 @@ void I_OutputMsg(const char *fmt, ...) } #endif -#if defined (_WIN32) && !defined (_XBOX) && !defined(_WIN32_WCE) +#if defined (_WIN32) #ifdef DEBUGFILE if (debugfile != stderr) #endif @@ -917,22 +811,12 @@ INT32 I_GetKey (void) // void I_JoyScale(void) { -#ifdef GP2X - if (JoyInfo.dev && SDL_JoystickIndex(JoyInfo.dev) == 0) - Joystick.bGamepadStyle = true; - else -#endif Joystick.bGamepadStyle = cv_joyscale.value==0; JoyInfo.scale = Joystick.bGamepadStyle?1:cv_joyscale.value; } void I_JoyScale2(void) { -#ifdef GP2X - if (JoyInfo2.dev && SDL_JoystickIndex(JoyInfo2.dev) == 0) - Joystick.bGamepadStyle = true; - else -#endif Joystick2.bGamepadStyle = cv_joyscale2.value==0; JoyInfo2.scale = Joystick2.bGamepadStyle?1:cv_joyscale2.value; } @@ -1035,11 +919,6 @@ void I_GetJoystickEvents(void) event.type = ev_keydown; else event.type = ev_keyup; -#ifdef _PSP - if (i == 12) - event.data1 = KEY_ESCAPE; - else -#endif event.data1 = KEY_JOY1 + i; D_PostEvent(&event); } @@ -1090,13 +969,11 @@ void I_GetJoystickEvents(void) axisy = SDL_JoystickGetAxis(JoyInfo.dev, i*2 + 1); else axisy = 0; -#ifdef _arch_dreamcast // -128 to 127 - axisx = axisx*8; - axisy = axisy*8; -#else // -32768 to 32767 + + // -32768 to 32767 axisx = axisx/32; axisy = axisy/32; -#endif + if (Joystick.bGamepadStyle) { @@ -1214,15 +1091,11 @@ static int joy_open(const char *fname) if (JoyInfo.buttons > JOYBUTTONS) JoyInfo.buttons = JOYBUTTONS; -#ifdef DC - JoyInfo.hats = 0; -#else JoyInfo.hats = SDL_JoystickNumHats(JoyInfo.dev); if (JoyInfo.hats > JOYHATS) JoyInfo.hats = JOYHATS; JoyInfo.balls = SDL_JoystickNumBalls(JoyInfo.dev); -#endif //Joystick.bGamepadStyle = !stricmp(SDL_JoystickName(JoyInfo.dev), "pad"); @@ -1379,13 +1252,9 @@ void I_GetJoystick2Events(void) axisy = SDL_JoystickGetAxis(JoyInfo2.dev, i*2 + 1); else axisy = 0; -#ifdef _arch_dreamcast // -128 to 127 - axisx = axisx*8; - axisy = axisy*8; -#else // -32768 to 32767 + // -32768 to 32767 axisx = axisx/32; axisy = axisy/32; -#endif if (Joystick2.bGamepadStyle) { @@ -1504,15 +1373,11 @@ static int joy_open2(const char *fname) if (JoyInfo2.buttons > JOYBUTTONS) JoyInfo2.buttons = JOYBUTTONS; -#ifdef DC - JoyInfo2.hats = 0; -#else JoyInfo2.hats = SDL_JoystickNumHats(JoyInfo2.dev); if (JoyInfo2.hats > JOYHATS) JoyInfo2.hats = JOYHATS; JoyInfo2.balls = SDL_JoystickNumBalls(JoyInfo2.dev); -#endif //Joystick.bGamepadStyle = !stricmp(SDL_JoystickName(JoyInfo2.dev), "pad"); @@ -1796,7 +1661,7 @@ static void I_ShutdownMouse2(void) if (fdmouse2 != -1) close(fdmouse2); mouse2_started = 0; } -#elif defined (_WIN32) && !defined (_XBOX) +#elif defined (_WIN32) static HANDLE mouse2filehandle = INVALID_HANDLE_VALUE; @@ -1994,7 +1859,7 @@ void I_StartupMouse2(void) } mouse2_started = 1; I_AddExitFunc(I_ShutdownMouse2); -#elif defined (_WIN32) && !defined (_XBOX) +#elif defined (_WIN32) DCB dcb; if (mouse2filehandle != INVALID_HANDLE_VALUE) @@ -2089,7 +1954,7 @@ FUNCMATH ticcmd_t *I_BaseTiccmd2(void) return &emptycmd2; } -#if (defined (_WIN32) && !defined (_WIN32_WCE)) && !defined (_XBOX) +#if defined (_WIN32) static HMODULE winmm = NULL; static DWORD starttickcount = 0; // hack for win2k time bug static p_timeGetTime pfntimeGetTime = NULL; @@ -2159,13 +2024,8 @@ static void I_ShutdownTimer(void) // tic_t I_GetTime (void) { -#ifdef _arch_dreamcast - static Uint64 basetime = 0; - Uint64 ticks = timer_ms_gettime64(); //using timer_ms_gettime64 instand of SDL_GetTicks for the Dreamcast -#else static Uint32 basetime = 0; Uint32 ticks = SDL_GetTicks(); -#endif if (!basetime) basetime = ticks; @@ -2174,11 +2034,7 @@ tic_t I_GetTime (void) ticks = (ticks*TICRATE); -#if 0 //#ifdef _WIN32_WCE - ticks = (ticks/10); -#else ticks = (ticks/1000); -#endif return (tic_t)ticks; } @@ -2189,7 +2045,7 @@ tic_t I_GetTime (void) // FUNCMATH void I_StartupTimer(void) { -#if (defined (_WIN32) && !defined (_WIN32_WCE)) && !defined (_XBOX) +#ifdef _WIN32 // for win2k time bug if (M_CheckParm("-gettickcount")) { @@ -2205,9 +2061,6 @@ FUNCMATH void I_StartupTimer(void) pfntimeGetTime = (p_timeGetTime)GetProcAddress(winmm, "timeGetTime"); } I_AddExitFunc(I_ShutdownTimer); -#elif 0 //#elif !defined (_arch_dreamcast) && !defined(GP2X) // the DC have it own timer and GP2X have broken pthreads? - if (SDL_InitSubSystem(SDL_INIT_TIMER) < 0) - I_Error("SRB2: Needs SDL_Timer, Error: %s", SDL_GetError()); #endif } @@ -2215,35 +2068,14 @@ FUNCMATH void I_StartupTimer(void) void I_Sleep(void) { -#if !(defined (_arch_dreamcast) || defined (_XBOX)) if (cv_sleep.value != -1) SDL_Delay(cv_sleep.value); -#endif } INT32 I_StartupSystem(void) { SDL_version SDLcompiled; SDL_version SDLlinked; -#ifdef _XBOX -#ifdef __GNUC__ - char DP[] =" Sonic Robo Blast 2!\n"; - debugPrint(DP); -#endif - unlink("e:/Games/SRB2/stdout.txt"); - freopen("e:/Games/SRB2/stdout.txt", "w+", stdout); - unlink("e:/Games/SRB2/stderr.txt"); - freopen("e:/Games/SRB2/stderr.txt", "w+", stderr); -#endif -#ifdef _arch_dreamcast -#ifdef _DEBUG - //gdb_init(); -#endif - printf(__FILE__":%i\n",__LINE__); -#ifdef _DEBUG - //gdb_breakpoint(); -#endif -#endif SDL_VERSION(&SDLcompiled) SDL_GetVersion(&SDLlinked); I_StartupConsole(); @@ -2251,11 +2083,7 @@ INT32 I_StartupSystem(void) SDLcompiled.major, SDLcompiled.minor, SDLcompiled.patch); I_OutputMsg("Linked with SDL version: %d.%d.%d\n", SDLlinked.major, SDLlinked.minor, SDLlinked.patch); -#if 0 //#ifdef GP2X //start up everything - if (SDL_Init(SDL_INIT_NOPARACHUTE|SDL_INIT_EVERYTHING) < 0) -#else - if (SDL_Init(SDL_INIT_NOPARACHUTE) < 0) -#endif + if (SDL_Init(0) < 0) I_Error("SRB2: SDL System Error: %s", SDL_GetError()); //Alam: Oh no.... #ifndef NOMUMBLE I_SetupMumble(); @@ -2297,9 +2125,7 @@ void I_Quit(void) I_ShutdownGraphics(); I_ShutdownInput(); I_ShutdownSystem(); -#ifndef _arch_dreamcast SDL_Quit(); -#endif /* if option -noendtxt is set, don't print the text */ if (!M_CheckParm("-noendtxt") && W_CheckNumForName("ENDOOM") != LUMPERROR) { @@ -2308,10 +2134,6 @@ void I_Quit(void) } death: W_Shutdown(); -#ifdef GP2X - chdir("/usr/gp2x"); - execl("/usr/gp2x/gp2xmenu", "/usr/gp2x/gp2xmenu", NULL); -#endif exit(0); } @@ -2364,10 +2186,8 @@ void I_Error(const char *error, ...) I_ShutdownInput(); if (errorcount == 7) I_ShutdownSystem(); -#ifndef _arch_dreamcast if (errorcount == 8) SDL_Quit(); -#endif if (errorcount == 9) { M_SaveConfig(NULL); @@ -2386,12 +2206,6 @@ void I_Error(const char *error, ...) buffer, NULL); W_Shutdown(); - -#ifdef GP2X - chdir("/usr/gp2x"); - execl("/usr/gp2x/gp2xmenu", "/usr/gp2x/gp2xmenu", NULL); -#endif - exit(-1); // recursive errors detected } } @@ -2427,9 +2241,7 @@ void I_Error(const char *error, ...) I_ShutdownGraphics(); I_ShutdownInput(); I_ShutdownSystem(); -#ifndef _arch_dreamcast SDL_Quit(); -#endif // Implement message box with SDL_ShowSimpleMessageBox, // which should fail gracefully if it can't put a message box up @@ -2449,11 +2261,6 @@ void I_Error(const char *error, ...) *(INT32 *)2 = 4; //Alam: Debug! #endif -#ifdef GP2X - chdir("/usr/gp2x"); - execl("/usr/gp2x/gp2xmenu", "/usr/gp2x/gp2xmenu", NULL); -#endif - exit(-1); } @@ -2516,7 +2323,7 @@ void I_ShutdownSystem(void) for (c = MAX_QUIT_FUNCS-1; c >= 0; c--) if (quit_funcs[c]) (*quit_funcs[c])(); -#ifdef LOGMESSAGES +#ifdef LOGMESSAGES if (logstream) { I_OutputMsg("I_ShutdownSystem(): end of logstream.\n"); @@ -2529,10 +2336,8 @@ void I_ShutdownSystem(void) void I_GetDiskFreeSpace(INT64 *freespace) { -#if defined (_arch_dreamcast) || defined (_PSP) - *freespace = 0; -#elif defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) -#if defined (SOLARIS) || defined (__HAIKU__) || defined (_WII) || defined (_PS3) +#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) +#if defined (SOLARIS) || defined (__HAIKU__) *freespace = INT32_MAX; return; #else // Both Linux and BSD have this, apparently. @@ -2544,7 +2349,7 @@ void I_GetDiskFreeSpace(INT64 *freespace) } *freespace = stfs.f_bavail * stfs.f_bsize; #endif -#elif (defined (_WIN32) && !defined (_WIN32_WCE)) && !defined (_XBOX) +#elif defined (_WIN32) static p_GetDiskFreeSpaceExA pfnGetDiskFreeSpaceEx = NULL; static boolean testwin95 = false; ULARGE_INTEGER usedbytes, lfreespace; @@ -2575,13 +2380,6 @@ void I_GetDiskFreeSpace(INT64 *freespace) char *I_GetUserName(void) { -#ifdef GP2X - static char username[MAXPLAYERNAME] = "GP2XUSER"; - return username; -#elif defined (PSP) - static char username[MAXPLAYERNAME] = "PSPUSER"; - return username; -#elif !(defined (_WIN32_WCE) || defined (_XBOX)) static char username[MAXPLAYERNAME]; char *p; #ifdef _WIN32 @@ -2613,7 +2411,6 @@ char *I_GetUserName(void) if (strcmp(username, "") != 0) return username; -#endif return NULL; // dummy for platform independent version } @@ -2622,7 +2419,7 @@ INT32 I_mkdir(const char *dirname, INT32 unixright) //[segabor] #if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) || defined (__CYGWIN__) || defined (__OS2__) return mkdir(dirname, unixright); -#elif (defined (_WIN32) || (defined (_WIN32_WCE) && !defined (__GNUC__))) && !defined (_XBOX) +#elif defined (_WIN32) UNREFERENCED_PARAMETER(unixright); /// \todo should implement ntright under nt... return CreateDirectoryA(dirname, NULL); #else @@ -2636,9 +2433,6 @@ char *I_GetEnv(const char *name) { #ifdef NEED_SDL_GETENV return SDL_getenv(name); -#elif defined(_WIN32_WCE) - (void)name; - return NULL; #else return getenv(name); #endif @@ -2648,8 +2442,6 @@ INT32 I_PutEnv(char *variable) { #ifdef NEED_SDL_GETENV return SDL_putenv(variable); -#elif defined(_WIN32_WCE) - return ((variable)?-1:0); #else return putenv(variable); #endif @@ -2789,15 +2581,6 @@ static const char *locateWad(void) if (((envstr = I_GetEnv("SRB2WADDIR")) != NULL) && isWadPathOk(envstr)) return envstr; -#if defined(_WIN32_WCE) || defined(_PS3) || defined(_PSP) - // examine argv[0] - strcpy(returnWadPath, myargv[0]); - pathonly(returnWadPath); - I_PutEnv(va("HOME=%s",returnWadPath)); - if (isWadPathOk(returnWadPath)) - return returnWadPath; -#endif - #ifndef NOCWD I_OutputMsg(",."); // examine current dir @@ -2916,9 +2699,9 @@ const char *I_LocateWad(void) if (waddir) { // change to the directory where we found srb2.srb -#if (defined (_WIN32) && !defined (_WIN32_WCE)) && !defined (_XBOX) +#if defined (_WIN32) SetCurrentDirectoryA(waddir); -#elif !defined (_WIN32_WCE) && !defined (_PS3) +#else if (chdir(waddir) == -1) I_OutputMsg("Couldn't change working directory\n"); #endif @@ -2935,17 +2718,7 @@ const char *I_LocateWad(void) // quick fix for compil UINT32 I_GetFreeMem(UINT32 *total) { -#if defined (_arch_dreamcast) - //Dreamcast! - if (total) - *total = 16<<20; - return 8<<20; -#elif defined (_PSP) - // PSP - if (total) - *total = 32<<20; - return 16<<20; -#elif defined (FREEBSD) +#ifdef FREEBSD struct vmmeter sum; kvm_t *kd; struct nlist namelist[] = @@ -2982,7 +2755,7 @@ UINT32 I_GetFreeMem(UINT32 *total) if (total) *total = 32 << 20; return 32 << 20; -#elif (defined (_WIN32) || (defined (_WIN32_WCE) && !defined (__GNUC__))) && !defined (_XBOX) +#elif defined (_WIN32) MEMORYSTATUS info; info.dwLength = sizeof (MEMORYSTATUS); @@ -3054,7 +2827,7 @@ UINT32 I_GetFreeMem(UINT32 *total) const CPUInfoFlags *I_CPUInfo(void) { -#if (defined (_WIN32) && !defined (_WIN32_WCE)) && !defined (_XBOX) +#if defined (_WIN32) static CPUInfoFlags WIN_CPUInfo; SYSTEM_INFO SI; p_IsProcessorFeaturePresent pfnCPUID = (p_IsProcessorFeaturePresent)GetProcAddress(GetModuleHandleA("kernel32.dll"), "IsProcessorFeaturePresent"); diff --git a/src/sdl/i_ttf.c b/src/sdl/i_ttf.c index 4a41f120e..f2cd497ee 100644 --- a/src/sdl/i_ttf.c +++ b/src/sdl/i_ttf.c @@ -26,10 +26,7 @@ #include "i_ttf.h" // Search directories to find aforementioned TTF file. -#ifdef _PS3 -#include -#define FONTSEARCHPATH1 "/dev_hdd0/game/SRB2-PS3_/USRDIR/etc" -#elif defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) +#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) #define FONTSEARCHPATH1 "/usr/share/fonts" #define FONTSEARCHPATH2 "/usr/local/share/fonts" #define FONTSEARCHPATH3 "/usr/games/SRB2" @@ -233,16 +230,9 @@ void I_StartupTTF(UINT32 fontpointsize, Uint32 initflags, Uint32 vidmodeflags) { char *fontpath = NULL; INT32 fontstatus = -1; -#ifdef _PS3 - videoState state; - videoGetState(0, 0, &state); - videoGetResolution(state.displayMode.resolution, &res); - bitsperpixel = 24; -#else res.width = 320; res.height = 200; bitsperpixel = 8; -#endif // what's the point of trying to display an error? // SDL_ttf is not started, can't display anything to screen (presumably)... diff --git a/src/sdl/i_ttf.h b/src/sdl/i_ttf.h index 929c8021c..5fae9ed16 100644 --- a/src/sdl/i_ttf.h +++ b/src/sdl/i_ttf.h @@ -57,13 +57,12 @@ int currentfonthinting; int currentfontoutline; #endif -#ifndef _PS3 typedef struct { UINT16 width; UINT16 height; } VideoResolution; -#endif + UINT8 bitsperpixel; typedef enum diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 752c443f5..893827a7b 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -47,7 +47,7 @@ #include "../doomdef.h" -#if defined (_WIN32) +#ifdef _WIN32 #include "SDL_syswm.h" #endif @@ -941,6 +941,7 @@ static inline boolean I_SkipFrame(void) case GS_LEVEL: if (!paused) return false; + /* FALLTHRU */ //case GS_TIMEATTACK: -- sorry optimisation but now we have a cool level platter and that being laggardly looks terrible case GS_WAITINGPLAYERS: return skip; // Skip odd frames diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index 88bbadd20..718324591 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -43,12 +43,10 @@ #define HAVE_ZLIB #ifndef _MSC_VER -#ifndef _WII #ifndef _LARGEFILE64_SOURCE #define _LARGEFILE64_SOURCE #endif #endif -#endif #ifndef _LFS64_LARGEFILE #define _LFS64_LARGEFILE diff --git a/src/sdl/sdl_sound.c b/src/sdl/sdl_sound.c index 0face92e2..1a2cabd23 100644 --- a/src/sdl/sdl_sound.c +++ b/src/sdl/sdl_sound.c @@ -49,7 +49,7 @@ #define MIX_CHANNELS 8 #endif -#if defined (_WIN32) && !defined (_WIN32_WCE) && !defined (_XBOX) +#ifdef _WIN32 #include #elif defined (__GNUC__) #include @@ -85,21 +85,11 @@ // mixing buffer, and the samplerate of the raw data. // Needed for calling the actual sound output. -#if defined (_WIN32_WCE) || defined (DC) || defined (PSP) || defined(GP2X) -#define NUM_CHANNELS MIX_CHANNELS -#else #define NUM_CHANNELS MIX_CHANNELS*4 -#endif #define INDEXOFSFX(x) ((sfxinfo_t *)x - S_sfx) -#if defined (_WIN32_WCE) || defined (DC) || defined (PSP) -static Uint16 samplecount = 512; //Alam: .5KB samplecount at 11025hz is 46.439909297052154195011337868481ms of buffer -#elif defined(GP2X) -static Uint16 samplecount = 128; -#else static Uint16 samplecount = 1024; //Alam: 1KB samplecount at 22050hz is 46.439909297052154195011337868481ms of buffer -#endif typedef struct chan_struct { @@ -151,17 +141,10 @@ static SDL_bool musicStarted = SDL_FALSE; #ifdef HAVE_MIXER static SDL_mutex *Msc_Mutex = NULL; /* FIXME: Make this file instance-specific */ -#ifdef _arch_dreamcast -#define MIDI_PATH "/ram" -#elif defined(GP2X) -#define MIDI_PATH "/mnt/sd/srb2" -#define MIDI_PATH2 "/tmp/mnt/sd/srb2" -#else #define MIDI_PATH srb2home #if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) #define MIDI_PATH2 "/tmp" #endif -#endif #define MIDI_TMPFILE "srb2music" #define MIDI_TMPFILE2 "srb2wav" static INT32 musicvol = 62; @@ -176,7 +159,7 @@ static SDL_bool canlooping = SDL_TRUE; #if SDL_MIXER_VERSION_ATLEAST(1,2,7) #define USE_RWOPS // ok, USE_RWOPS is in here -#if defined (DC) || defined (_WIN32_WCE) || defined (_XBOX) //|| defined(_WIN32) || defined(GP2X) +#if 0 // defined(_WIN32) #undef USE_RWOPS #endif #endif @@ -1188,13 +1171,6 @@ void I_StartupSound(void) #endif #ifndef HAVE_MIXER nomidimusic = nodigimusic = true; -#endif -#ifdef DC - //nosound = true; -#ifdef HAVE_MIXER - nomidimusic = true; - nodigimusic = true; -#endif #endif memset(channels, 0, sizeof (channels)); //Alam: Clean it @@ -1243,13 +1219,7 @@ void I_StartupSound(void) audio.samples /= 2; } -#if defined (_PSP) && defined (HAVE_MIXER) // Bug in PSP's SDL_OpenAudio, can not open twice - I_SetChannels(); - sound_started = true; - Snd_Mutex = SDL_CreateMutex(); -#else if (nosound) -#endif return; #ifdef HW3SOUND @@ -1302,7 +1272,7 @@ void I_StartupSound(void) snddev.bps = 16; snddev.sample_rate = audio.freq; snddev.numsfxs = NUMSFX; -#if defined (_WIN32) && !defined (_XBOX) +#if defined (_WIN32) snddev.cooplevel = 0x00000002; snddev.hWnd = vid.WndParent; #endif @@ -1520,9 +1490,7 @@ void I_InitMusic(void) I_OutputMsg("Compiled for SDL_mixer version: %d.%d.%d\n", MIXcompiled.major, MIXcompiled.minor, MIXcompiled.patch); #ifdef MIXER_POS -#ifndef _WII if (MIXlinked->major == 1 && MIXlinked->minor == 2 && MIXlinked->patch < 7) -#endif canlooping = SDL_FALSE; #endif #ifdef USE_RWOPS @@ -1531,13 +1499,11 @@ void I_InitMusic(void) #endif I_OutputMsg("Linked with SDL_mixer version: %d.%d.%d\n", MIXlinked->major, MIXlinked->minor, MIXlinked->patch); -#if !(defined (DC) || defined (PSP) || defined(GP2X) || defined (WII)) if (audio.freq < 44100 && !M_CheckParm ("-freq")) //I want atleast 44Khz { audio.samples = (Uint16)(audio.samples*(INT32)(44100/audio.freq)); audio.freq = 44100; //Alam: to keep it around the same XX ms } -#endif if (sound_started #ifdef HW3SOUND @@ -1929,7 +1895,7 @@ boolean I_StartDigSong(const char *musicname, boolean looping) if (loopstart > 0) { loopstartDig = (double)((44.1l+loopstart) / 44100.0l); //8 PCM chucks off and PCM to secs -//#ifdef GP2X//#ifdef PARANOIA +//#ifdef PARANOIA //I_OutputMsg("I_StartDigSong: setting looping point to %ul PCMs(%f seconds)\n", loopstart, loopstartDig); //#endif } diff --git a/src/sdl12/MakeCYG.cfg b/src/sdl12/MakeCYG.cfg index 5907579c1..b55d9dc50 100644 --- a/src/sdl12/MakeCYG.cfg +++ b/src/sdl12/MakeCYG.cfg @@ -1,5 +1,5 @@ # -# sdl/makeCYG.cfg for SRB2/Cygwin +# sdl12/makeCYG.cfg for SRB2/Cygwin # # diff --git a/src/sdl12/MakeNIX.cfg b/src/sdl12/MakeNIX.cfg index 457f52301..1278aaf06 100644 --- a/src/sdl12/MakeNIX.cfg +++ b/src/sdl12/MakeNIX.cfg @@ -1,5 +1,5 @@ # -# sdl/makeNIX.cfg for SRB2/?nix +# sdl12/makeNIX.cfg for SRB2/?nix # #Valgrind support diff --git a/src/sdl12/Makefile.cfg b/src/sdl12/Makefile.cfg index 1d404c4c9..8d9ebc35c 100644 --- a/src/sdl12/Makefile.cfg +++ b/src/sdl12/Makefile.cfg @@ -1,5 +1,5 @@ # -# sdl/makefile.cfg for SRB2/SDL +# sdl12/makefile.cfg for SRB2/SDL # # @@ -7,35 +7,35 @@ # ifdef UNIXCOMMON -include sdl/MakeNIX.cfg +include sdl12/MakeNIX.cfg endif ifdef PANDORA -include sdl/SRB2Pandora/Makefile.cfg +include sdl12/SRB2Pandora/Makefile.cfg endif #ifdef PANDORA ifdef DC -include sdl/SRB2DC/Makefile.cfg +include sdl12/SRB2DC/Makefile.cfg endif #ifdef DC ifdef PS3N -include sdl/SRB2PS3/Makefile.cfg +include sdl12/SRB2PS3/Makefile.cfg endif #ifdef PS3N ifdef PSP -include sdl/SRB2PSP/Makefile.cfg +include sdl12/SRB2PSP/Makefile.cfg endif #ifdef PSP ifdef XBOX -include sdl/SRB2XBOX/Makefile.cfg +include sdl12/SRB2XBOX/Makefile.cfg endif #ifdef XBOX ifdef WINCE -include sdl/SRB2CE/Makefile.cfg +include sdl12/SRB2CE/Makefile.cfg endif #ifef WINCE ifdef CYGWIN32 -include sdl/MakeCYG.cfg +include sdl12/MakeCYG.cfg endif #ifdef CYGWIN32 ifdef SDL_PKGCONFIG @@ -151,7 +151,7 @@ endif # FIXME: DevkitPPC and ready-compiled SDL Wii require these things to be in a silly order ifdef WII -include sdl/SRB2WII/Makefile.cfg +include sdl12/SRB2WII/Makefile.cfg endif #ifdef WII CFLAGS+=$(SDL_CFLAGS) diff --git a/src/sdl12/SRB2PS3/Makefile.cfg b/src/sdl12/SRB2PS3/Makefile.cfg index a4a01714a..80f8db7bc 100644 --- a/src/sdl12/SRB2PS3/Makefile.cfg +++ b/src/sdl12/SRB2PS3/Makefile.cfg @@ -27,10 +27,10 @@ PKGNAME?=SRB2PS3.pkg endif DGBNAME?=$(EXENAME).debug -SRB2PS3DIR=sdl/SRB2PS3 +SRB2PS3DIR=sdl12/SRB2PS3 ICON0?=$(SRB2PS3DIR)/ICON0.png SFOXML?=sfo.xml -SRB2TTF?=sdl/srb2.ttf +SRB2TTF?=sdl12/srb2.ttf TITLE=Sonic Robo Blast 2 v2.0.6 APPID=SRB2-PS3 diff --git a/src/sdl12/SRB2PSP/Makefile.cfg b/src/sdl12/SRB2PSP/Makefile.cfg index f9ec6416b..5e4c0ba2f 100644 --- a/src/sdl12/SRB2PSP/Makefile.cfg +++ b/src/sdl12/SRB2PSP/Makefile.cfg @@ -36,14 +36,14 @@ endif PSP_EBOOT_TITLE=SRB2-PSP vME PSP_EBOOT_SFO=$(BIN)/PARAM.SFO - PSP_EBOOT_ICON=sdl/SRB2PSP/ICON0.png + PSP_EBOOT_ICON=sdl12/SRB2PSP/ICON0.png PSP_EBOOT_ICON1=NULL PSP_EBOOT_UNKPNG=NULL - PSP_EBOOT_PIC1=sdl/SRB2PSP/PIC1.png + PSP_EBOOT_PIC1=sdl12/SRB2PSP/PIC1.png PSP_EBOOT_SND0=NULL PSP_EBOOT_PSAR=NULL - SIGNER?=sdl/SRB2PSP/psp-prxsign/psp-prxsign + SIGNER?=sdl12/SRB2PSP/psp-prxsign/psp-prxsign SDL=1 PREFIX=psp @@ -100,8 +100,8 @@ kxploit: $(BIN)/$(EXENAME) $(PSP_EBOOT_SFO) $(PSP_EBOOT_ICON1) $(PSP_EBOOT_UNKPNG) $(PSP_EBOOT_PIC1) \ $(PSP_EBOOT_SND0) NULL $(PSP_EBOOT_PSAR) -sdl/SRB2PSP/psp-prxsign/psp-prxsign: - -$(MAKE) -C sdl/SRB2PSP/psp-prxsign CFLAGS=-pipe CC="$(HOSTCC)" +sdl12/SRB2PSP/psp-prxsign/psp-prxsign: + -$(MAKE) -C sdl12/SRB2PSP/psp-prxsign CFLAGS=-pipe CC="$(HOSTCC)" fix-up: $(BIN)/$(EXENAME) @echo Running psp-fixup-imports on $(EXENAME) diff --git a/src/sdl12/SRB2Pandora/Makefile.cfg b/src/sdl12/SRB2Pandora/Makefile.cfg index c7f0f8449..1f057a212 100644 --- a/src/sdl12/SRB2Pandora/Makefile.cfg +++ b/src/sdl12/SRB2Pandora/Makefile.cfg @@ -2,8 +2,8 @@ PNDNAME=SRB2.pnd PNDDIR=$(BIN)/pnd -ICON=sdl/SRB2Pandora/icon.png -PXML=sdl/SRB2Pandora/PXML.xml +ICON=sdl12/SRB2Pandora/icon.png +PXML=sdl12/SRB2Pandora/PXML.xml SED=sed CAT=cat diff --git a/src/sdl12/SRB2WII/Makefile.cfg b/src/sdl12/SRB2WII/Makefile.cfg index 1b1863042..778d2c3d6 100644 --- a/src/sdl12/SRB2WII/Makefile.cfg +++ b/src/sdl12/SRB2WII/Makefile.cfg @@ -16,8 +16,8 @@ EXENAME?=$(SRB2NAME).elf DBGNAME?=$(SRB2NAME).elf.debug DOLNAME?=$(SRB2NAME).dol -ICONPNG?=sdl/SRB2WII/icon.png -METAXML?=sdl/SRB2WII/meta.xml +ICONPNG?=sdl12/SRB2WII/icon.png +METAXML?=sdl12/SRB2WII/meta.xml APPDIR=apps/$(SRB2NAME) ZIPNAME=$(SRB2NAME).zip diff --git a/src/sounds.c b/src/sounds.c index 2c1c5f3af..d687714ac 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -486,7 +486,7 @@ void S_InitRuntimeSounds (void) { sfxenum_t i; INT32 value; - char soundname[7]; + char soundname[10]; for (i = sfx_freeslot0; i <= sfx_lastskinsoundslot; i++) { diff --git a/src/st_stuff.c b/src/st_stuff.c index 4515495af..ceef586a4 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -684,6 +684,8 @@ static inline void ST_drawRings(void) static void ST_drawLives(void) { const INT32 v_splitflag = (splitscreen && stplyr == &players[displayplayer] ? V_SPLITSCREEN : 0); + INT32 livescount; + boolean notgreyedout; if (!stplyr->skincolor) return; // Just joined a server, skin isn't loaded yet! @@ -723,66 +725,47 @@ static void ST_drawLives(void) V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS|v_splitflag, stlivex); // lives number - if ((netgame || multiplayer) && gametype == GT_COOP) + if ((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 3) { - switch (cv_cooplives.value) + INT32 i; + livescount = 0; + notgreyedout = (stplyr->lives > 0); + for (i = 0; i < MAXPLAYERS; i++) { - case 0: - V_DrawCharacter(hudinfo[HUD_LIVESNUM].x - 8, hudinfo[HUD_LIVESNUM].y + (v_splitflag ? -4 : 0), '\x16' | 0x80 | V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS|v_splitflag, false); - return; - case 3: - { - INT32 i, sum = 0; - boolean canrespawn = (stplyr->lives > 0); - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i]) - continue; + if (!playeringame[i]) + continue; - if (players[i].lives < 1) - continue; + if (players[i].lives < 1) + continue; - if (players[i].lives > 1) - canrespawn = true; + if (players[i].lives > 1) + notgreyedout = true; - sum += (players[i].lives); - } - V_DrawRightAlignedString(hudinfo[HUD_LIVESNUM].x, hudinfo[HUD_LIVESNUM].y + (v_splitflag ? -4 : 0), - V_SNAPTOLEFT|V_SNAPTOBOTTOM|(canrespawn ? V_HUDTRANS : V_HUDTRANSHALF)|v_splitflag, - va("%d",sum)); - return; - } -#if 0 // render the number of lives you COULD steal - case 2: - { - INT32 i, sum = 0; - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i]) - continue; - - if (&players[i] == stplyr) - continue; - - if (players[i].lives < 2) - continue; - - sum += (players[i].lives - 1); - } - V_DrawString(hudinfo[HUD_LIVESNUM].x, hudinfo[HUD_LIVESNUM].y + (v_splitflag ? -4 : 0), - V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANSHALF|v_splitflag, va("/%d",sum)); - } - // intentional fallthrough -#endif - default: - // don't return so the SP one can be drawn below + if (players[i].lives == 0x7f) + { + livescount = 0x7f; break; + } + else if (livescount < 99) + livescount += (players[i].lives); } } + else + { + livescount = stplyr->lives; + notgreyedout = true; + } - V_DrawRightAlignedString(hudinfo[HUD_LIVESNUM].x, hudinfo[HUD_LIVESNUM].y + (v_splitflag ? -4 : 0), - V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS|v_splitflag, - va("%d",stplyr->lives)); + if (livescount == 0x7f) + V_DrawCharacter(hudinfo[HUD_LIVESNUM].x - 8, hudinfo[HUD_LIVESNUM].y + (v_splitflag ? -4 : 0), '\x16' | 0x80 | V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS|v_splitflag, false); + else + { + if (livescount > 99) + livescount = 99; + V_DrawRightAlignedString(hudinfo[HUD_LIVESNUM].x, hudinfo[HUD_LIVESNUM].y + (v_splitflag ? -4 : 0), + V_SNAPTOLEFT|V_SNAPTOBOTTOM|(notgreyedout ? V_HUDTRANS : V_HUDTRANSHALF)|v_splitflag, + ((livescount > 99) ? "!!" : va("%d",livescount))); + } } static void ST_drawLevelTitle(void) diff --git a/src/v_video.c b/src/v_video.c index 6ac101f2d..fa366eb65 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -524,12 +524,21 @@ static inline UINT8 transmappedpdraw(const UINT8 *dest, const UINT8 *source, fix { return *(v_translevel + (((*(v_colormap + source[ofs>>FRACBITS]))<<8)&0xff00) + (*dest&0xff)); } + +static UINT8 staticstep = 0; +static fixed_t staticval = 0; + static inline UINT8 staticpdraw(const UINT8 *dest, const UINT8 *source, fixed_t ofs) { UINT8 val = source[ofs>>FRACBITS]; (void)dest; + if ((++staticstep) >= 4) + { + staticstep = 0; + staticval = M_RandomFixed(); + } if (val < 7) return val; - return M_RandomKey(7+1)+(val-7);//M_RandomByte(); + return ((staticval>>staticstep)&7)+(val-7); } // Draws a patch scaled to arbitrary size. @@ -660,30 +669,10 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t y = FixedMul(y,dupy<>= FRACBITS; y >>= FRACBITS; - desttop += (y*vid.width) + x; // Center it if necessary if (!(scrn & V_SCALEPATCHMASK)) { - if (vid.width != BASEVIDWIDTH * dupx) - { - // dupx adjustments pretend that screen width is BASEVIDWIDTH * dupx, - // so center this imaginary screen - if (scrn & V_SNAPTORIGHT) - desttop += (vid.width - (BASEVIDWIDTH * dupx)); - else if (!(scrn & V_SNAPTOLEFT)) - desttop += (vid.width - (BASEVIDWIDTH * dupx)) / 2; - } - if (vid.height != BASEVIDHEIGHT * dupy) - { - // same thing here - if ((scrn & (V_SPLITSCREEN|V_SNAPTOBOTTOM)) == (V_SPLITSCREEN|V_SNAPTOBOTTOM)) - desttop += (vid.height/2 - (BASEVIDHEIGHT/2 * dupy)) * vid.width; - else if (scrn & V_SNAPTOBOTTOM) - desttop += (vid.height - (BASEVIDHEIGHT * dupy)) * vid.width; - else if (!(scrn & V_SNAPTOTOP)) - desttop += (vid.height - (BASEVIDHEIGHT * dupy)) * vid.width / 2; - } // if it's meant to cover the whole screen, black out the rest if (x == 0 && SHORT(patch->width) == BASEVIDWIDTH && y == 0 && SHORT(patch->height) == BASEVIDHEIGHT) { @@ -691,7 +680,29 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t source = (const UINT8 *)(column) + 3; V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0])); } + + if (vid.width != BASEVIDWIDTH * dupx) + { + // dupx adjustments pretend that screen width is BASEVIDWIDTH * dupx, + // so center this imaginary screen + if (scrn & V_SNAPTORIGHT) + x += (vid.width - (BASEVIDWIDTH * dupx)); + else if (!(scrn & V_SNAPTOLEFT)) + x += (vid.width - (BASEVIDWIDTH * dupx)) / 2; + } + if (vid.height != BASEVIDHEIGHT * dupy) + { + // same thing here + if ((scrn & (V_SPLITSCREEN|V_SNAPTOBOTTOM)) == (V_SPLITSCREEN|V_SNAPTOBOTTOM)) + y += (vid.height/2 - (BASEVIDHEIGHT/2 * dupy)); + else if (scrn & V_SNAPTOBOTTOM) + y += (vid.height - (BASEVIDHEIGHT * dupy)); + else if (!(scrn & V_SNAPTOTOP)) + y += (vid.height - (BASEVIDHEIGHT * dupy)) / 2; + } } + + desttop += (y*vid.width) + x; } if (pscale != FRACUNIT) // scale width properly @@ -797,28 +808,10 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_ y = FixedMul(y,dupy<>= FRACBITS; y >>= FRACBITS; - desttop += (y*vid.width) + x; // Center it if necessary if (!(scrn & V_SCALEPATCHMASK)) { - if (vid.width != BASEVIDWIDTH * dupx) - { - // dupx adjustments pretend that screen width is BASEVIDWIDTH * dupx, - // so center this imaginary screen - if (scrn & V_SNAPTORIGHT) - desttop += (vid.width - (BASEVIDWIDTH * dupx)); - else if (!(scrn & V_SNAPTOLEFT)) - desttop += (vid.width - (BASEVIDWIDTH * dupx)) / 2; - } - if (vid.height != BASEVIDHEIGHT * dupy) - { - // same thing here - if (scrn & V_SNAPTOBOTTOM) - desttop += (vid.height - (BASEVIDHEIGHT * dupy)) * vid.width; - else if (!(scrn & V_SNAPTOTOP)) - desttop += (vid.height - (BASEVIDHEIGHT * dupy)) * vid.width / 2; - } // if it's meant to cover the whole screen, black out the rest if (x == 0 && SHORT(patch->width) == BASEVIDWIDTH && y == 0 && SHORT(patch->height) == BASEVIDHEIGHT) { @@ -826,7 +819,29 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_ source = (const UINT8 *)(column) + 3; V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0])); } + + if (vid.width != BASEVIDWIDTH * dupx) + { + // dupx adjustments pretend that screen width is BASEVIDWIDTH * dupx, + // so center this imaginary screen + if (scrn & V_SNAPTORIGHT) + x += (vid.width - (BASEVIDWIDTH * dupx)); + else if (!(scrn & V_SNAPTOLEFT)) + x += (vid.width - (BASEVIDWIDTH * dupx)) / 2; + } + if (vid.height != BASEVIDHEIGHT * dupy) + { + // same thing here + if ((scrn & (V_SPLITSCREEN|V_SNAPTOBOTTOM)) == (V_SPLITSCREEN|V_SNAPTOBOTTOM)) + y += (vid.height/2 - (BASEVIDHEIGHT/2 * dupy)); + else if (scrn & V_SNAPTOBOTTOM) + y += (vid.height - (BASEVIDHEIGHT * dupy)); + else if (!(scrn & V_SNAPTOTOP)) + y += (vid.height - (BASEVIDHEIGHT * dupy)) / 2; + } } + + desttop += (y*vid.width) + x; } for (col = sx<>FRACBITS) < SHORT(patch->width) && (col>>FRACBITS) < w; col += colfrac, ++x, desttop++) @@ -1293,6 +1308,7 @@ char *V_WordWrap(INT32 x, INT32 w, INT32 option, const char *string) { case V_MONOSPACE: spacewidth = 8; + /* FALLTHRU */ case V_OLDSPACING: charwidth = 8; break; @@ -1346,7 +1362,7 @@ char *V_WordWrap(INT32 x, INT32 w, INT32 option, const char *string) // void V_DrawString(INT32 x, INT32 y, INT32 option, const char *string) { - INT32 w, c, cx = x, cy = y, dupx, dupy, scrwidth = BASEVIDWIDTH, center = 0; + INT32 w, c, cx = x, cy = y, dupx, dupy, scrwidth, center = 0, left = 0; const char *ch = string; INT32 charflags = 0; const UINT8 *colormap = NULL; @@ -1362,7 +1378,11 @@ void V_DrawString(INT32 x, INT32 y, INT32 option, const char *string) scrwidth = vid.width; } else + { dupx = dupy = 1; + scrwidth = vid.width/vid.dupx; + left = (scrwidth - BASEVIDWIDTH)/2; + } charflags = (option & V_CHARCOLORMASK); @@ -1370,6 +1390,7 @@ void V_DrawString(INT32 x, INT32 y, INT32 option, const char *string) { case V_MONOSPACE: spacewidth = 8; + /* FALLTHRU */ case V_OLDSPACING: charwidth = 8; break; @@ -1422,9 +1443,9 @@ void V_DrawString(INT32 x, INT32 y, INT32 option, const char *string) else w = SHORT(hu_font[c]->width) * dupx; - if (cx + w > scrwidth) + if (cx+left > scrwidth) break; - if (cx < 0) //left boundary check + if (cx+left + w < 0) //left boundary check { cx += w; continue; @@ -1455,7 +1476,7 @@ void V_DrawRightAlignedString(INT32 x, INT32 y, INT32 option, const char *string // void V_DrawSmallString(INT32 x, INT32 y, INT32 option, const char *string) { - INT32 w, c, cx = x, cy = y, dupx, dupy, scrwidth = BASEVIDWIDTH, center = 0; + INT32 w, c, cx = x, cy = y, dupx, dupy, scrwidth, center = 0, left = 0; const char *ch = string; INT32 charflags = 0; const UINT8 *colormap = NULL; @@ -1471,7 +1492,11 @@ void V_DrawSmallString(INT32 x, INT32 y, INT32 option, const char *string) scrwidth = vid.width; } else + { dupx = dupy = 1; + scrwidth = vid.width/vid.dupx; + left = (scrwidth - BASEVIDWIDTH)/2; + } charflags = (option & V_CHARCOLORMASK); @@ -1479,6 +1504,7 @@ void V_DrawSmallString(INT32 x, INT32 y, INT32 option, const char *string) { case V_MONOSPACE: spacewidth = 4; + /* FALLTHRU */ case V_OLDSPACING: charwidth = 4; break; @@ -1529,9 +1555,9 @@ void V_DrawSmallString(INT32 x, INT32 y, INT32 option, const char *string) } else w = SHORT(hu_font[c]->width) * dupx / 2; - if (cx + w > scrwidth) + if (cx+left > scrwidth) break; - if (cx < 0) //left boundary check + if (cx+left + w < 0) //left boundary check { cx += w; continue; @@ -1556,7 +1582,7 @@ void V_DrawRightAlignedSmallString(INT32 x, INT32 y, INT32 option, const char *s // void V_DrawThinString(INT32 x, INT32 y, INT32 option, const char *string) { - INT32 w, c, cx = x, cy = y, dupx, dupy, scrwidth = BASEVIDWIDTH; + INT32 w, c, cx = x, cy = y, dupx, dupy, scrwidth, left = 0; const char *ch = string; INT32 charflags = 0; const UINT8 *colormap = NULL; @@ -1572,7 +1598,11 @@ void V_DrawThinString(INT32 x, INT32 y, INT32 option, const char *string) scrwidth = vid.width; } else + { dupx = dupy = 1; + scrwidth = vid.width/vid.dupx; + left = (scrwidth - BASEVIDWIDTH)/2; + } charflags = (option & V_CHARCOLORMASK); @@ -1580,6 +1610,7 @@ void V_DrawThinString(INT32 x, INT32 y, INT32 option, const char *string) { case V_MONOSPACE: spacewidth = 5; + /* FALLTHRU */ case V_OLDSPACING: charwidth = 5; break; @@ -1628,9 +1659,9 @@ void V_DrawThinString(INT32 x, INT32 y, INT32 option, const char *string) else w = (SHORT(tny_font[c]->width) * dupx); - if (cx + w > scrwidth) + if (cx+left > scrwidth) break; - if (cx < 0) //left boundary check + if (cx+left + w < 0) //left boundary check { cx += w; continue; @@ -1653,7 +1684,7 @@ void V_DrawRightAlignedThinString(INT32 x, INT32 y, INT32 option, const char *st void V_DrawStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string) { fixed_t cx = x, cy = y; - INT32 w, c, dupx, dupy, scrwidth = BASEVIDWIDTH, center = 0; + INT32 w, c, dupx, dupy, scrwidth, center = 0, left = 0; const char *ch = string; INT32 spacewidth = 4, charwidth = 0; @@ -1667,12 +1698,17 @@ void V_DrawStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string) scrwidth = vid.width; } else + { dupx = dupy = 1; + scrwidth = vid.width/vid.dupx; + left = (scrwidth - BASEVIDWIDTH)/2; + } switch (option & V_SPACINGMASK) { case V_MONOSPACE: spacewidth = 8; + /* FALLTHRU */ case V_OLDSPACING: charwidth = 8; break; @@ -1720,9 +1756,9 @@ void V_DrawStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string) else w = SHORT(hu_font[c]->width) * dupx; - if ((cx>>FRACBITS) + w > scrwidth) + if ((cx>>FRACBITS)+left > scrwidth) break; - if (cx < 0) //left boundary check + if (cx+left + w < 0) //left boundary check { cx += w< 1 ? "s" : ""); } @@ -1163,6 +1164,7 @@ void Y_StartIntermission(void) // fall back into the special stage intermission for now intertype = int_spec; + /* FALLTHRU */ case int_spec: // coop or single player, special stage { // Update visitation flags? @@ -1170,7 +1172,7 @@ void Y_StartIntermission(void) { if (!stagefailed) mapvisited[gamemap-1] |= MV_BEATEN; - + // all emeralds/ultimate/perfect emblems won't be possible in ss, oh well? if (completionEmblems) CONS_Printf(M_GetText("\x82" "Earned %hu emblem%s for level completion.\n"), (UINT16)completionEmblems, completionEmblems > 1 ? "s" : "");