mirror of
https://github.com/ZDoom/qzdoom.git
synced 2025-03-15 23:40:52 +00:00
Merge branch 'master' of https://github.com/coelckers/gzdoom
# Conflicts: # src/swrenderer/line/r_walldraw.cpp # src/version.h
This commit is contained in:
commit
0f2fd5c4c9
305 changed files with 10892 additions and 10730 deletions
|
@ -33,7 +33,7 @@ build_script:
|
|||
- md build
|
||||
- cd build
|
||||
- cmake -G "%GENERATOR%" -T "%TOOLSET%" -DPK3_QUIET_ZIPDIR=YES ..
|
||||
- cmake --build . --config "%CONFIGURATION%" -- /verbosity:minimal
|
||||
- cmake --build . --config "%CONFIGURATION%" -- -maxcpucount -verbosity:minimal
|
||||
|
||||
after_build:
|
||||
- set OUTPUT_DIR=%APPVEYOR_BUILD_FOLDER%\build\%CONFIGURATION%\
|
||||
|
|
21
.travis.yml
21
.travis.yml
|
@ -1,5 +1,5 @@
|
|||
language: c++
|
||||
dist: trusty
|
||||
language: cpp
|
||||
dist: xenial
|
||||
|
||||
branches:
|
||||
except:
|
||||
|
@ -27,8 +27,6 @@ matrix:
|
|||
- CMAKE_OPTIONS="-DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS=-Wno-maybe-uninitialized"
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- g++-4.9
|
||||
- libsdl2-dev
|
||||
|
@ -41,8 +39,6 @@ matrix:
|
|||
- CMAKE_OPTIONS="-DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS=-Wno-maybe-uninitialized"
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- g++-5
|
||||
- libsdl2-dev
|
||||
|
@ -99,7 +95,7 @@ matrix:
|
|||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-trusty-7
|
||||
- llvm-toolchain-xenial-7
|
||||
packages:
|
||||
- clang-7
|
||||
- libsdl2-dev
|
||||
|
@ -110,6 +106,14 @@ matrix:
|
|||
- libfluidsynth-dev
|
||||
- libgtk-3-dev
|
||||
|
||||
- os: windows
|
||||
env:
|
||||
- CMAKE_OPTIONS="-A Win32"
|
||||
|
||||
- os: windows
|
||||
env:
|
||||
- CMAKE_OPTIONS="-A x64"
|
||||
|
||||
before_install:
|
||||
- if [ -n "$GCC_VERSION" ]; then export CC="gcc-${GCC_VERSION}" CXX="g++-${GCC_VERSION}"; fi
|
||||
- if [ -n "$CLANG_VERSION" ]; then export CC="clang-${CLANG_VERSION}" CXX="clang++-${CLANG_VERSION}"; fi
|
||||
|
@ -128,7 +132,8 @@ script:
|
|||
-DFORCE_INTERNAL_GME=YES \
|
||||
-DPK3_QUIET_ZIPDIR=YES \
|
||||
..
|
||||
- make -j2 -k
|
||||
- if [[ $TRAVIS_OS_NAME == 'windows' ]]; then cmake --build . --config Release -- -maxcpucount -verbosity:minimal; fi
|
||||
- if [[ $TRAVIS_OS_NAME != 'windows' ]]; then cmake --build . -- --jobs=2 --keep-going; fi
|
||||
|
||||
notifications:
|
||||
email: false
|
||||
|
|
|
@ -163,14 +163,29 @@ option( NO_OPENAL "Disable OpenAL sound support" OFF )
|
|||
find_package( BZip2 )
|
||||
find_package( JPEG )
|
||||
find_package( ZLIB )
|
||||
find_package( asmjit )
|
||||
|
||||
include( TargetArch )
|
||||
|
||||
target_architecture(ZDOOM_TARGET_ARCH)
|
||||
|
||||
if( ${ZDOOM_TARGET_ARCH} MATCHES "x86_64" )
|
||||
set( HAVE_VM_JIT ON )
|
||||
endif()
|
||||
|
||||
# no, we're not using external asmjit for now, we made too many modifications to our's.
|
||||
# if the asmjit author uses our changes then we'll update this.
|
||||
|
||||
#if( ${HAVE_VM_JIT} )
|
||||
# find_package( asmjit )
|
||||
#endif()
|
||||
|
||||
# GME
|
||||
find_path( GME_INCLUDE_DIR gme/gme.h )
|
||||
find_library( GME_LIBRARIES gme )
|
||||
mark_as_advanced( GME_INCLUDE_DIR GME_LIBRARIES )
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS( GME
|
||||
REQUIRED_VARS GME_LIBRARIES GME_INCLUDE_DIR
|
||||
)
|
||||
#find_path( GME_INCLUDE_DIR gme/gme.h )
|
||||
#find_library( GME_LIBRARIES gme )
|
||||
#mark_as_advanced( GME_INCLUDE_DIR GME_LIBRARIES )
|
||||
#FIND_PACKAGE_HANDLE_STANDARD_ARGS( GME
|
||||
# REQUIRED_VARS GME_LIBRARIES GME_INCLUDE_DIR
|
||||
#)
|
||||
|
||||
if( MSVC )
|
||||
# Eliminate unreferenced functions and data
|
||||
|
@ -222,6 +237,7 @@ if( MSVC )
|
|||
string(REPLACE "/MD " " " CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE} )
|
||||
string(REPLACE "/MD " " " CMAKE_CXX_FLAGS_MINSIZEREL ${CMAKE_CXX_FLAGS_MINSIZEREL} )
|
||||
string(REPLACE "/MD " " " CMAKE_CXX_FLAGS_RELWITHDEBINFO ${CMAKE_CXX_FLAGS_RELWITHDEBINFO} )
|
||||
string(REPLACE "/Ob1 " "/Ob2 " CMAKE_CXX_FLAGS_RELWITHDEBINFO ${CMAKE_CXX_FLAGS_RELWITHDEBINFO} )
|
||||
string(REPLACE "/MDd " " " CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG} )
|
||||
string(REPLACE "/MD " " " CMAKE_C_FLAGS_RELEASE ${CMAKE_C_FLAGS_RELEASE} )
|
||||
string(REPLACE "/MD " " " CMAKE_C_FLAGS_MINSIZEREL ${CMAKE_C_FLAGS_MINSIZEREL} )
|
||||
|
@ -271,8 +287,10 @@ set( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${DEB_C_FLAGS} -D_DEBUG" )
|
|||
option(FORCE_INTERNAL_ZLIB "Use internal zlib")
|
||||
option(FORCE_INTERNAL_JPEG "Use internal jpeg")
|
||||
option(FORCE_INTERNAL_BZIP2 "Use internal bzip2")
|
||||
option(FORCE_INTERNAL_GME "Use internal gme")
|
||||
option(FORCE_INTERNAL_ASMJIT "Use internal asmjit")
|
||||
option(FORCE_INTERNAL_GME "Use internal gme" ON)
|
||||
mark_as_advanced( FORCE_INTERNAL_GME )
|
||||
option(FORCE_INTERNAL_ASMJIT "Use internal asmjit" ON)
|
||||
mark_as_advanced( FORCE_INTERNAL_ASMJIT )
|
||||
|
||||
# Fast math flags, required by some subprojects
|
||||
set( ZD_FASTMATH_FLAG "" )
|
||||
|
@ -293,15 +311,17 @@ else()
|
|||
set( ZLIB_LIBRARY z )
|
||||
endif()
|
||||
|
||||
if( ASMJIT_FOUND AND NOT FORCE_INTERNAL_ASMJIT )
|
||||
message( STATUS "Using system asmjit, includes found at ${ASMJIT_INCLUDE_DIR}" )
|
||||
else()
|
||||
message( STATUS "Using internal asmjit" )
|
||||
set( SKIP_INSTALL_ALL TRUE ) # Avoid installing asmjit alongside zdoom
|
||||
add_subdirectory( asmjit )
|
||||
set( ASMJIT_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/asmjit )
|
||||
set( ASMJIT_LIBRARIES asmjit )
|
||||
set( ASMJIT_LIBRARY asmjit )
|
||||
if( ${HAVE_VM_JIT} )
|
||||
if( ASMJIT_FOUND AND NOT FORCE_INTERNAL_ASMJIT )
|
||||
message( STATUS "Using system asmjit, includes found at ${ASMJIT_INCLUDE_DIR}" )
|
||||
else()
|
||||
message( STATUS "Using internal asmjit" )
|
||||
set( SKIP_INSTALL_ALL TRUE ) # Avoid installing asmjit alongside zdoom
|
||||
add_subdirectory( asmjit )
|
||||
set( ASMJIT_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/asmjit )
|
||||
set( ASMJIT_LIBRARIES asmjit )
|
||||
set( ASMJIT_LIBRARY asmjit )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if( JPEG_FOUND AND NOT FORCE_INTERNAL_JPEG )
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Game_Music_Emu https://bitbucket.org/mpyne/game-music-emu/
|
||||
// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/
|
||||
|
||||
/*
|
||||
Last validated with zexall 2006.11.14 2:19 PM
|
||||
|
@ -162,6 +162,11 @@ static byte const ed_dd_timing [0x100] = {
|
|||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
};
|
||||
|
||||
// even on x86, using short and unsigned char was slower
|
||||
typedef int fint16;
|
||||
typedef unsigned fuint16;
|
||||
typedef unsigned fuint8;
|
||||
|
||||
bool Kss_Cpu::run( cpu_time_t end_time )
|
||||
{
|
||||
set_end_time( end_time );
|
||||
|
@ -178,10 +183,10 @@ bool Kss_Cpu::run( cpu_time_t end_time )
|
|||
rg = this->r.b;
|
||||
|
||||
cpu_time_t s_time = s.time;
|
||||
uint16_t pc = r.pc;
|
||||
uint16_t sp = r.sp;
|
||||
uint16_t ix = r.ix; // TODO: keep in memory for direct access?
|
||||
uint16_t iy = r.iy;
|
||||
fuint16 pc = r.pc;
|
||||
fuint16 sp = r.sp;
|
||||
fuint16 ix = r.ix; // TODO: keep in memory for direct access?
|
||||
fuint16 iy = r.iy;
|
||||
int flags = r.b.flags;
|
||||
|
||||
goto loop;
|
||||
|
@ -203,7 +208,7 @@ loop:
|
|||
uint8_t const* instr = s.read [pc >> page_shift];
|
||||
#define GET_ADDR() GET_LE16( instr )
|
||||
|
||||
uint8_t opcode;
|
||||
fuint8 opcode;
|
||||
|
||||
// TODO: eliminate this special case
|
||||
#if BLARGG_NONPORTABLE
|
||||
|
@ -236,7 +241,7 @@ loop:
|
|||
11,10,10, 4,17,11, 7,11,11, 6,10, 4,17, 8, 7,11, // F
|
||||
};
|
||||
|
||||
uint16_t data;
|
||||
fuint16 data;
|
||||
data = base_timing [opcode];
|
||||
if ( (s_time += data) >= 0 )
|
||||
goto possibly_out_of_time;
|
||||
|
@ -292,7 +297,7 @@ possibly_out_of_time:
|
|||
goto loop;
|
||||
|
||||
case 0x3A:{// LD A,(addr)
|
||||
uint16_t addr = GET_ADDR();
|
||||
fuint16 addr = GET_ADDR();
|
||||
pc += 2;
|
||||
rg.a = READ( addr );
|
||||
goto loop;
|
||||
|
@ -380,7 +385,7 @@ possibly_out_of_time:
|
|||
|
||||
case 0xCD:{// CALL addr
|
||||
call_taken:
|
||||
uint16_t addr = pc + 2;
|
||||
fuint16 addr = pc + 2;
|
||||
pc = GET_ADDR();
|
||||
sp = uint16_t (sp - 2);
|
||||
WRITE_WORD( sp, addr );
|
||||
|
@ -388,7 +393,7 @@ possibly_out_of_time:
|
|||
}
|
||||
|
||||
case 0xFF: // RST
|
||||
if ( pc >= idle_addr )
|
||||
if ( pc > idle_addr )
|
||||
goto hit_idle_addr;
|
||||
CASE7( C7, CF, D7, DF, E7, EF, F7 ):
|
||||
data = pc;
|
||||
|
@ -496,7 +501,7 @@ possibly_out_of_time:
|
|||
add_hl_data: {
|
||||
blargg_ulong sum = rp.hl + data;
|
||||
data ^= rp.hl;
|
||||
rp.hl = sum;
|
||||
rp.hl = (uint16_t)sum;
|
||||
flags = (flags & (S80 | Z40 | V04)) |
|
||||
(sum >> 16) |
|
||||
(sum >> 8 & (F20 | F08)) |
|
||||
|
@ -686,21 +691,21 @@ possibly_out_of_time:
|
|||
goto loop;
|
||||
|
||||
case 0x2A:{// LD HL,(addr)
|
||||
uint16_t addr = GET_ADDR();
|
||||
fuint16 addr = GET_ADDR();
|
||||
pc += 2;
|
||||
rp.hl = READ_WORD( addr );
|
||||
goto loop;
|
||||
}
|
||||
|
||||
case 0x32:{// LD (addr),A
|
||||
uint16_t addr = GET_ADDR();
|
||||
fuint16 addr = GET_ADDR();
|
||||
pc += 2;
|
||||
WRITE( addr, rg.a );
|
||||
goto loop;
|
||||
}
|
||||
|
||||
case 0x22:{// LD (addr),HL
|
||||
uint16_t addr = GET_ADDR();
|
||||
fuint16 addr = GET_ADDR();
|
||||
pc += 2;
|
||||
WRITE_WORD( addr, rp.hl );
|
||||
goto loop;
|
||||
|
@ -723,7 +728,7 @@ possibly_out_of_time:
|
|||
// Rotate
|
||||
|
||||
case 0x07:{// RLCA
|
||||
uint16_t temp = rg.a;
|
||||
fuint16 temp = rg.a;
|
||||
temp = (temp << 1) | (temp >> 7);
|
||||
flags = (flags & (S80 | Z40 | P04)) |
|
||||
(temp & (F20 | F08 | C01));
|
||||
|
@ -732,7 +737,7 @@ possibly_out_of_time:
|
|||
}
|
||||
|
||||
case 0x0F:{// RRCA
|
||||
uint16_t temp = rg.a;
|
||||
fuint16 temp = rg.a;
|
||||
flags = (flags & (S80 | Z40 | P04)) |
|
||||
(temp & C01);
|
||||
temp = (temp << 7) | (temp >> 1);
|
||||
|
@ -746,12 +751,12 @@ possibly_out_of_time:
|
|||
flags = (flags & (S80 | Z40 | P04)) |
|
||||
(temp & (F20 | F08)) |
|
||||
(temp >> 8);
|
||||
rg.a = temp;
|
||||
rg.a = (uint8_t)temp;
|
||||
goto loop;
|
||||
}
|
||||
|
||||
case 0x1F:{// RRA
|
||||
uint16_t temp = (flags << 7) | (rg.a >> 1);
|
||||
fuint16 temp = (flags << 7) | (rg.a >> 1);
|
||||
flags = (flags & (S80 | Z40 | P04)) |
|
||||
(temp & (F20 | F08)) |
|
||||
(rg.a & C01);
|
||||
|
@ -761,7 +766,7 @@ possibly_out_of_time:
|
|||
|
||||
// Misc
|
||||
case 0x2F:{// CPL
|
||||
uint16_t temp = ~rg.a;
|
||||
fuint16 temp = ~rg.a;
|
||||
flags = (flags & (S80 | Z40 | P04 | C01)) |
|
||||
(temp & (F20 | F08)) |
|
||||
(H10 | N02);
|
||||
|
@ -787,21 +792,21 @@ possibly_out_of_time:
|
|||
goto loop;
|
||||
|
||||
case 0xE3:{// EX (SP),HL
|
||||
uint16_t temp = READ_WORD( sp );
|
||||
fuint16 temp = READ_WORD( sp );
|
||||
WRITE_WORD( sp, rp.hl );
|
||||
rp.hl = temp;
|
||||
goto loop;
|
||||
}
|
||||
|
||||
case 0xEB:{// EX DE,HL
|
||||
uint16_t temp = rp.hl;
|
||||
fuint16 temp = rp.hl;
|
||||
rp.hl = rp.de;
|
||||
rp.de = temp;
|
||||
goto loop;
|
||||
}
|
||||
|
||||
case 0xD9:{// EXX DE,HL
|
||||
uint16_t temp = r.alt.w.bc;
|
||||
fuint16 temp = r.alt.w.bc;
|
||||
r.alt.w.bc = rp.bc;
|
||||
rp.bc = temp;
|
||||
|
||||
|
@ -842,7 +847,7 @@ possibly_out_of_time:
|
|||
// Rotate left
|
||||
|
||||
#define RLC( read, write ) {\
|
||||
uint8_t result = read;\
|
||||
fuint8 result = read;\
|
||||
result = uint8_t (result << 1) | (result >> 7);\
|
||||
flags = SZ28P( result ) | (result & C01);\
|
||||
write;\
|
||||
|
@ -861,7 +866,7 @@ possibly_out_of_time:
|
|||
}
|
||||
|
||||
#define RL( read, write ) {\
|
||||
uint16_t result = (read << 1) | (flags & C01);\
|
||||
fuint16 result = (read << 1) | (flags & C01);\
|
||||
flags = SZ28PC( result );\
|
||||
write;\
|
||||
goto loop;\
|
||||
|
@ -879,7 +884,7 @@ possibly_out_of_time:
|
|||
}
|
||||
|
||||
#define SLA( read, add, write ) {\
|
||||
uint16_t result = (read << 1) | add;\
|
||||
fuint16 result = (read << 1) | add;\
|
||||
flags = SZ28PC( result );\
|
||||
write;\
|
||||
goto loop;\
|
||||
|
@ -910,7 +915,7 @@ possibly_out_of_time:
|
|||
// Rotate right
|
||||
|
||||
#define RRC( read, write ) {\
|
||||
uint8_t result = read;\
|
||||
fuint8 result = read;\
|
||||
flags = result & C01;\
|
||||
result = uint8_t (result << 7) | (result >> 1);\
|
||||
flags |= SZ28P( result );\
|
||||
|
@ -930,8 +935,8 @@ possibly_out_of_time:
|
|||
}
|
||||
|
||||
#define RR( read, write ) {\
|
||||
uint8_t result = read;\
|
||||
uint8_t temp = result & C01;\
|
||||
fuint8 result = read;\
|
||||
fuint8 temp = result & C01;\
|
||||
result = uint8_t (flags << 7) | (result >> 1);\
|
||||
flags = SZ28P( result ) | temp;\
|
||||
write;\
|
||||
|
@ -950,7 +955,7 @@ possibly_out_of_time:
|
|||
}
|
||||
|
||||
#define SRA( read, write ) {\
|
||||
uint8_t result = read;\
|
||||
fuint8 result = read;\
|
||||
flags = result & C01;\
|
||||
result = (result & 0x80) | (result >> 1);\
|
||||
flags |= SZ28P( result );\
|
||||
|
@ -970,7 +975,7 @@ possibly_out_of_time:
|
|||
}
|
||||
|
||||
#define SRL( read, write ) {\
|
||||
uint8_t result = read;\
|
||||
fuint8 result = read;\
|
||||
flags = result & C01;\
|
||||
result >>= 1;\
|
||||
flags |= SZ28P( result );\
|
||||
|
@ -1078,7 +1083,7 @@ possibly_out_of_time:
|
|||
blargg_ulong sum = temp + (flags & C01);
|
||||
flags = ~data >> 2 & N02;
|
||||
if ( flags )
|
||||
sum = -sum;
|
||||
sum = (blargg_ulong)-(blargg_long)sum;
|
||||
sum += rp.hl;
|
||||
temp ^= rp.hl;
|
||||
temp ^= sum;
|
||||
|
@ -1086,7 +1091,7 @@ possibly_out_of_time:
|
|||
(temp >> 8 & H10) |
|
||||
(sum >> 8 & (S80 | F20 | F08)) |
|
||||
((temp - -0x8000) >> 14 & V04);
|
||||
rp.hl = sum;
|
||||
rp.hl = (uint16_t)sum;
|
||||
if ( (uint16_t) sum )
|
||||
goto loop;
|
||||
flags |= Z40;
|
||||
|
@ -1114,7 +1119,7 @@ possibly_out_of_time:
|
|||
case 0x43: // LD (ADDR),BC
|
||||
case 0x53: // LD (ADDR),DE
|
||||
temp = R16( data, 4, 0x43 );
|
||||
uint16_t addr = GET_ADDR();
|
||||
fuint16 addr = GET_ADDR();
|
||||
pc += 2;
|
||||
WRITE_WORD( addr, temp );
|
||||
goto loop;
|
||||
|
@ -1122,21 +1127,21 @@ possibly_out_of_time:
|
|||
|
||||
case 0x4B: // LD BC,(ADDR)
|
||||
case 0x5B:{// LD DE,(ADDR)
|
||||
uint16_t addr = GET_ADDR();
|
||||
fuint16 addr = GET_ADDR();
|
||||
pc += 2;
|
||||
R16( data, 4, 0x4B ) = READ_WORD( addr );
|
||||
goto loop;
|
||||
}
|
||||
|
||||
case 0x7B:{// LD SP,(ADDR)
|
||||
uint16_t addr = GET_ADDR();
|
||||
fuint16 addr = GET_ADDR();
|
||||
pc += 2;
|
||||
sp = READ_WORD( addr );
|
||||
goto loop;
|
||||
}
|
||||
|
||||
case 0x67:{// RRD
|
||||
uint8_t temp = READ( rp.hl );
|
||||
fuint8 temp = READ( rp.hl );
|
||||
WRITE( rp.hl, (rg.a << 4) | (temp >> 4) );
|
||||
temp = (rg.a & 0xF0) | (temp & 0x0F);
|
||||
flags = (flags & C01) | SZ28P( temp );
|
||||
|
@ -1145,7 +1150,7 @@ possibly_out_of_time:
|
|||
}
|
||||
|
||||
case 0x6F:{// RLD
|
||||
uint8_t temp = READ( rp.hl );
|
||||
fuint8 temp = READ( rp.hl );
|
||||
WRITE( rp.hl, (temp << 4) | (rg.a & 0x0F) );
|
||||
temp = (rg.a & 0xF0) | (temp >> 4);
|
||||
flags = (flags & C01) | SZ28P( temp );
|
||||
|
@ -1169,7 +1174,7 @@ possibly_out_of_time:
|
|||
case 0xA1: // CPI
|
||||
case 0xB1: // CPIR
|
||||
inc = +1;
|
||||
uint16_t addr = rp.hl;
|
||||
fuint16 addr = rp.hl;
|
||||
rp.hl = addr + inc;
|
||||
int temp = READ( addr );
|
||||
|
||||
|
@ -1202,7 +1207,7 @@ possibly_out_of_time:
|
|||
case 0xA0: // LDI
|
||||
case 0xB0: // LDIR
|
||||
inc = +1;
|
||||
uint16_t addr = rp.hl;
|
||||
fuint16 addr = rp.hl;
|
||||
rp.hl = addr + inc;
|
||||
int temp = READ( addr );
|
||||
|
||||
|
@ -1234,7 +1239,7 @@ possibly_out_of_time:
|
|||
case 0xA3: // OUTI
|
||||
case 0xB3: // OTIR
|
||||
inc = +1;
|
||||
uint16_t addr = rp.hl;
|
||||
fuint16 addr = rp.hl;
|
||||
rp.hl = addr + inc;
|
||||
int temp = READ( addr );
|
||||
|
||||
|
@ -1260,7 +1265,7 @@ possibly_out_of_time:
|
|||
case 0xB2: // INIR
|
||||
inc = +1;
|
||||
|
||||
uint16_t addr = rp.hl;
|
||||
fuint16 addr = rp.hl;
|
||||
rp.hl = addr + inc;
|
||||
|
||||
int temp = IN( rp.bc );
|
||||
|
@ -1325,7 +1330,7 @@ possibly_out_of_time:
|
|||
|
||||
//////////////////////////////////////// DD/FD prefix
|
||||
{
|
||||
uint16_t ixy;
|
||||
fuint16 ixy;
|
||||
case 0xDD:
|
||||
ixy = ix;
|
||||
goto ix_prefix;
|
||||
|
@ -1521,7 +1526,7 @@ possibly_out_of_time:
|
|||
goto loop;
|
||||
|
||||
case 0x22:{// LD (ADDR),IXY
|
||||
uint16_t addr = GET_ADDR();
|
||||
fuint16 addr = GET_ADDR();
|
||||
pc += 2;
|
||||
WRITE_WORD( addr, ixy );
|
||||
goto loop;
|
||||
|
@ -1533,7 +1538,7 @@ possibly_out_of_time:
|
|||
goto set_ixy;
|
||||
|
||||
case 0x2A:{// LD IXY,(addr)
|
||||
uint16_t addr = GET_ADDR();
|
||||
fuint16 addr = GET_ADDR();
|
||||
ixy = READ_WORD( addr );
|
||||
pc += 2;
|
||||
goto set_ixy;
|
||||
|
@ -1557,7 +1562,7 @@ possibly_out_of_time:
|
|||
case 0x3E: goto srl_data_addr; // SRL (IXY)
|
||||
|
||||
CASE8( 46, 4E, 56, 5E, 66, 6E, 76, 7E ):{// BIT b,(IXY+disp)
|
||||
uint8_t temp = READ( data );
|
||||
fuint8 temp = READ( data );
|
||||
int masked = temp & 1 << (data2 >> 3 & 7);
|
||||
flags = (flags & C01) | H10 |
|
||||
(masked & S80) |
|
||||
|
@ -1659,7 +1664,7 @@ possibly_out_of_time:
|
|||
goto loop;
|
||||
|
||||
case 0xE3:{// EX (SP),IXY
|
||||
uint16_t temp = READ_WORD( sp );
|
||||
fuint16 temp = READ_WORD( sp );
|
||||
WRITE_WORD( sp, ixy );
|
||||
ixy = temp;
|
||||
goto set_ixy;
|
||||
|
|
|
@ -299,11 +299,6 @@ blargg_err_t Spc_Emu::start_track_( int track )
|
|||
RETURN_ERR( apu.load_spc( file_data, file_size ) );
|
||||
filter.set_gain( (int) (gain() * SPC_Filter::gain_unit) );
|
||||
apu.clear_echo();
|
||||
track_info_t spc_info;
|
||||
RETURN_ERR( track_info_( &spc_info, track ) );
|
||||
// Set a default track length, need a non-zero fadeout
|
||||
if ( spc_info.length > 0 )
|
||||
set_fade ( spc_info.length, 50 );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* 7zArcIn.c -- 7z Input functions
|
||||
2017-04-03 : Igor Pavlov : Public domain */
|
||||
2018-07-04 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "Precomp.h"
|
||||
|
||||
|
@ -1744,7 +1744,7 @@ size_t SzArEx_GetFullNameLen(const CSzArEx *p, size_t fileIndex)
|
|||
|
||||
UInt16 *SzArEx_GetFullNameUtf16_Back(const CSzArEx *p, size_t fileIndex, UInt16 *dest)
|
||||
{
|
||||
Bool needSlash;
|
||||
BoolInt needSlash;
|
||||
if (!p->FileNameOffsets)
|
||||
{
|
||||
*(--dest) = 0;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* 7zDec.c -- Decoding from 7z folder
|
||||
2017-04-03 : Igor Pavlov : Public domain */
|
||||
2018-07-04 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "Precomp.h"
|
||||
|
||||
|
@ -44,7 +44,7 @@ typedef struct
|
|||
const Byte *end;
|
||||
const Byte *begin;
|
||||
UInt64 processed;
|
||||
Bool extra;
|
||||
BoolInt extra;
|
||||
SRes res;
|
||||
const ILookInStream *inStream;
|
||||
} CByteInToLook;
|
||||
|
@ -269,7 +269,7 @@ static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer
|
|||
return SZ_OK;
|
||||
}
|
||||
|
||||
static Bool IS_MAIN_METHOD(UInt32 m)
|
||||
static BoolInt IS_MAIN_METHOD(UInt32 m)
|
||||
{
|
||||
switch (m)
|
||||
{
|
||||
|
@ -286,7 +286,7 @@ static Bool IS_MAIN_METHOD(UInt32 m)
|
|||
return False;
|
||||
}
|
||||
|
||||
static Bool IS_SUPPORTED_CODER(const CSzCoderInfo *c)
|
||||
static BoolInt IS_SUPPORTED_CODER(const CSzCoderInfo *c)
|
||||
{
|
||||
return
|
||||
c->NumStreams == 1
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* 7zTypes.h -- Basic types
|
||||
2017-07-17 : Igor Pavlov : Public domain */
|
||||
2018-08-04 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __7Z_TYPES_H
|
||||
#define __7Z_TYPES_H
|
||||
|
@ -103,7 +103,8 @@ typedef UInt32 SizeT;
|
|||
typedef size_t SizeT;
|
||||
#endif
|
||||
|
||||
typedef int Bool;
|
||||
typedef int BoolInt;
|
||||
/* typedef BoolInt Bool; */
|
||||
#define True 1
|
||||
#define False 0
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#define MY_VER_MAJOR 18
|
||||
#define MY_VER_MINOR 05
|
||||
#define MY_VER_MINOR 06
|
||||
#define MY_VER_BUILD 0
|
||||
#define MY_VERSION_NUMBERS "18.05"
|
||||
#define MY_VERSION_NUMBERS "18.06"
|
||||
#define MY_VERSION MY_VERSION_NUMBERS
|
||||
|
||||
#ifdef MY_CPU_NAME
|
||||
|
@ -10,7 +10,7 @@
|
|||
#define MY_VERSION_CPU MY_VERSION
|
||||
#endif
|
||||
|
||||
#define MY_DATE "2018-04-30"
|
||||
#define MY_DATE "2018-12-30"
|
||||
#undef MY_COPYRIGHT
|
||||
#undef MY_VERSION_COPYRIGHT_DATE
|
||||
#define MY_AUTHOR_NAME "Igor Pavlov"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* CpuArch.c -- CPU specific code
|
||||
2016-02-25: Igor Pavlov : Public domain */
|
||||
2018-07-04: Igor Pavlov : Public domain */
|
||||
|
||||
#include "Precomp.h"
|
||||
|
||||
|
@ -115,7 +115,7 @@ void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)
|
|||
#endif
|
||||
}
|
||||
|
||||
Bool x86cpuid_CheckAndRead(Cx86cpuid *p)
|
||||
BoolInt x86cpuid_CheckAndRead(Cx86cpuid *p)
|
||||
{
|
||||
CHECK_CPUID_IS_SUPPORTED
|
||||
MyCPUID(0, &p->maxFunc, &p->vendor[0], &p->vendor[2], &p->vendor[1]);
|
||||
|
@ -144,7 +144,7 @@ int x86cpuid_GetFirm(const Cx86cpuid *p)
|
|||
return -1;
|
||||
}
|
||||
|
||||
Bool CPU_Is_InOrder()
|
||||
BoolInt CPU_Is_InOrder()
|
||||
{
|
||||
Cx86cpuid p;
|
||||
int firm;
|
||||
|
@ -175,7 +175,7 @@ Bool CPU_Is_InOrder()
|
|||
|
||||
#if !defined(MY_CPU_AMD64) && defined(_WIN32)
|
||||
#include <windows.h>
|
||||
static Bool CPU_Sys_Is_SSE_Supported()
|
||||
static BoolInt CPU_Sys_Is_SSE_Supported()
|
||||
{
|
||||
OSVERSIONINFO vi;
|
||||
vi.dwOSVersionInfoSize = sizeof(vi);
|
||||
|
@ -188,7 +188,7 @@ static Bool CPU_Sys_Is_SSE_Supported()
|
|||
#define CHECK_SYS_SSE_SUPPORT
|
||||
#endif
|
||||
|
||||
Bool CPU_Is_Aes_Supported()
|
||||
BoolInt CPU_Is_Aes_Supported()
|
||||
{
|
||||
Cx86cpuid p;
|
||||
CHECK_SYS_SSE_SUPPORT
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* CpuArch.h -- CPU specific code
|
||||
2017-09-04 : Igor Pavlov : Public domain */
|
||||
2018-07-04 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __CPU_ARCH_H
|
||||
#define __CPU_ARCH_H
|
||||
|
@ -318,15 +318,15 @@ enum
|
|||
|
||||
void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d);
|
||||
|
||||
Bool x86cpuid_CheckAndRead(Cx86cpuid *p);
|
||||
BoolInt x86cpuid_CheckAndRead(Cx86cpuid *p);
|
||||
int x86cpuid_GetFirm(const Cx86cpuid *p);
|
||||
|
||||
#define x86cpuid_GetFamily(ver) (((ver >> 16) & 0xFF0) | ((ver >> 8) & 0xF))
|
||||
#define x86cpuid_GetModel(ver) (((ver >> 12) & 0xF0) | ((ver >> 4) & 0xF))
|
||||
#define x86cpuid_GetStepping(ver) (ver & 0xF)
|
||||
|
||||
Bool CPU_Is_InOrder();
|
||||
Bool CPU_Is_Aes_Supported();
|
||||
BoolInt CPU_Is_InOrder();
|
||||
BoolInt CPU_Is_Aes_Supported();
|
||||
|
||||
#endif
|
||||
|
||||
|
|
164
lzma/C/LzFind.c
164
lzma/C/LzFind.c
|
@ -1,5 +1,5 @@
|
|||
/* LzFind.c -- Match finder for LZ algorithms
|
||||
2017-06-10 : Igor Pavlov : Public domain */
|
||||
2018-07-08 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "Precomp.h"
|
||||
|
||||
|
@ -138,7 +138,7 @@ static void MatchFinder_SetDefaultSettings(CMatchFinder *p)
|
|||
|
||||
void MatchFinder_Construct(CMatchFinder *p)
|
||||
{
|
||||
UInt32 i;
|
||||
unsigned i;
|
||||
p->bufferBase = NULL;
|
||||
p->directInput = 0;
|
||||
p->hash = NULL;
|
||||
|
@ -147,7 +147,7 @@ void MatchFinder_Construct(CMatchFinder *p)
|
|||
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
UInt32 r = i;
|
||||
UInt32 r = (UInt32)i;
|
||||
unsigned j;
|
||||
for (j = 0; j < 8; j++)
|
||||
r = (r >> 1) ^ (kCrcPoly & ((UInt32)0 - (r & 1)));
|
||||
|
@ -368,6 +368,8 @@ static void MatchFinder_Normalize(CMatchFinder *p)
|
|||
MatchFinder_ReduceOffsets(p, subValue);
|
||||
}
|
||||
|
||||
|
||||
MY_NO_INLINE
|
||||
static void MatchFinder_CheckLimits(CMatchFinder *p)
|
||||
{
|
||||
if (p->pos == kMaxValForNormalize)
|
||||
|
@ -379,10 +381,16 @@ static void MatchFinder_CheckLimits(CMatchFinder *p)
|
|||
MatchFinder_SetLimits(p);
|
||||
}
|
||||
|
||||
static UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
|
||||
|
||||
/*
|
||||
(lenLimit > maxLen)
|
||||
*/
|
||||
MY_FORCE_INLINE
|
||||
static UInt32 * Hc_GetMatchesSpec(unsigned lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
|
||||
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
|
||||
UInt32 *distances, UInt32 maxLen)
|
||||
UInt32 *distances, unsigned maxLen)
|
||||
{
|
||||
/*
|
||||
son[_cyclicBufferPos] = curMatch;
|
||||
for (;;)
|
||||
{
|
||||
|
@ -400,7 +408,8 @@ static UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos,
|
|||
break;
|
||||
if (maxLen < len)
|
||||
{
|
||||
*distances++ = maxLen = len;
|
||||
maxLen = len;
|
||||
*distances++ = len;
|
||||
*distances++ = delta - 1;
|
||||
if (len == lenLimit)
|
||||
return distances;
|
||||
|
@ -408,15 +417,58 @@ static UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos,
|
|||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
const Byte *lim = cur + lenLimit;
|
||||
son[_cyclicBufferPos] = curMatch;
|
||||
do
|
||||
{
|
||||
UInt32 delta = pos - curMatch;
|
||||
if (delta >= _cyclicBufferSize)
|
||||
break;
|
||||
{
|
||||
ptrdiff_t diff;
|
||||
curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)];
|
||||
diff = (ptrdiff_t)0 - delta;
|
||||
if (cur[maxLen] == cur[maxLen + diff])
|
||||
{
|
||||
const Byte *c = cur;
|
||||
while (*c == c[diff])
|
||||
{
|
||||
if (++c == lim)
|
||||
{
|
||||
distances[0] = (UInt32)(lim - cur);
|
||||
distances[1] = delta - 1;
|
||||
return distances + 2;
|
||||
}
|
||||
}
|
||||
{
|
||||
unsigned len = (unsigned)(c - cur);
|
||||
if (maxLen < len)
|
||||
{
|
||||
maxLen = len;
|
||||
distances[0] = (UInt32)len;
|
||||
distances[1] = delta - 1;
|
||||
distances += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
while (--cutValue);
|
||||
|
||||
return distances;
|
||||
}
|
||||
|
||||
|
||||
MY_FORCE_INLINE
|
||||
UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
|
||||
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
|
||||
UInt32 *distances, UInt32 maxLen)
|
||||
{
|
||||
CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
|
||||
CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
|
||||
UInt32 len0 = 0, len1 = 0;
|
||||
CLzRef *ptr0 = son + ((size_t)_cyclicBufferPos << 1) + 1;
|
||||
CLzRef *ptr1 = son + ((size_t)_cyclicBufferPos << 1);
|
||||
unsigned len0 = 0, len1 = 0;
|
||||
for (;;)
|
||||
{
|
||||
UInt32 delta = pos - curMatch;
|
||||
|
@ -426,9 +478,10 @@ UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byt
|
|||
return distances;
|
||||
}
|
||||
{
|
||||
CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
|
||||
CLzRef *pair = son + ((size_t)(_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
|
||||
const Byte *pb = cur - delta;
|
||||
UInt32 len = (len0 < len1 ? len0 : len1);
|
||||
unsigned len = (len0 < len1 ? len0 : len1);
|
||||
UInt32 pair0 = pair[0];
|
||||
if (pb[len] == cur[len])
|
||||
{
|
||||
if (++len != lenLimit && pb[len] == cur[len])
|
||||
|
@ -437,11 +490,12 @@ UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byt
|
|||
break;
|
||||
if (maxLen < len)
|
||||
{
|
||||
*distances++ = maxLen = len;
|
||||
maxLen = (UInt32)len;
|
||||
*distances++ = (UInt32)len;
|
||||
*distances++ = delta - 1;
|
||||
if (len == lenLimit)
|
||||
{
|
||||
*ptr1 = pair[0];
|
||||
*ptr1 = pair0;
|
||||
*ptr0 = pair[1];
|
||||
return distances;
|
||||
}
|
||||
|
@ -468,9 +522,9 @@ UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byt
|
|||
static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
|
||||
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue)
|
||||
{
|
||||
CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
|
||||
CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
|
||||
UInt32 len0 = 0, len1 = 0;
|
||||
CLzRef *ptr0 = son + ((size_t)_cyclicBufferPos << 1) + 1;
|
||||
CLzRef *ptr1 = son + ((size_t)_cyclicBufferPos << 1);
|
||||
unsigned len0 = 0, len1 = 0;
|
||||
for (;;)
|
||||
{
|
||||
UInt32 delta = pos - curMatch;
|
||||
|
@ -480,9 +534,9 @@ static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const
|
|||
return;
|
||||
}
|
||||
{
|
||||
CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
|
||||
CLzRef *pair = son + ((size_t)(_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
|
||||
const Byte *pb = cur - delta;
|
||||
UInt32 len = (len0 < len1 ? len0 : len1);
|
||||
unsigned len = (len0 < len1 ? len0 : len1);
|
||||
if (pb[len] == cur[len])
|
||||
{
|
||||
while (++len != lenLimit)
|
||||
|
@ -520,13 +574,13 @@ static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const
|
|||
p->buffer++; \
|
||||
if (++p->pos == p->posLimit) MatchFinder_CheckLimits(p);
|
||||
|
||||
#define MOVE_POS_RET MOVE_POS return offset;
|
||||
#define MOVE_POS_RET MOVE_POS return (UInt32)offset;
|
||||
|
||||
static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; }
|
||||
|
||||
#define GET_MATCHES_HEADER2(minLen, ret_op) \
|
||||
UInt32 lenLimit; UInt32 hv; const Byte *cur; UInt32 curMatch; \
|
||||
lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \
|
||||
unsigned lenLimit; UInt32 hv; const Byte *cur; UInt32 curMatch; \
|
||||
lenLimit = (unsigned)p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \
|
||||
cur = p->buffer;
|
||||
|
||||
#define GET_MATCHES_HEADER(minLen) GET_MATCHES_HEADER2(minLen, return 0)
|
||||
|
@ -535,22 +589,22 @@ static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; }
|
|||
#define MF_PARAMS(p) p->pos, p->buffer, p->son, p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue
|
||||
|
||||
#define GET_MATCHES_FOOTER(offset, maxLen) \
|
||||
offset = (UInt32)(GetMatchesSpec1(lenLimit, curMatch, MF_PARAMS(p), \
|
||||
distances + offset, maxLen) - distances); MOVE_POS_RET;
|
||||
offset = (unsigned)(GetMatchesSpec1((UInt32)lenLimit, curMatch, MF_PARAMS(p), \
|
||||
distances + offset, (UInt32)maxLen) - distances); MOVE_POS_RET;
|
||||
|
||||
#define SKIP_FOOTER \
|
||||
SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS;
|
||||
SkipMatchesSpec((UInt32)lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS;
|
||||
|
||||
#define UPDATE_maxLen { \
|
||||
ptrdiff_t diff = (ptrdiff_t)0 - d2; \
|
||||
const Byte *c = cur + maxLen; \
|
||||
const Byte *lim = cur + lenLimit; \
|
||||
for (; c != lim; c++) if (*(c + diff) != *c) break; \
|
||||
maxLen = (UInt32)(c - cur); }
|
||||
maxLen = (unsigned)(c - cur); }
|
||||
|
||||
static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
||||
{
|
||||
UInt32 offset;
|
||||
unsigned offset;
|
||||
GET_MATCHES_HEADER(2)
|
||||
HASH2_CALC;
|
||||
curMatch = p->hash[hv];
|
||||
|
@ -561,7 +615,7 @@ static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
|||
|
||||
UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
||||
{
|
||||
UInt32 offset;
|
||||
unsigned offset;
|
||||
GET_MATCHES_HEADER(3)
|
||||
HASH_ZIP_CALC;
|
||||
curMatch = p->hash[hv];
|
||||
|
@ -572,7 +626,8 @@ UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
|||
|
||||
static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
||||
{
|
||||
UInt32 h2, d2, maxLen, offset, pos;
|
||||
UInt32 h2, d2, pos;
|
||||
unsigned maxLen, offset;
|
||||
UInt32 *hash;
|
||||
GET_MATCHES_HEADER(3)
|
||||
|
||||
|
@ -594,12 +649,12 @@ static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
|||
if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur)
|
||||
{
|
||||
UPDATE_maxLen
|
||||
distances[0] = maxLen;
|
||||
distances[0] = (UInt32)maxLen;
|
||||
distances[1] = d2 - 1;
|
||||
offset = 2;
|
||||
if (maxLen == lenLimit)
|
||||
{
|
||||
SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
|
||||
SkipMatchesSpec((UInt32)lenLimit, curMatch, MF_PARAMS(p));
|
||||
MOVE_POS_RET;
|
||||
}
|
||||
}
|
||||
|
@ -609,7 +664,8 @@ static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
|||
|
||||
static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
||||
{
|
||||
UInt32 h2, h3, d2, d3, maxLen, offset, pos;
|
||||
UInt32 h2, h3, d2, d3, pos;
|
||||
unsigned maxLen, offset;
|
||||
UInt32 *hash;
|
||||
GET_MATCHES_HEADER(4)
|
||||
|
||||
|
@ -618,12 +674,12 @@ static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
|||
hash = p->hash;
|
||||
pos = p->pos;
|
||||
|
||||
d2 = pos - hash[ h2];
|
||||
d2 = pos - hash [h2];
|
||||
d3 = pos - (hash + kFix3HashSize)[h3];
|
||||
|
||||
curMatch = (hash + kFix4HashSize)[hv];
|
||||
|
||||
hash[ h2] = pos;
|
||||
hash [h2] = pos;
|
||||
(hash + kFix3HashSize)[h3] = pos;
|
||||
(hash + kFix4HashSize)[hv] = pos;
|
||||
|
||||
|
@ -632,7 +688,8 @@ static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
|||
|
||||
if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur)
|
||||
{
|
||||
distances[0] = maxLen = 2;
|
||||
maxLen = 2;
|
||||
distances[0] = 2;
|
||||
distances[1] = d2 - 1;
|
||||
offset = 2;
|
||||
}
|
||||
|
@ -648,10 +705,10 @@ static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
|||
if (offset != 0)
|
||||
{
|
||||
UPDATE_maxLen
|
||||
distances[(size_t)offset - 2] = maxLen;
|
||||
distances[(size_t)offset - 2] = (UInt32)maxLen;
|
||||
if (maxLen == lenLimit)
|
||||
{
|
||||
SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
|
||||
SkipMatchesSpec((UInt32)lenLimit, curMatch, MF_PARAMS(p));
|
||||
MOVE_POS_RET;
|
||||
}
|
||||
}
|
||||
|
@ -674,13 +731,13 @@ static UInt32 Bt5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
|||
hash = p->hash;
|
||||
pos = p->pos;
|
||||
|
||||
d2 = pos - hash[ h2];
|
||||
d2 = pos - hash [h2];
|
||||
d3 = pos - (hash + kFix3HashSize)[h3];
|
||||
d4 = pos - (hash + kFix4HashSize)[h4];
|
||||
|
||||
curMatch = (hash + kFix5HashSize)[hv];
|
||||
|
||||
hash[ h2] = pos;
|
||||
hash [h2] = pos;
|
||||
(hash + kFix3HashSize)[h3] = pos;
|
||||
(hash + kFix4HashSize)[h4] = pos;
|
||||
(hash + kFix5HashSize)[hv] = pos;
|
||||
|
@ -741,7 +798,8 @@ static UInt32 Bt5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
|||
|
||||
static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
||||
{
|
||||
UInt32 h2, h3, d2, d3, maxLen, offset, pos;
|
||||
UInt32 h2, h3, d2, d3, pos;
|
||||
unsigned maxLen, offset;
|
||||
UInt32 *hash;
|
||||
GET_MATCHES_HEADER(4)
|
||||
|
||||
|
@ -750,12 +808,11 @@ static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
|||
hash = p->hash;
|
||||
pos = p->pos;
|
||||
|
||||
d2 = pos - hash[ h2];
|
||||
d2 = pos - hash [h2];
|
||||
d3 = pos - (hash + kFix3HashSize)[h3];
|
||||
|
||||
curMatch = (hash + kFix4HashSize)[hv];
|
||||
|
||||
hash[ h2] = pos;
|
||||
hash [h2] = pos;
|
||||
(hash + kFix3HashSize)[h3] = pos;
|
||||
(hash + kFix4HashSize)[hv] = pos;
|
||||
|
||||
|
@ -764,7 +821,8 @@ static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
|||
|
||||
if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur)
|
||||
{
|
||||
distances[0] = maxLen = 2;
|
||||
maxLen = 2;
|
||||
distances[0] = 2;
|
||||
distances[1] = d2 - 1;
|
||||
offset = 2;
|
||||
}
|
||||
|
@ -780,7 +838,7 @@ static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
|||
if (offset != 0)
|
||||
{
|
||||
UPDATE_maxLen
|
||||
distances[(size_t)offset - 2] = maxLen;
|
||||
distances[(size_t)offset - 2] = (UInt32)maxLen;
|
||||
if (maxLen == lenLimit)
|
||||
{
|
||||
p->son[p->cyclicBufferPos] = curMatch;
|
||||
|
@ -791,7 +849,7 @@ static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
|||
if (maxLen < 3)
|
||||
maxLen = 3;
|
||||
|
||||
offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
|
||||
offset = (unsigned)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
|
||||
distances + offset, maxLen) - (distances));
|
||||
MOVE_POS_RET
|
||||
}
|
||||
|
@ -808,13 +866,13 @@ static UInt32 Hc5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
|||
hash = p->hash;
|
||||
pos = p->pos;
|
||||
|
||||
d2 = pos - hash[ h2];
|
||||
d2 = pos - hash [h2];
|
||||
d3 = pos - (hash + kFix3HashSize)[h3];
|
||||
d4 = pos - (hash + kFix4HashSize)[h4];
|
||||
|
||||
curMatch = (hash + kFix5HashSize)[hv];
|
||||
|
||||
hash[ h2] = pos;
|
||||
hash [h2] = pos;
|
||||
(hash + kFix3HashSize)[h3] = pos;
|
||||
(hash + kFix4HashSize)[h4] = pos;
|
||||
(hash + kFix5HashSize)[hv] = pos;
|
||||
|
@ -877,12 +935,12 @@ static UInt32 Hc5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
|||
|
||||
UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
||||
{
|
||||
UInt32 offset;
|
||||
unsigned offset;
|
||||
GET_MATCHES_HEADER(3)
|
||||
HASH_ZIP_CALC;
|
||||
curMatch = p->hash[hv];
|
||||
p->hash[hv] = p->pos;
|
||||
offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
|
||||
offset = (unsigned)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
|
||||
distances, 2) - (distances));
|
||||
MOVE_POS_RET
|
||||
}
|
||||
|
@ -940,7 +998,7 @@ static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
|||
HASH4_CALC;
|
||||
hash = p->hash;
|
||||
curMatch = (hash + kFix4HashSize)[hv];
|
||||
hash[ h2] =
|
||||
hash [h2] =
|
||||
(hash + kFix3HashSize)[h3] =
|
||||
(hash + kFix4HashSize)[hv] = p->pos;
|
||||
SKIP_FOOTER
|
||||
|
@ -959,7 +1017,7 @@ static void Bt5_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
|||
HASH5_CALC;
|
||||
hash = p->hash;
|
||||
curMatch = (hash + kFix5HashSize)[hv];
|
||||
hash[ h2] =
|
||||
hash [h2] =
|
||||
(hash + kFix3HashSize)[h3] =
|
||||
(hash + kFix4HashSize)[h4] =
|
||||
(hash + kFix5HashSize)[hv] = p->pos;
|
||||
|
@ -979,7 +1037,7 @@ static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
|||
HASH4_CALC;
|
||||
hash = p->hash;
|
||||
curMatch = (hash + kFix4HashSize)[hv];
|
||||
hash[ h2] =
|
||||
hash [h2] =
|
||||
(hash + kFix3HashSize)[h3] =
|
||||
(hash + kFix4HashSize)[hv] = p->pos;
|
||||
p->son[p->cyclicBufferPos] = curMatch;
|
||||
|
@ -999,7 +1057,7 @@ static void Hc5_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
|||
HASH5_CALC;
|
||||
hash = p->hash;
|
||||
curMatch = hash + kFix5HashSize)[hv];
|
||||
hash[ h2] =
|
||||
hash [h2] =
|
||||
(hash + kFix3HashSize)[h3] =
|
||||
(hash + kFix4HashSize)[h4] =
|
||||
(hash + kFix5HashSize)[hv] = p->pos;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* LzFindMt.c -- multithreaded Match finder for LZ algorithms
|
||||
2017-06-10 : Igor Pavlov : Public domain */
|
||||
2018-12-29 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "Precomp.h"
|
||||
|
||||
|
@ -232,38 +232,57 @@ static void MatchFinderMt_GetNextBlock_Hash(CMatchFinderMt *p)
|
|||
|
||||
#define kEmptyHashValue 0
|
||||
|
||||
/* #define MFMT_GM_INLINE */
|
||||
#define MFMT_GM_INLINE
|
||||
|
||||
#ifdef MFMT_GM_INLINE
|
||||
|
||||
#define NO_INLINE MY_FAST_CALL
|
||||
/*
|
||||
we use size_t for _cyclicBufferPos instead of UInt32
|
||||
to eliminate "movsx" BUG in old MSVC x64 compiler.
|
||||
*/
|
||||
|
||||
static Int32 NO_INLINE GetMatchesSpecN(UInt32 lenLimit, UInt32 pos, const Byte *cur, CLzRef *son,
|
||||
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
|
||||
UInt32 *_distances, UInt32 _maxLen, const UInt32 *hash, Int32 limit, UInt32 size, UInt32 *posRes)
|
||||
MY_NO_INLINE
|
||||
static UInt32 *GetMatchesSpecN(UInt32 lenLimit, UInt32 pos, const Byte *cur, CLzRef *son,
|
||||
size_t _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
|
||||
UInt32 *distances, UInt32 _maxLen, const UInt32 *hash, const UInt32 *limit, UInt32 size, UInt32 *posRes)
|
||||
{
|
||||
do
|
||||
{
|
||||
UInt32 *distances = _distances + 1;
|
||||
UInt32 curMatch = pos - *hash++;
|
||||
UInt32 *_distances = ++distances;
|
||||
UInt32 delta = *hash++;
|
||||
|
||||
CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
|
||||
CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
|
||||
UInt32 len0 = 0, len1 = 0;
|
||||
CLzRef *ptr0 = son + ((size_t)_cyclicBufferPos << 1) + 1;
|
||||
CLzRef *ptr1 = son + ((size_t)_cyclicBufferPos << 1);
|
||||
unsigned len0 = 0, len1 = 0;
|
||||
UInt32 cutValue = _cutValue;
|
||||
UInt32 maxLen = _maxLen;
|
||||
for (;;)
|
||||
unsigned maxLen = (unsigned)_maxLen;
|
||||
|
||||
/*
|
||||
if (size > 1)
|
||||
{
|
||||
UInt32 delta = pos - curMatch;
|
||||
if (cutValue-- == 0 || delta >= _cyclicBufferSize)
|
||||
UInt32 delta = *hash;
|
||||
if (delta < _cyclicBufferSize)
|
||||
{
|
||||
*ptr0 = *ptr1 = kEmptyHashValue;
|
||||
break;
|
||||
UInt32 cyc1 = _cyclicBufferPos + 1;
|
||||
CLzRef *pair = son + ((size_t)(cyc1 - delta + ((delta > cyc1) ? _cyclicBufferSize : 0)) << 1);
|
||||
Byte b = *(cur + 1 - delta);
|
||||
_distances[0] = pair[0];
|
||||
_distances[1] = b;
|
||||
}
|
||||
}
|
||||
*/
|
||||
if (cutValue == 0 || delta >= _cyclicBufferSize)
|
||||
{
|
||||
*ptr0 = *ptr1 = kEmptyHashValue;
|
||||
}
|
||||
else
|
||||
for(;;)
|
||||
{
|
||||
{
|
||||
CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
|
||||
CLzRef *pair = son + ((size_t)(_cyclicBufferPos - delta + ((_cyclicBufferPos < delta) ? _cyclicBufferSize : 0)) << 1);
|
||||
const Byte *pb = cur - delta;
|
||||
UInt32 len = (len0 < len1 ? len0 : len1);
|
||||
unsigned len = (len0 < len1 ? len0 : len1);
|
||||
UInt32 pair0 = *pair;
|
||||
if (pb[len] == cur[len])
|
||||
{
|
||||
if (++len != lenLimit && pb[len] == cur[len])
|
||||
|
@ -272,54 +291,66 @@ static Int32 NO_INLINE GetMatchesSpecN(UInt32 lenLimit, UInt32 pos, const Byte *
|
|||
break;
|
||||
if (maxLen < len)
|
||||
{
|
||||
*distances++ = maxLen = len;
|
||||
maxLen = len;
|
||||
*distances++ = (UInt32)len;
|
||||
*distances++ = delta - 1;
|
||||
if (len == lenLimit)
|
||||
{
|
||||
*ptr1 = pair[0];
|
||||
*ptr0 = pair[1];
|
||||
UInt32 pair1 = pair[1];
|
||||
*ptr1 = pair0;
|
||||
*ptr0 = pair1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pb[len] < cur[len])
|
||||
{
|
||||
*ptr1 = curMatch;
|
||||
ptr1 = pair + 1;
|
||||
curMatch = *ptr1;
|
||||
len1 = len;
|
||||
}
|
||||
else
|
||||
{
|
||||
*ptr0 = curMatch;
|
||||
ptr0 = pair;
|
||||
curMatch = *ptr0;
|
||||
len0 = len;
|
||||
UInt32 curMatch = pos - delta;
|
||||
// delta = pos - *pair;
|
||||
// delta = pos - pair[((UInt32)pb[len] - (UInt32)cur[len]) >> 31];
|
||||
if (pb[len] < cur[len])
|
||||
{
|
||||
delta = pos - pair[1];
|
||||
*ptr1 = curMatch;
|
||||
ptr1 = pair + 1;
|
||||
len1 = len;
|
||||
}
|
||||
else
|
||||
{
|
||||
delta = pos - *pair;
|
||||
*ptr0 = curMatch;
|
||||
ptr0 = pair;
|
||||
len0 = len;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (--cutValue == 0 || delta >= _cyclicBufferSize)
|
||||
{
|
||||
*ptr0 = *ptr1 = kEmptyHashValue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
pos++;
|
||||
_cyclicBufferPos++;
|
||||
cur++;
|
||||
{
|
||||
UInt32 num = (UInt32)(distances - _distances);
|
||||
*_distances = num - 1;
|
||||
_distances += num;
|
||||
limit -= num;
|
||||
_distances[-1] = num;
|
||||
}
|
||||
}
|
||||
while (limit > 0 && --size != 0);
|
||||
while (distances < limit && --size != 0);
|
||||
*posRes = pos;
|
||||
return limit;
|
||||
return distances;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
static void BtGetMatches(CMatchFinderMt *p, UInt32 *distances)
|
||||
{
|
||||
UInt32 numProcessed = 0;
|
||||
UInt32 curPos = 2;
|
||||
UInt32 limit = kMtBtBlockSize - (p->matchMaxLen * 2);
|
||||
UInt32 limit = kMtBtBlockSize - (p->matchMaxLen * 2); // * 2
|
||||
|
||||
distances[1] = p->hashNumAvail;
|
||||
|
||||
|
@ -369,8 +400,10 @@ static void BtGetMatches(CMatchFinderMt *p, UInt32 *distances)
|
|||
#else
|
||||
{
|
||||
UInt32 posRes;
|
||||
curPos = limit - GetMatchesSpecN(lenLimit, pos, p->buffer, p->son, cyclicBufferPos, p->cyclicBufferSize, p->cutValue,
|
||||
distances + curPos, p->numHashBytes - 1, p->hashBuf + p->hashBufPos, (Int32)(limit - curPos), size, &posRes);
|
||||
curPos = (UInt32)(GetMatchesSpecN(lenLimit, pos, p->buffer, p->son, cyclicBufferPos, p->cyclicBufferSize, p->cutValue,
|
||||
distances + curPos, p->numHashBytes - 1, p->hashBuf + p->hashBufPos,
|
||||
distances + limit,
|
||||
size, &posRes) - distances);
|
||||
p->hashBufPos += posRes - pos;
|
||||
cyclicBufferPos += posRes - pos;
|
||||
p->buffer += posRes - pos;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* LzFindMt.h -- multithreaded Match finder for LZ algorithms
|
||||
2017-04-03 : Igor Pavlov : Public domain */
|
||||
2018-07-04 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __LZ_FIND_MT_H
|
||||
#define __LZ_FIND_MT_H
|
||||
|
@ -19,10 +19,10 @@ EXTERN_C_BEGIN
|
|||
|
||||
typedef struct _CMtSync
|
||||
{
|
||||
Bool wasCreated;
|
||||
Bool needStart;
|
||||
Bool exit;
|
||||
Bool stopWriting;
|
||||
BoolInt wasCreated;
|
||||
BoolInt needStart;
|
||||
BoolInt exit;
|
||||
BoolInt stopWriting;
|
||||
|
||||
CThread thread;
|
||||
CAutoResetEvent canStart;
|
||||
|
@ -30,8 +30,8 @@ typedef struct _CMtSync
|
|||
CAutoResetEvent wasStopped;
|
||||
CSemaphore freeSemaphore;
|
||||
CSemaphore filledSemaphore;
|
||||
Bool csWasInitialized;
|
||||
Bool csWasEntered;
|
||||
BoolInt csWasInitialized;
|
||||
BoolInt csWasEntered;
|
||||
CCriticalSection cs;
|
||||
UInt32 numProcessedBlocks;
|
||||
} CMtSync;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* Lzma2Dec.c -- LZMA2 Decoder
|
||||
2018-02-19 : Igor Pavlov : Public domain */
|
||||
2018-07-04 : Igor Pavlov : Public domain */
|
||||
|
||||
/* #define SHOW_DEBUG_INFO */
|
||||
|
||||
|
@ -169,7 +169,7 @@ static void LzmaDec_UpdateWithUncompressed(CLzmaDec *p, const Byte *src, SizeT s
|
|||
p->processedPos += (UInt32)size;
|
||||
}
|
||||
|
||||
void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState);
|
||||
void LzmaDec_InitDicAndState(CLzmaDec *p, BoolInt initDic, BoolInt initState);
|
||||
|
||||
|
||||
SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
|
||||
|
@ -232,7 +232,7 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
|
|||
|
||||
if (p->state == LZMA2_STATE_DATA)
|
||||
{
|
||||
Bool initDic = (p->control == LZMA2_CONTROL_COPY_RESET_DIC);
|
||||
BoolInt initDic = (p->control == LZMA2_CONTROL_COPY_RESET_DIC);
|
||||
LzmaDec_InitDicAndState(&p->decoder, initDic, False);
|
||||
}
|
||||
|
||||
|
@ -254,8 +254,8 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
|
|||
|
||||
if (p->state == LZMA2_STATE_DATA)
|
||||
{
|
||||
Bool initDic = (p->control >= 0xE0);
|
||||
Bool initState = (p->control >= 0xA0);
|
||||
BoolInt initDic = (p->control >= 0xE0);
|
||||
BoolInt initState = (p->control >= 0xA0);
|
||||
LzmaDec_InitDicAndState(&p->decoder, initDic, initState);
|
||||
p->state = LZMA2_STATE_DATA_CONT;
|
||||
}
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
/* LzmaDec.c -- LZMA Decoder
|
||||
2018-02-28 : Igor Pavlov : Public domain */
|
||||
2018-07-04 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "Precomp.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/* #include "CpuArch.h" */
|
||||
#include "LzmaDec.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#define kNumTopBits 24
|
||||
#define kTopValue ((UInt32)1 << kNumTopBits)
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
|||
|
||||
#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); }
|
||||
|
||||
#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
|
||||
#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * (UInt32)ttt; if (code < bound)
|
||||
#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
|
||||
#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits));
|
||||
#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \
|
||||
|
@ -66,7 +66,7 @@
|
|||
|
||||
#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); }
|
||||
|
||||
#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
|
||||
#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * (UInt32)ttt; if (code < bound)
|
||||
#define UPDATE_0_CHECK range = bound;
|
||||
#define UPDATE_1_CHECK range -= bound; code -= bound;
|
||||
#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \
|
||||
|
@ -539,7 +539,7 @@ int MY_FAST_CALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit
|
|||
curLen = ((rem < len) ? (unsigned)rem : len);
|
||||
pos = dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0);
|
||||
|
||||
processedPos += curLen;
|
||||
processedPos += (UInt32)curLen;
|
||||
|
||||
len -= curLen;
|
||||
if (curLen <= dicBufSize - pos)
|
||||
|
@ -547,7 +547,7 @@ int MY_FAST_CALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit
|
|||
Byte *dest = dic + dicPos;
|
||||
ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos;
|
||||
const Byte *lim = dest + curLen;
|
||||
dicPos += curLen;
|
||||
dicPos += (SizeT)curLen;
|
||||
do
|
||||
*(dest) = (Byte)*(dest + src);
|
||||
while (++dest != lim);
|
||||
|
@ -572,14 +572,14 @@ int MY_FAST_CALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit
|
|||
p->buf = buf;
|
||||
p->range = range;
|
||||
p->code = code;
|
||||
p->remainLen = len;
|
||||
p->remainLen = (UInt32)len;
|
||||
p->dicPos = dicPos;
|
||||
p->processedPos = processedPos;
|
||||
p->reps[0] = rep0;
|
||||
p->reps[1] = rep1;
|
||||
p->reps[2] = rep2;
|
||||
p->reps[3] = rep3;
|
||||
p->state = state;
|
||||
p->state = (UInt32)state;
|
||||
|
||||
return SZ_OK;
|
||||
}
|
||||
|
@ -601,8 +601,8 @@ static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
|
|||
if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len)
|
||||
p->checkDicSize = p->prop.dicSize;
|
||||
|
||||
p->processedPos += len;
|
||||
p->remainLen -= len;
|
||||
p->processedPos += (UInt32)len;
|
||||
p->remainLen -= (UInt32)len;
|
||||
while (len != 0)
|
||||
{
|
||||
len--;
|
||||
|
@ -850,7 +850,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
|
|||
}
|
||||
|
||||
|
||||
void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
|
||||
void LzmaDec_InitDicAndState(CLzmaDec *p, BoolInt initDic, BoolInt initState)
|
||||
{
|
||||
p->remainLen = kMatchSpecLenStart + 1;
|
||||
p->tempBufSize = 0;
|
||||
|
@ -979,10 +979,10 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
|
|||
p->tempBufSize = rem;
|
||||
if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
|
||||
{
|
||||
int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem);
|
||||
int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, (SizeT)rem);
|
||||
if (dummyRes == DUMMY_ERROR)
|
||||
{
|
||||
(*srcLen) += lookAhead;
|
||||
(*srcLen) += (SizeT)lookAhead;
|
||||
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
|
||||
return SZ_OK;
|
||||
}
|
||||
|
@ -1005,9 +1005,9 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
|
|||
return SZ_ERROR_FAIL; /* some internal error */
|
||||
lookAhead -= rem;
|
||||
}
|
||||
(*srcLen) += lookAhead;
|
||||
(*srcLen) += (SizeT)lookAhead;
|
||||
src += lookAhead;
|
||||
inSize -= lookAhead;
|
||||
inSize -= (SizeT)lookAhead;
|
||||
p->tempBufSize = 0;
|
||||
}
|
||||
}
|
||||
|
|
739
lzma/C/LzmaEnc.c
739
lzma/C/LzmaEnc.c
File diff suppressed because it is too large
Load diff
|
@ -1,5 +1,5 @@
|
|||
/* Ppmd7.c -- PPMdH codec
|
||||
2017-04-03 : Igor Pavlov : Public domain
|
||||
2018-07-04 : Igor Pavlov : Public domain
|
||||
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
|
||||
|
||||
#include "Precomp.h"
|
||||
|
@ -95,7 +95,7 @@ void Ppmd7_Free(CPpmd7 *p, ISzAllocPtr alloc)
|
|||
p->Base = 0;
|
||||
}
|
||||
|
||||
Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAllocPtr alloc)
|
||||
BoolInt Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAllocPtr alloc)
|
||||
{
|
||||
if (!p->Base || p->Size != size)
|
||||
{
|
||||
|
@ -342,7 +342,7 @@ void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder)
|
|||
p->DummySee.Count = 64; /* unused */
|
||||
}
|
||||
|
||||
static CTX_PTR CreateSuccessors(CPpmd7 *p, Bool skip)
|
||||
static CTX_PTR CreateSuccessors(CPpmd7 *p, BoolInt skip)
|
||||
{
|
||||
CPpmd_State upState;
|
||||
CTX_PTR c = p->MinContext;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* Ppmd7.h -- PPMdH compression codec
|
||||
2017-04-03 : Igor Pavlov : Public domain
|
||||
2018-07-04 : Igor Pavlov : Public domain
|
||||
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
|
||||
|
||||
/* This code supports virtual RangeDecoder and includes the implementation
|
||||
|
@ -60,7 +60,7 @@ typedef struct
|
|||
} CPpmd7;
|
||||
|
||||
void Ppmd7_Construct(CPpmd7 *p);
|
||||
Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAllocPtr alloc);
|
||||
BoolInt Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAllocPtr alloc);
|
||||
void Ppmd7_Free(CPpmd7 *p, ISzAllocPtr alloc);
|
||||
void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder);
|
||||
#define Ppmd7_WasAllocated(p) ((p)->Base != NULL)
|
||||
|
@ -115,7 +115,7 @@ typedef struct
|
|||
} CPpmd7z_RangeDec;
|
||||
|
||||
void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p);
|
||||
Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p);
|
||||
BoolInt Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p);
|
||||
#define Ppmd7z_RangeDec_IsFinishedOK(p) ((p)->Code == 0)
|
||||
|
||||
int Ppmd7_DecodeSymbol(CPpmd7 *p, const IPpmd7_RangeDec *rc);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* Ppmd7Dec.c -- PPMdH Decoder
|
||||
2017-04-03 : Igor Pavlov : Public domain
|
||||
2018-07-04 : Igor Pavlov : Public domain
|
||||
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
|
||||
|
||||
#include "Precomp.h"
|
||||
|
@ -8,7 +8,7 @@ This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
|
|||
|
||||
#define kTopValue (1 << 24)
|
||||
|
||||
Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p)
|
||||
BoolInt Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p)
|
||||
{
|
||||
unsigned i;
|
||||
p->Code = 0;
|
||||
|
|
|
@ -1,6 +1,109 @@
|
|||
HISTORY of the LZMA SDK
|
||||
-----------------------
|
||||
|
||||
18.06 2018-12-30
|
||||
-------------------------
|
||||
- The speed for LZMA/LZMA2 compressing was increased by 3-10%,
|
||||
and there are minor changes in compression ratio.
|
||||
- Some bugs were fixed.
|
||||
- The bug in 7-Zip 18.02-18.05 was fixed:
|
||||
There was memory leak in multithreading xz decoder - XzDecMt_Decode(),
|
||||
if xz stream contains only one block.
|
||||
- The changes for MSVS compiler makefiles:
|
||||
- the makefiles now use "PLATFORM" macroname with values (x64, x86, arm64)
|
||||
instead of "CPU" macroname with values (AMD64, ARM64).
|
||||
- the makefiles by default now use static version of the run-time library.
|
||||
|
||||
|
||||
18.05 2018-04-30
|
||||
-------------------------
|
||||
- The speed for LZMA/LZMA2 compressing was increased
|
||||
by 8% for fastest/fast compression levels and
|
||||
by 3% for normal/maximum compression levels.
|
||||
- Previous versions of 7-Zip could work incorrectly in "Large memory pages" mode in
|
||||
Windows 10 because of some BUG with "Large Pages" in Windows 10.
|
||||
Now 7-Zip doesn't use "Large Pages" on Windows 10 up to revision 1709 (16299).
|
||||
- The BUG was fixed in Lzma2Enc.c
|
||||
Lzma2Enc_Encode2() function worked incorretly,
|
||||
if (inStream == NULL) and the number of block threads is more than 1.
|
||||
|
||||
|
||||
18.03 beta 2018-03-04
|
||||
-------------------------
|
||||
- Asm\x86\LzmaDecOpt.asm: new optimized LZMA decoder written in asm
|
||||
for x64 with about 30% higher speed than main version of LZMA decoder written in C.
|
||||
- The speed for single-thread LZMA/LZMA2 decoder written in C was increased by 3%.
|
||||
- 7-Zip now can use multi-threading for 7z/LZMA2 decoding,
|
||||
if there are multiple independent data chunks in LZMA2 stream.
|
||||
- 7-Zip now can use multi-threading for xz decoding,
|
||||
if there are multiple blocks in xz stream.
|
||||
|
||||
|
||||
18.01 2019-01-28
|
||||
-------------------------
|
||||
- The BUG in 17.01 - 18.00 beta was fixed:
|
||||
XzDec.c : random block unpacking and XzUnpacker_IsBlockFinished()
|
||||
didn't work correctly for xz archives without checksum (CRC).
|
||||
|
||||
|
||||
18.00 beta 2019-01-10
|
||||
-------------------------
|
||||
- The BUG in xz encoder was fixed:
|
||||
There was memory leak of 16 KB for each file compressed with
|
||||
xz compression method, if additional filter was used.
|
||||
|
||||
|
||||
17.01 beta 2017-08-28
|
||||
-------------------------
|
||||
- Minor speed optimization for LZMA2 (xz and 7z) multi-threading compression.
|
||||
7-Zip now uses additional memory buffers for multi-block LZMA2 compression.
|
||||
CPU utilization was slightly improved.
|
||||
- 7-zip now creates multi-block xz archives by default. Block size can be
|
||||
specified with -ms[Size]{m|g} switch.
|
||||
- xz decoder now can unpack random block from multi-block xz archives.
|
||||
- 7-Zip command line: @listfile now doesn't work after -- switch.
|
||||
Use -i@listfile before -- switch instead.
|
||||
- The BUGs were fixed:
|
||||
7-Zip 17.00 beta crashed for commands that write anti-item to 7z archive.
|
||||
|
||||
|
||||
17.00 beta 2017-04-29
|
||||
-------------------------
|
||||
- NewHandler.h / NewHandler.cpp:
|
||||
now it redefines operator new() only for old MSVC compilers (_MSC_VER < 1900).
|
||||
- C/7zTypes.h : the names of variables in interface structures were changed (vt).
|
||||
- Some bugs were fixed. 7-Zip could crash in some cases.
|
||||
- Some internal changes in code.
|
||||
|
||||
|
||||
16.04 2016-10-04
|
||||
-------------------------
|
||||
- The bug was fixed in DllSecur.c.
|
||||
|
||||
|
||||
16.03 2016-09-28
|
||||
-------------------------
|
||||
- SFX modules now use some protection against DLL preloading attack.
|
||||
- Some bugs in 7z code were fixed.
|
||||
|
||||
|
||||
16.02 2016-05-21
|
||||
-------------------------
|
||||
- The BUG in 16.00 - 16.01 was fixed:
|
||||
Split Handler (SplitHandler.cpp) returned incorrect
|
||||
total size value (kpidSize) for split archives.
|
||||
|
||||
|
||||
16.01 2016-05-19
|
||||
-------------------------
|
||||
- Some internal changes to reduce the number of compiler warnings.
|
||||
|
||||
|
||||
16.00 2016-05-10
|
||||
-------------------------
|
||||
- Some bugs were fixed.
|
||||
|
||||
|
||||
15.12 2015-11-19
|
||||
-------------------------
|
||||
- The BUG in C version of 7z decoder was fixed:
|
|
@ -1,4 +1,4 @@
|
|||
LZMA SDK 15.13
|
||||
LZMA SDK 18.06
|
||||
--------------
|
||||
|
||||
LZMA SDK provides the documentation, samples, header files,
|
|
@ -13,7 +13,6 @@ include( CheckIncludeFile )
|
|||
include( CheckIncludeFiles )
|
||||
include( CheckLibraryExists )
|
||||
include( FindPkgConfig )
|
||||
include( TargetArch )
|
||||
|
||||
if( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE )
|
||||
option( NO_STRIP "Do not strip Release or MinSizeRel builds" )
|
||||
|
@ -33,12 +32,13 @@ if( APPLE )
|
|||
option( OSX_COCOA_BACKEND "Use native Cocoa backend instead of SDL" ON )
|
||||
endif()
|
||||
|
||||
target_architecture(ZDOOM_TARGET_ARCH)
|
||||
|
||||
if( ${ZDOOM_TARGET_ARCH} MATCHES "x86_64" )
|
||||
set( X64 64 )
|
||||
endif()
|
||||
|
||||
if( X64 OR ${ZDOOM_TARGET_ARCH} MATCHES "i386" )
|
||||
add_definitions( -DARCH_IA32 )
|
||||
endif()
|
||||
|
||||
if( NOT ZDOOM_LIBS )
|
||||
set( ZDOOM_LIBS "" )
|
||||
|
@ -460,8 +460,14 @@ add_custom_target( revision_check ALL
|
|||
# Libraries ZDoom needs
|
||||
|
||||
message( STATUS "Fluid synth libs: ${FLUIDSYNTH_LIBRARIES}" )
|
||||
set( ZDOOM_LIBS ${ZDOOM_LIBS} "${ZLIB_LIBRARIES}" "${JPEG_LIBRARIES}" "${BZIP2_LIBRARIES}" "${GME_LIBRARIES}" "${ASMJIT_LIBRARIES}" "${CMAKE_DL_LIBS}" )
|
||||
include_directories( "${ZLIB_INCLUDE_DIR}" "${BZIP2_INCLUDE_DIR}" "${LZMA_INCLUDE_DIR}" "${JPEG_INCLUDE_DIR}" "${GME_INCLUDE_DIR}" "${ASMJIT_INCLUDE_DIR}" )
|
||||
set( ZDOOM_LIBS ${ZDOOM_LIBS} "${ZLIB_LIBRARIES}" "${JPEG_LIBRARIES}" "${BZIP2_LIBRARIES}" "${GME_LIBRARIES}" "${CMAKE_DL_LIBS}" )
|
||||
include_directories( "${ZLIB_INCLUDE_DIR}" "${BZIP2_INCLUDE_DIR}" "${LZMA_INCLUDE_DIR}" "${JPEG_INCLUDE_DIR}" "${GME_INCLUDE_DIR}" )
|
||||
|
||||
if( ${HAVE_VM_JIT} )
|
||||
add_definitions( -DHAVE_VM_JIT )
|
||||
include_directories( "${ASMJIT_INCLUDE_DIR}" )
|
||||
set( ZDOOM_LIBS ${ZDOOM_LIBS} "${ASMJIT_LIBRARIES}")
|
||||
endif()
|
||||
|
||||
if( SNDFILE_FOUND )
|
||||
set( ZDOOM_LIBS ${ZDOOM_LIBS} "${SNDFILE_LIBRARIES}" )
|
||||
|
@ -649,6 +655,7 @@ file( GLOB HEADER_FILES
|
|||
g_statusbar/*.h
|
||||
g_inventory/*.h
|
||||
intermission/*.h
|
||||
maploader/*.h
|
||||
menu/*.h
|
||||
sound/adlmidi/*.h*
|
||||
sound/opnmidi/*.h*
|
||||
|
@ -799,6 +806,17 @@ set( NOT_COMPILED_SOURCE_FILES
|
|||
zcc-parse.h
|
||||
)
|
||||
|
||||
set( VM_JIT_SOURCES
|
||||
scripting/vm/jit.cpp
|
||||
scripting/vm/jit_runtime.cpp
|
||||
scripting/vm/jit_call.cpp
|
||||
scripting/vm/jit_flow.cpp
|
||||
scripting/vm/jit_load.cpp
|
||||
scripting/vm/jit_math.cpp
|
||||
scripting/vm/jit_move.cpp
|
||||
scripting/vm/jit_store.cpp
|
||||
)
|
||||
|
||||
# This is disabled for now because I cannot find a way to give the .pch file a different name.
|
||||
# Visual C++ 2015 seems hell-bent on only allowing one .pch file with the same name as the executable.
|
||||
#enable_precompiled_headers( g_pch2.h FASTMATH_PCH_SOURCES )
|
||||
|
@ -890,7 +908,6 @@ set (PCH_SOURCES
|
|||
c_functions.cpp
|
||||
cmdlib.cpp
|
||||
colormatcher.cpp
|
||||
compatibility.cpp
|
||||
configfile.cpp
|
||||
ct_chat.cpp
|
||||
cycler.cpp
|
||||
|
@ -908,7 +925,6 @@ set (PCH_SOURCES
|
|||
doomstat.cpp
|
||||
dsectoreffect.cpp
|
||||
dthinker.cpp
|
||||
edata.cpp
|
||||
f_wipe.cpp
|
||||
files.cpp
|
||||
files_decompress.cpp
|
||||
|
@ -955,7 +971,6 @@ set (PCH_SOURCES
|
|||
p_effect.cpp
|
||||
p_enemy.cpp
|
||||
p_floor.cpp
|
||||
p_glnodes.cpp
|
||||
p_interaction.cpp
|
||||
p_lights.cpp
|
||||
p_linkedsectors.cpp
|
||||
|
@ -974,7 +989,6 @@ set (PCH_SOURCES
|
|||
p_sectors.cpp
|
||||
p_setup.cpp
|
||||
p_sight.cpp
|
||||
p_slopes.cpp
|
||||
p_spec.cpp
|
||||
p_states.cpp
|
||||
p_switch.cpp
|
||||
|
@ -984,7 +998,6 @@ set (PCH_SOURCES
|
|||
p_things.cpp
|
||||
p_tick.cpp
|
||||
p_trace.cpp
|
||||
p_udmf.cpp
|
||||
p_usdf.cpp
|
||||
p_user.cpp
|
||||
p_xlat.cpp
|
||||
|
@ -1077,7 +1090,14 @@ set (PCH_SOURCES
|
|||
hwrenderer/utility/hw_lighting.cpp
|
||||
hwrenderer/utility/hw_shaderpatcher.cpp
|
||||
hwrenderer/utility/hw_vrmodes.cpp
|
||||
|
||||
maploader/edata.cpp
|
||||
maploader/maploader.cpp
|
||||
maploader/slopes.cpp
|
||||
maploader/glnodes.cpp
|
||||
maploader/udmf.cpp
|
||||
maploader/polyobjects.cpp
|
||||
maploader/renderinfo.cpp
|
||||
maploader/compatibility.cpp
|
||||
menu/joystickmenu.cpp
|
||||
menu/loadsavemenu.cpp
|
||||
menu/menu.cpp
|
||||
|
@ -1144,7 +1164,6 @@ set (PCH_SOURCES
|
|||
r_data/sprites.cpp
|
||||
r_data/portalgroups.cpp
|
||||
r_data/voxels.cpp
|
||||
r_data/renderinfo.cpp
|
||||
r_data/renderstyle.cpp
|
||||
r_data/r_canvastexture.cpp
|
||||
r_data/r_interpolate.cpp
|
||||
|
@ -1174,14 +1193,6 @@ set (PCH_SOURCES
|
|||
scripting/decorate/thingdef_states.cpp
|
||||
scripting/vm/vmexec.cpp
|
||||
scripting/vm/vmframe.cpp
|
||||
scripting/vm/jit.cpp
|
||||
scripting/vm/jit_runtime.cpp
|
||||
scripting/vm/jit_call.cpp
|
||||
scripting/vm/jit_flow.cpp
|
||||
scripting/vm/jit_load.cpp
|
||||
scripting/vm/jit_math.cpp
|
||||
scripting/vm/jit_move.cpp
|
||||
scripting/vm/jit_store.cpp
|
||||
scripting/zscript/ast.cpp
|
||||
scripting/zscript/zcc_compile.cpp
|
||||
scripting/zscript/zcc_parser.cpp
|
||||
|
@ -1256,6 +1267,12 @@ set (PCH_SOURCES
|
|||
events.cpp
|
||||
)
|
||||
|
||||
if( ${HAVE_VM_JIT} )
|
||||
set( PCH_SOURCES ${PCH_SOURCES} ${VM_JIT_SOURCES} )
|
||||
else()
|
||||
set( NOT_COMPILED_SOURCE_FILES ${NOT_COMPILED_SOURCE_FILES} ${VM_JIT_SOURCES} )
|
||||
endif()
|
||||
|
||||
enable_precompiled_headers( g_pch.h PCH_SOURCES )
|
||||
|
||||
add_executable( zdoom WIN32 MACOSX_BUNDLE
|
||||
|
@ -1263,7 +1280,6 @@ add_executable( zdoom WIN32 MACOSX_BUNDLE
|
|||
${NOT_COMPILED_SOURCE_FILES}
|
||||
__autostart.cpp
|
||||
${SYSTEM_SOURCES}
|
||||
${X86_SOURCES}
|
||||
${FASTMATH_SOURCES}
|
||||
${PCH_SOURCES}
|
||||
x86.cpp
|
||||
|
@ -1301,6 +1317,13 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL "SunOS")
|
|||
set( ZDOOM_LIBS ${ZDOOM_LIBS} nsl socket)
|
||||
endif()
|
||||
|
||||
if( UNIX )
|
||||
find_package( Backtrace )
|
||||
if(Backtrace_FOUND)
|
||||
set( ZDOOM_LIBS ${ZDOOM_LIBS} ${Backtrace_LIBRARIES} )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
target_link_libraries( zdoom ${ZDOOM_LIBS} gdtoa dumb lzma )
|
||||
|
||||
include_directories( .
|
||||
|
@ -1422,7 +1445,7 @@ source_group("External\\RapidJSON" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_D
|
|||
source_group("External\\SFMT" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/sfmt/.+")
|
||||
source_group("FraggleScript" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/fragglescript/.+")
|
||||
source_group("Intermission" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/intermission/.+")
|
||||
source_group("Inventory" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/g_inventory/.+")
|
||||
source_group("Map Loader" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/maploader/.+")
|
||||
source_group("Menu" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/menu/.+")
|
||||
source_group("Hardware Renderer" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/.+")
|
||||
source_group("Hardware Renderer\\Data" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/hwrenderer/data/.+")
|
||||
|
|
15
src/actor.h
15
src/actor.h
|
@ -742,11 +742,6 @@ public:
|
|||
bool CallOkayToSwitchTarget(AActor *other);
|
||||
bool OkayToSwitchTarget (AActor *other);
|
||||
|
||||
// Note: Although some of the inventory functions are virtual, this
|
||||
// is not exposed to scripts, as the only class overriding them is
|
||||
// APlayerPawn for some specific handling for players. None of this
|
||||
// should ever be overridden by custom classes.
|
||||
|
||||
// Uses an item and removes it from the inventory.
|
||||
bool UseInventory (AActor *item);
|
||||
|
||||
|
@ -821,7 +816,9 @@ public:
|
|||
void Crash();
|
||||
|
||||
// Return starting health adjusted by skill level
|
||||
double AttackOffset(double offset = 0);
|
||||
int SpawnHealth() const;
|
||||
virtual int GetMaxHealth(bool withupgrades = false) const;
|
||||
int GetGibHealth() const;
|
||||
double GetCameraHeight() const;
|
||||
|
||||
|
@ -1106,7 +1103,7 @@ public:
|
|||
int32_t threshold; // if > 0, the target will be chased
|
||||
int32_t DefThreshold; // [MC] Default threshold which the actor will reset its threshold to after switching targets
|
||||
// no matter what (even if shot)
|
||||
player_t *player; // only valid if type of APlayerPawn
|
||||
player_t *player; // only valid if type of PlayerPawn
|
||||
TObjPtr<AActor*> LastLookActor; // Actor last looked for (if TIDtoHate != 0)
|
||||
DVector3 SpawnPoint; // For nightmare respawn
|
||||
uint16_t SpawnAngle;
|
||||
|
@ -1235,7 +1232,7 @@ public:
|
|||
DVector3 Prev;
|
||||
DRotator PrevAngles;
|
||||
int PrevPortalGroup;
|
||||
TArray<TObjPtr<AActor*> > AttachedLights;
|
||||
TArray<FDynamicLight *> AttachedLights;
|
||||
|
||||
// When was this actor spawned?
|
||||
int SpawnTime;
|
||||
|
@ -1489,13 +1486,11 @@ public:
|
|||
|
||||
int ApplyDamageFactor(FName damagetype, int damage) const;
|
||||
int GetModifiedDamage(FName damagetype, int damage, bool passive);
|
||||
|
||||
void DeleteAttachedLights();
|
||||
static void DeleteAllAttachedLights();
|
||||
static void RecreateAllAttachedLights();
|
||||
|
||||
bool hasmodel;
|
||||
|
||||
size_t PropagateMark();
|
||||
};
|
||||
|
||||
class FActorIterator
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "actor.h"
|
||||
#include "r_defs.h"
|
||||
#include "g_levellocals.h"
|
||||
#include "d_player.h"
|
||||
// These depend on both actor.h and r_defs.h so they cannot be in either file without creating a circular dependency.
|
||||
|
||||
inline DVector3 AActor::PosRelative(int portalgroup) const
|
||||
|
@ -79,3 +80,16 @@ inline double AActor::GetGravity() const
|
|||
if (flags & MF_NOGRAVITY) return 0;
|
||||
return level.gravity * Sector->gravity * Gravity * 0.00125;
|
||||
}
|
||||
|
||||
inline double AActor::AttackOffset(double offset)
|
||||
{
|
||||
if (player != NULL)
|
||||
{
|
||||
return (FloatVar(NAME_AttackZOffset) + offset) * player->crouchfactor;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 8 + offset;
|
||||
}
|
||||
|
||||
}
|
|
@ -150,7 +150,7 @@ void VerifyTargetChain(AActor *self, bool preciseMissileCheck)
|
|||
{
|
||||
// if any of the actors from self to (inclusive) origin match the next actor,
|
||||
// self has reached/created a loop
|
||||
self->target = NULL;
|
||||
self->target = nullptr;
|
||||
return;
|
||||
}
|
||||
if (compare == origin) break; // when "compare" = origin, we know that the next actor is, and should be "next"
|
||||
|
@ -176,7 +176,7 @@ void VerifyMasterChain(AActor *self)
|
|||
{
|
||||
if (compare == next)
|
||||
{
|
||||
self->master = NULL;
|
||||
self->master = nullptr;
|
||||
return;
|
||||
}
|
||||
if (compare == origin) break;
|
||||
|
@ -215,4 +215,4 @@ void ASSIGN_AAPTR(AActor *toActor, int toSlot, AActor *ptr, int flags)
|
|||
toActor->tracer = ptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,6 +83,7 @@ CVAR (Bool, am_customcolors, true, CVAR_ARCHIVE);
|
|||
CVAR (Int, am_map_secrets, 1, CVAR_ARCHIVE);
|
||||
CVAR (Int, am_drawmapback, 1, CVAR_ARCHIVE);
|
||||
CVAR (Bool, am_showkeys, true, CVAR_ARCHIVE);
|
||||
CVAR (Bool, am_showkeys_always, false, CVAR_ARCHIVE);
|
||||
CVAR (Int, am_showtriggerlines, 0, CVAR_ARCHIVE);
|
||||
CVAR (Int, am_showthingsprites, 0, CVAR_ARCHIVE);
|
||||
|
||||
|
@ -2333,10 +2334,9 @@ void AM_showSS()
|
|||
AM_drawSeg(sub->firstline + i, yellow);
|
||||
}
|
||||
|
||||
for (int i = 0; i <po_NumPolyobjs; i++)
|
||||
for (auto &poly : level.Polyobjects)
|
||||
{
|
||||
FPolyObj *po = &polyobjs[i];
|
||||
FPolyNode *pnode = po->subsectorlinks;
|
||||
FPolyNode *pnode = poly.subsectorlinks;
|
||||
|
||||
while (pnode != NULL)
|
||||
{
|
||||
|
@ -3057,7 +3057,7 @@ void AM_drawThings ()
|
|||
// That is the case for all default keys, however.
|
||||
if (t->IsKindOf(NAME_Key))
|
||||
{
|
||||
if (G_SkillProperty(SKILLP_EasyKey))
|
||||
if (G_SkillProperty(SKILLP_EasyKey) || am_showkeys_always)
|
||||
{
|
||||
// Already drawn by AM_drawKeys(), so don't draw again
|
||||
color.Index = -1;
|
||||
|
@ -3284,7 +3284,7 @@ void AM_Drawer (int bottom)
|
|||
|
||||
AM_drawWalls(allmap);
|
||||
AM_drawPlayers();
|
||||
if (G_SkillProperty(SKILLP_EasyKey))
|
||||
if (G_SkillProperty(SKILLP_EasyKey) || am_showkeys_always)
|
||||
AM_drawKeys();
|
||||
if ((am_cheat >= 2 && am_cheat != 4) || allthings)
|
||||
AM_drawThings();
|
||||
|
|
|
@ -71,14 +71,14 @@ DBot::DBot ()
|
|||
|
||||
void DBot::Clear ()
|
||||
{
|
||||
player = NULL;
|
||||
player = nullptr;
|
||||
Angle = 0.;
|
||||
dest = NULL;
|
||||
prev = NULL;
|
||||
enemy = NULL;
|
||||
missile = NULL;
|
||||
mate = NULL;
|
||||
last_mate = NULL;
|
||||
dest = nullptr;
|
||||
prev = nullptr;
|
||||
enemy = nullptr;
|
||||
missile = nullptr;
|
||||
mate = nullptr;
|
||||
last_mate = nullptr;
|
||||
memset(&skill, 0, sizeof(skill));
|
||||
t_active = 0;
|
||||
t_respawn = 0;
|
||||
|
@ -138,7 +138,7 @@ void DBot::Tick ()
|
|||
{
|
||||
Super::Tick ();
|
||||
|
||||
if (player->mo == NULL || bglobal.freeze)
|
||||
if (player->mo == nullptr || bglobal.freeze)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -176,7 +176,7 @@ CCMD (addbot)
|
|||
if (argv.argc() > 1)
|
||||
bglobal.SpawnBot (argv[1]);
|
||||
else
|
||||
bglobal.SpawnBot (NULL);
|
||||
bglobal.SpawnBot (nullptr);
|
||||
}
|
||||
|
||||
void FCajunMaster::ClearPlayer (int i, bool keepTeam)
|
||||
|
@ -184,7 +184,7 @@ void FCajunMaster::ClearPlayer (int i, bool keepTeam)
|
|||
if (players[i].mo)
|
||||
{
|
||||
players[i].mo->Destroy ();
|
||||
players[i].mo = NULL;
|
||||
players[i].mo = nullptr;
|
||||
}
|
||||
botinfo_t *bot = botinfo;
|
||||
while (bot && stricmp (players[i].userinfo.GetName(), bot->name))
|
||||
|
@ -194,10 +194,10 @@ void FCajunMaster::ClearPlayer (int i, bool keepTeam)
|
|||
bot->inuse = BOTINUSE_No;
|
||||
bot->lastteam = keepTeam ? players[i].userinfo.GetTeam() : TEAM_NONE;
|
||||
}
|
||||
if (players[i].Bot != NULL)
|
||||
if (players[i].Bot != nullptr)
|
||||
{
|
||||
players[i].Bot->Destroy ();
|
||||
players[i].Bot = NULL;
|
||||
players[i].Bot = nullptr;
|
||||
}
|
||||
players[i].~player_t();
|
||||
::new(&players[i]) player_t;
|
||||
|
@ -261,7 +261,7 @@ void InitBotStuff()
|
|||
while (sc.GetString())
|
||||
{
|
||||
PClassActor *wcls = PClass::FindActor(sc.String);
|
||||
if (wcls != NULL && wcls->IsDescendantOf(NAME_Weapon))
|
||||
if (wcls != nullptr && wcls->IsDescendantOf(NAME_Weapon))
|
||||
{
|
||||
BotInfoData bi = {};
|
||||
sc.MustGetStringName(",");
|
||||
|
@ -306,7 +306,7 @@ void InitBotStuff()
|
|||
for(unsigned i=0;i<countof(warnbotmissiles);i++)
|
||||
{
|
||||
AActor *a = GetDefaultByName (warnbotmissiles[i]);
|
||||
if (a != NULL)
|
||||
if (a != nullptr)
|
||||
{
|
||||
a->flags3|=MF3_WARNBOT;
|
||||
}
|
||||
|
|
|
@ -351,7 +351,7 @@ AActor *DBot::Choose_Mate ()
|
|||
if (mate)
|
||||
{
|
||||
if (mate->health <= 0)
|
||||
mate = NULL;
|
||||
mate = nullptr;
|
||||
else
|
||||
last_mate = mate;
|
||||
}
|
||||
|
@ -361,7 +361,7 @@ AActor *DBot::Choose_Mate ()
|
|||
//Check old_mates status.
|
||||
if (last_mate)
|
||||
if (last_mate->health <= 0)
|
||||
last_mate = NULL;
|
||||
last_mate = nullptr;
|
||||
|
||||
target = NULL;
|
||||
closest_dist = FLT_MAX;
|
||||
|
|
|
@ -92,6 +92,7 @@ Everything that is changed is marked (maybe commented) with "Added by MC"
|
|||
#include "d_player.h"
|
||||
#include "events.h"
|
||||
#include "vm.h"
|
||||
#include "g_levellocals.h"
|
||||
|
||||
static FRandom pr_botspawn ("BotSpawn");
|
||||
|
||||
|
@ -173,12 +174,12 @@ void FCajunMaster::Main ()
|
|||
void FCajunMaster::Init ()
|
||||
{
|
||||
botnum = 0;
|
||||
firstthing = NULL;
|
||||
firstthing = nullptr;
|
||||
spawn_tries = 0;
|
||||
freeze = false;
|
||||
observer = false;
|
||||
body1 = NULL;
|
||||
body2 = NULL;
|
||||
body1 = nullptr;
|
||||
body2 = nullptr;
|
||||
|
||||
if (ctf && teamplay == false)
|
||||
teamplay = true; //Need teamplay for ctf. (which is not done yet)
|
||||
|
@ -447,7 +448,7 @@ void FCajunMaster::RemoveAllBots (bool fromlist)
|
|||
// [ZZ] run event hook
|
||||
E_PlayerDisconnected(i);
|
||||
//
|
||||
FBehavior::StaticStartTypedScripts (SCRIPT_Disconnect, players[i].mo, true, i, true);
|
||||
level.Behaviors.StartTypedScripts (SCRIPT_Disconnect, players[i].mo, true, i, true);
|
||||
ClearPlayer (i, !fromlist);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ void DBot::Think ()
|
|||
memset (cmd, 0, sizeof(*cmd));
|
||||
|
||||
if (enemy && enemy->health <= 0)
|
||||
enemy = NULL;
|
||||
enemy = nullptr;
|
||||
|
||||
if (player->mo->health > 0) //Still alive
|
||||
{
|
||||
|
@ -121,7 +121,7 @@ void DBot::ThinkForMove (ticcmd_t *cmd)
|
|||
(!missile->Vel.X || !missile->Vel.Y || !Check_LOS(missile, SHOOTFOV*3/2)))
|
||||
{
|
||||
sleft = !sleft;
|
||||
missile = NULL; //Probably ended its travel.
|
||||
missile = nullptr; //Probably ended its travel.
|
||||
}
|
||||
|
||||
#if 0 // this has always been broken and without any reference it cannot be fixed.
|
||||
|
@ -183,7 +183,7 @@ void DBot::ThinkForMove (ticcmd_t *cmd)
|
|||
}
|
||||
}
|
||||
|
||||
dest = NULL; //To let bot turn right
|
||||
dest = nullptr; //To let bot turn right
|
||||
|
||||
if (GetBotInfo(player->ReadyWeapon).MoveCombatDist == 0)
|
||||
player->mo->flags &= ~MF_DROPOFF; //Don't jump off any ledges when fighting.
|
||||
|
@ -237,7 +237,7 @@ void DBot::ThinkForMove (ticcmd_t *cmd)
|
|||
{
|
||||
if (mate == dest && pr_botmove.Random() < 32)
|
||||
{ // [RH] If the mate is the dest, pick a new dest sometimes
|
||||
dest = NULL;
|
||||
dest = nullptr;
|
||||
}
|
||||
goto roam;
|
||||
}
|
||||
|
@ -264,7 +264,7 @@ void DBot::ThinkForMove (ticcmd_t *cmd)
|
|||
|
||||
if (dest && !(dest->flags&MF_SPECIAL) && dest->health < 0)
|
||||
{ //Roaming after something dead.
|
||||
dest = NULL;
|
||||
dest = nullptr;
|
||||
}
|
||||
|
||||
if (dest == NULL)
|
||||
|
@ -333,7 +333,7 @@ void DBot::ThinkForMove (ticcmd_t *cmd)
|
|||
if (!t_roam && dest)
|
||||
{
|
||||
prev = dest;
|
||||
dest = NULL;
|
||||
dest = nullptr;
|
||||
}
|
||||
|
||||
if (t_fight<(AFTERTICS/2))
|
||||
|
@ -342,7 +342,7 @@ void DBot::ThinkForMove (ticcmd_t *cmd)
|
|||
old = player->mo->Pos();
|
||||
}
|
||||
|
||||
int P_GetRealMaxHealth(APlayerPawn *actor, int max);
|
||||
int P_GetRealMaxHealth(AActor *actor, int max);
|
||||
|
||||
//BOT_WhatToGet
|
||||
//
|
||||
|
@ -438,5 +438,5 @@ void DBot::Set_enemy ()
|
|||
}
|
||||
//Verify that that enemy is really something alive that bot can kill.
|
||||
if (enemy && ((enemy->health < 0 || !(enemy->flags&MF_SHOOTABLE)) || player->mo->IsFriend(enemy)))
|
||||
enemy = NULL;
|
||||
enemy = nullptr;
|
||||
}
|
||||
|
|
158
src/c_bind.cpp
158
src/c_bind.cpp
|
@ -55,100 +55,100 @@ const char *KeyNames[NUM_KEYS] =
|
|||
// DirectInput codes and assume a qwerty keyboard layout.
|
||||
// See <dinput.h> for the DIK_* codes
|
||||
|
||||
NULL, "escape", "1", "2", "3", "4", "5", "6", //00
|
||||
"7", "8", "9", "0", "-", "=", "backspace","tab", //08
|
||||
"q", "w", "e", "r", "t", "y", "u", "i", //10
|
||||
"o", "p", "[", "]", "enter", "ctrl", "a", "s", //18
|
||||
"d", "f", "g", "h", "j", "k", "l", ";", //20
|
||||
"'", "`", "shift", "\\", "z", "x", "c", "v", //28
|
||||
"b", "n", "m", ",", ".", "/", "rshift", "kp*", //30
|
||||
"alt", "space", "capslock", "f1", "f2", "f3", "f4", "f5", //38
|
||||
"f6", "f7", "f8", "f9", "f10", "numlock", "scroll", "kp7", //40
|
||||
"kp8", "kp9", "kp-", "kp4", "kp5", "kp6", "kp+", "kp1", //48
|
||||
"kp2", "kp3", "kp0", "kp.", NULL, NULL, "oem102", "f11", //50
|
||||
"f12", NULL, NULL, NULL, NULL, NULL, NULL, NULL, //58
|
||||
NULL, NULL, NULL, NULL, "f13", "f14", "f15", "f16", //60
|
||||
NULL, "Escape", "1", "2", "3", "4", "5", "6", //00
|
||||
"7", "8", "9", "0", "-", "=", "Backspace","Tab", //08
|
||||
"Q", "W", "E", "R", "T", "Y", "U", "I", //10
|
||||
"O", "P", "[", "]", "Enter", "Ctrl", "A", "S", //18
|
||||
"D", "F", "G", "H", "J", "K", "L", ";", //20
|
||||
"'", "`", "Shift", "\\", "Z", "X", "C", "V", //28
|
||||
"B", "N", "M", ",", ".", "/", "RShift", "KP*", //30
|
||||
"Alt", "Space", "CapsLock", "F1", "F2", "F3", "F4", "F5", //38
|
||||
"F6", "F7", "F8", "F9", "F10", "NumLock", "Scroll", "KP7", //40
|
||||
"KP8", "KP9", "KP-", "KP4", "KP5", "KP6", "KP+", "KP1", //48
|
||||
"KP2", "KP3", "KP0", "KP.", NULL, NULL, "OEM102", "F11", //50
|
||||
"F12", NULL, NULL, NULL, NULL, NULL, NULL, NULL, //58
|
||||
NULL, NULL, NULL, NULL, "F13", "F14", "F15", "F16", //60
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, //68
|
||||
"kana", NULL, NULL, "abnt_c1", NULL, NULL, NULL, NULL, //70
|
||||
NULL, "convert", NULL, "noconvert",NULL, "yen", "abnt_c2", NULL, //78
|
||||
"Kana", NULL, NULL, "Abnt_C1", NULL, NULL, NULL, NULL, //70
|
||||
NULL, "Convert", NULL, "NoConvert",NULL, "Yen", "Abnt_C2", NULL, //78
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, //80
|
||||
NULL, NULL, NULL, NULL, NULL, "kp=", NULL, NULL, //88
|
||||
"circumflex","@", ":", "_", "kanji", "stop", "ax", "unlabeled",//90
|
||||
NULL, "prevtrack",NULL, NULL, "kp-enter", "rctrl", NULL, NULL, //98
|
||||
"mute", "calculator","play", NULL, "stop", NULL, NULL, NULL, //A0
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, "voldown", NULL, //A8
|
||||
"volup", NULL, "webhome", "kp,", NULL, "kp/", NULL, "sysrq", //B0
|
||||
"ralt", NULL, NULL, NULL, NULL, NULL, NULL, NULL, //B8
|
||||
NULL, NULL, NULL, NULL, NULL, "pause", NULL, "home", //C0
|
||||
"uparrow", "pgup", NULL, "leftarrow",NULL, "rightarrow",NULL, "end", //C8
|
||||
"downarrow","pgdn", "ins", "del", NULL, NULL, NULL, NULL, //D0
|
||||
NULL, NULL, NULL, NULL, NULL, "KP=", NULL, NULL, //88
|
||||
"Circumflex","@", ":", "_", "Kanji", "Stop", "Ax", "Unlabeled",//90
|
||||
NULL, "PrevTrack",NULL, NULL, "KP-Enter", "RCtrl", NULL, NULL, //98
|
||||
"Mute", "Calculator","Play", NULL, "Stop", NULL, NULL, NULL, //A0
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, "VolDown", NULL, //A8
|
||||
"VolUp", NULL, "WebHome", "KP,", NULL, "KP/", NULL, "SysRq", //B0
|
||||
"RAlt", NULL, NULL, NULL, NULL, NULL, NULL, NULL, //B8
|
||||
NULL, NULL, NULL, NULL, NULL, "Pause", NULL, "Home", //C0
|
||||
"UpArrow", "PgUp", NULL, "LeftArrow",NULL, "RightArrow",NULL, "End", //C8
|
||||
"DownArrow","PgDn", "Ins", "Del", NULL, NULL, NULL, NULL, //D0
|
||||
#ifdef __APPLE__
|
||||
NULL, NULL, NULL, "command", NULL, "apps", "power", "sleep", //D8
|
||||
NULL, NULL, NULL, "Command", NULL, "Apps", "Power", "Sleep", //D8
|
||||
#else // !__APPLE__
|
||||
NULL, NULL, NULL, "lwin", "rwin", "apps", "power", "sleep", //D8
|
||||
NULL, NULL, NULL, "LWin", "RWin", "Apps", "Power", "Sleep", //D8
|
||||
#endif // __APPLE__
|
||||
NULL, NULL, NULL, "wake", NULL, "search", "favorites","refresh", //E0
|
||||
"webstop", "webforward","webback", "mycomputer","mail", "mediaselect",NULL, NULL, //E8
|
||||
NULL, NULL, NULL, "Wake", NULL, "Search", "Favorites","Refresh", //E0
|
||||
"WebStop", "WebForward","WebBack", "MyComputer","Mail", "MediaSelect",NULL, NULL, //E8
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, //F0
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, //F8
|
||||
|
||||
// non-keyboard buttons that can be bound
|
||||
"mouse1", "mouse2", "mouse3", "mouse4", // 8 mouse buttons
|
||||
"mouse5", "mouse6", "mouse7", "mouse8",
|
||||
"Mouse1", "Mouse2", "Mouse3", "Mouse4", // 8 mouse buttons
|
||||
"Mouse5", "Mouse6", "Mouse7", "Mouse8",
|
||||
|
||||
"joy1", "joy2", "joy3", "joy4", // 128 joystick buttons!
|
||||
"joy5", "joy6", "joy7", "joy8",
|
||||
"joy9", "joy10", "joy11", "joy12",
|
||||
"joy13", "joy14", "joy15", "joy16",
|
||||
"joy17", "joy18", "joy19", "joy20",
|
||||
"joy21", "joy22", "joy23", "joy24",
|
||||
"joy25", "joy26", "joy27", "joy28",
|
||||
"joy29", "joy30", "joy31", "joy32",
|
||||
"joy33", "joy34", "joy35", "joy36",
|
||||
"joy37", "joy38", "joy39", "joy40",
|
||||
"joy41", "joy42", "joy43", "joy44",
|
||||
"joy45", "joy46", "joy47", "joy48",
|
||||
"joy49", "joy50", "joy51", "joy52",
|
||||
"joy53", "joy54", "joy55", "joy56",
|
||||
"joy57", "joy58", "joy59", "joy60",
|
||||
"joy61", "joy62", "joy63", "joy64",
|
||||
"joy65", "joy66", "joy67", "joy68",
|
||||
"joy69", "joy70", "joy71", "joy72",
|
||||
"joy73", "joy74", "joy75", "joy76",
|
||||
"joy77", "joy78", "joy79", "joy80",
|
||||
"joy81", "joy82", "joy83", "joy84",
|
||||
"joy85", "joy86", "joy87", "joy88",
|
||||
"joy89", "joy90", "joy91", "joy92",
|
||||
"joy93", "joy94", "joy95", "joy96",
|
||||
"joy97", "joy98", "joy99", "joy100",
|
||||
"joy101", "joy102", "joy103", "joy104",
|
||||
"joy105", "joy106", "joy107", "joy108",
|
||||
"joy109", "joy110", "joy111", "joy112",
|
||||
"joy113", "joy114", "joy115", "joy116",
|
||||
"joy117", "joy118", "joy119", "joy120",
|
||||
"joy121", "joy122", "joy123", "joy124",
|
||||
"joy125", "joy126", "joy127", "joy128",
|
||||
"Joy1", "Joy2", "Joy3", "Joy4", // 128 joystick buttons!
|
||||
"Joy5", "Joy6", "Joy7", "Joy8",
|
||||
"Joy9", "Joy10", "Joy11", "Joy12",
|
||||
"Joy13", "Joy14", "Joy15", "Joy16",
|
||||
"Joy17", "Joy18", "Joy19", "Joy20",
|
||||
"Joy21", "Joy22", "Joy23", "Joy24",
|
||||
"Joy25", "Joy26", "Joy27", "Joy28",
|
||||
"Joy29", "Joy30", "Joy31", "Joy32",
|
||||
"Joy33", "Joy34", "Joy35", "Joy36",
|
||||
"Joy37", "Joy38", "Joy39", "Joy40",
|
||||
"Joy41", "Joy42", "Joy43", "Joy44",
|
||||
"Joy45", "Joy46", "Joy47", "Joy48",
|
||||
"Joy49", "Joy50", "Joy51", "Joy52",
|
||||
"Joy53", "Joy54", "Joy55", "Joy56",
|
||||
"Joy57", "Joy58", "Joy59", "Joy60",
|
||||
"Joy61", "Joy62", "Joy63", "Joy64",
|
||||
"Joy65", "Joy66", "Joy67", "Joy68",
|
||||
"Joy69", "Joy70", "Joy71", "Joy72",
|
||||
"Joy73", "Joy74", "Joy75", "Joy76",
|
||||
"Joy77", "Joy78", "Joy79", "Joy80",
|
||||
"Joy81", "Joy82", "Joy83", "Joy84",
|
||||
"Joy85", "Joy86", "Joy87", "Joy88",
|
||||
"Joy89", "Joy90", "Joy91", "Joy92",
|
||||
"Joy93", "Joy94", "Joy95", "Joy96",
|
||||
"Joy97", "Joy98", "Joy99", "Joy100",
|
||||
"Joy101", "Joy102", "Joy103", "Joy104",
|
||||
"Joy105", "Joy106", "Joy107", "Joy108",
|
||||
"Joy109", "Joy110", "Joy111", "Joy112",
|
||||
"Joy113", "Joy114", "Joy115", "Joy116",
|
||||
"Joy117", "Joy118", "Joy119", "Joy120",
|
||||
"Joy121", "Joy122", "Joy123", "Joy124",
|
||||
"Joy125", "Joy126", "Joy127", "Joy128",
|
||||
|
||||
"pov1up", "pov1right","pov1down", "pov1left", // First POV hat
|
||||
"pov2up", "pov2right","pov2down", "pov2left", // Second POV hat
|
||||
"pov3up", "pov3right","pov3down", "pov3left", // Third POV hat
|
||||
"pov4up", "pov4right","pov4down", "pov4left", // Fourth POV hat
|
||||
"POV1Up", "POV1Right","POV1Down", "POV1Left", // First POV hat
|
||||
"POV2Up", "POV2Right","POV2Down", "POV2Left", // Second POV hat
|
||||
"POV3Up", "POV3Right","POV3Down", "POV3Left", // Third POV hat
|
||||
"POV4Up", "POV4Right","POV4Down", "POV4Left", // Fourth POV hat
|
||||
|
||||
"mwheelup", "mwheeldown", // the mouse wheel
|
||||
"mwheelright", "mwheelleft",
|
||||
"MWheelUp", "MWheelDown", // the mouse wheel
|
||||
"MWheelRight", "MWheelLeft",
|
||||
|
||||
"axis1plus","axis1minus","axis2plus","axis2minus", // joystick axes as buttons
|
||||
"axis3plus","axis3minus","axis4plus","axis4minus",
|
||||
"axis5plus","axis5minus","axis6plus","axis6minus",
|
||||
"axis7plus","axis7minus","axis8plus","axis8minus",
|
||||
"Axis1Plus","Axis1Minus","Axis2Plus","Axis2Minus", // joystick axes as buttons
|
||||
"Axis3Plus","Axis3Minus","Axis4Plus","Axis4Minus",
|
||||
"Axis5Plus","Axis5Minus","Axis6Plus","Axis6Minus",
|
||||
"Axis7Plus","Axis7Minus","Axis8Plus","Axis8Minus",
|
||||
|
||||
"lstickright","lstickleft","lstickdown","lstickup", // Gamepad axis-based buttons
|
||||
"rstickright","rstickleft","rstickdown","rstickup",
|
||||
"LStickRight","LStickLeft","LStickDown","LStickUp", // Gamepad axis-based buttons
|
||||
"RStickRight","RStickLeft","RStickDown","RStickUp",
|
||||
|
||||
"dpadup","dpaddown","dpadleft","dpadright", // Gamepad buttons
|
||||
"pad_start","pad_back","lthumb","rthumb",
|
||||
"lshoulder","rshoulder","ltrigger","rtrigger",
|
||||
"pad_a", "pad_b", "pad_x", "pad_y"
|
||||
"DPadUp","DPadDown","DPadLeft","DPadRight", // Gamepad buttons
|
||||
"Pad_Start","Pad_Back","LThumb","RThumb",
|
||||
"LShoulder","RShoulder","LTrigger","RTrigger",
|
||||
"Pad_A", "Pad_B", "Pad_X", "Pad_Y"
|
||||
};
|
||||
|
||||
FKeyBindings Bindings;
|
||||
|
|
|
@ -74,6 +74,7 @@ extern bool insave;
|
|||
|
||||
CVAR (Bool, sv_cheats, false, CVAR_SERVERINFO | CVAR_LATCH)
|
||||
CVAR (Bool, sv_unlimited_pickup, false, CVAR_SERVERINFO)
|
||||
CVAR (Bool, cl_blockcheats, false, 0)
|
||||
|
||||
CCMD (toggleconsole)
|
||||
{
|
||||
|
@ -87,6 +88,11 @@ bool CheckCheatmode (bool printmsg)
|
|||
if (printmsg) Printf ("sv_cheats must be true to enable this command.\n");
|
||||
return true;
|
||||
}
|
||||
else if (cl_blockcheats)
|
||||
{
|
||||
if (printmsg) Printf ("cl_blockcheats is turned on and disabled this command.\n");
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
|
|
|
@ -629,7 +629,7 @@ void C_DeinitConsole ()
|
|||
while (cmd != NULL)
|
||||
{
|
||||
GameAtExit *next = cmd->Next;
|
||||
AddCommandString (cmd->Command.LockBuffer());
|
||||
AddCommandString (cmd->Command);
|
||||
delete cmd;
|
||||
cmd = next;
|
||||
}
|
||||
|
@ -1559,17 +1559,9 @@ static bool C_HandleKey (event_t *ev, FCommandBuffer &buffer)
|
|||
{
|
||||
// Work with a copy of command to avoid side effects caused by
|
||||
// exception raised during execution, like with 'error' CCMD.
|
||||
// It's problematic to maintain FString's lock symmetry.
|
||||
static TArray<char> command;
|
||||
const size_t length = buffer.Text.Len();
|
||||
|
||||
command.Resize(unsigned(length + 1));
|
||||
memcpy(&command[0], buffer.Text.GetChars(), length);
|
||||
command[length] = '\0';
|
||||
|
||||
FString copy = buffer.Text;
|
||||
buffer.SetString("");
|
||||
|
||||
AddCommandString(&command[0]);
|
||||
AddCommandString(copy);
|
||||
}
|
||||
TabbedLast = false;
|
||||
TabbedList = false;
|
||||
|
|
|
@ -59,38 +59,122 @@
|
|||
|
||||
// TYPES -------------------------------------------------------------------
|
||||
|
||||
class DWaitingCommand : public DThinker
|
||||
class UnsafeExecutionScope
|
||||
{
|
||||
DECLARE_CLASS (DWaitingCommand, DThinker)
|
||||
const bool wasEnabled;
|
||||
|
||||
public:
|
||||
DWaitingCommand (const char *cmd, int tics, bool unsafe);
|
||||
~DWaitingCommand ();
|
||||
void Serialize(FSerializer &arc);
|
||||
void Tick ();
|
||||
explicit UnsafeExecutionScope(const bool enable = true)
|
||||
: wasEnabled(UnsafeExecutionContext)
|
||||
{
|
||||
UnsafeExecutionContext = enable;
|
||||
}
|
||||
|
||||
private:
|
||||
DWaitingCommand ();
|
||||
~UnsafeExecutionScope()
|
||||
{
|
||||
UnsafeExecutionContext = wasEnabled;
|
||||
}
|
||||
};
|
||||
|
||||
char *Command;
|
||||
class FDelayedCommand
|
||||
{
|
||||
public:
|
||||
virtual ~FDelayedCommand() {}
|
||||
|
||||
protected:
|
||||
virtual bool Tick() = 0;
|
||||
|
||||
friend class FDelayedCommandQueue;
|
||||
};
|
||||
|
||||
class FWaitingCommand : public FDelayedCommand
|
||||
{
|
||||
public:
|
||||
FWaitingCommand(const char *cmd, int tics, bool unsafe)
|
||||
: Command(cmd), TicsLeft(tics+1), IsUnsafe(unsafe)
|
||||
{}
|
||||
|
||||
bool Tick() override
|
||||
{
|
||||
if (--TicsLeft == 0)
|
||||
{
|
||||
UnsafeExecutionScope scope(IsUnsafe);
|
||||
AddCommandString(Command);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
FString Command;
|
||||
int TicsLeft;
|
||||
bool IsUnsafe;
|
||||
};
|
||||
|
||||
class DStoredCommand : public DThinker
|
||||
class FStoredCommand : public FDelayedCommand
|
||||
{
|
||||
DECLARE_CLASS (DStoredCommand, DThinker)
|
||||
public:
|
||||
DStoredCommand (FConsoleCommand *com, const char *cmd);
|
||||
~DStoredCommand ();
|
||||
void Tick ();
|
||||
FStoredCommand(FConsoleCommand *com, const char *cmd)
|
||||
: Command(com), Text(cmd)
|
||||
{}
|
||||
|
||||
bool Tick() override
|
||||
{
|
||||
if (Text.IsNotEmpty() && Command != nullptr)
|
||||
{
|
||||
FCommandLine args(Text);
|
||||
Command->Run(args, players[consoleplayer].mo, 0);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
DStoredCommand ();
|
||||
|
||||
FConsoleCommand *Command;
|
||||
char *Text;
|
||||
FString Text;
|
||||
};
|
||||
|
||||
class FDelayedCommandQueue
|
||||
{
|
||||
TDeletingArray<FDelayedCommand *> delayedCommands;
|
||||
public:
|
||||
void Run()
|
||||
{
|
||||
for (unsigned i = 0; i < delayedCommands.Size(); i++)
|
||||
{
|
||||
if (delayedCommands[i]->Tick())
|
||||
{
|
||||
delete delayedCommands[i];
|
||||
delayedCommands.Delete(i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
delayedCommands.DeleteAndClear();
|
||||
}
|
||||
|
||||
void AddCommand(FDelayedCommand * cmd)
|
||||
{
|
||||
delayedCommands.Push(cmd);
|
||||
}
|
||||
};
|
||||
|
||||
static FDelayedCommandQueue delayedCommandQueue;
|
||||
|
||||
void C_RunDelayedCommands()
|
||||
{
|
||||
delayedCommandQueue.Run();
|
||||
}
|
||||
|
||||
void C_ClearDelayedCommands()
|
||||
{
|
||||
delayedCommandQueue.Clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct FActionMap
|
||||
{
|
||||
FButtonStatus *Button;
|
||||
|
@ -127,22 +211,6 @@ FButtonStatus Button_Mlook, Button_Klook, Button_Use, Button_AltAttack,
|
|||
|
||||
bool ParsingKeyConf, UnsafeExecutionContext;
|
||||
|
||||
class UnsafeExecutionScope
|
||||
{
|
||||
const bool wasEnabled;
|
||||
|
||||
public:
|
||||
explicit UnsafeExecutionScope(const bool enable = true)
|
||||
: wasEnabled(UnsafeExecutionContext)
|
||||
{
|
||||
UnsafeExecutionContext = enable;
|
||||
}
|
||||
|
||||
~UnsafeExecutionScope()
|
||||
{
|
||||
UnsafeExecutionContext = wasEnabled;
|
||||
}
|
||||
};
|
||||
|
||||
// To add new actions, go to the console and type "key <action name>".
|
||||
// This will give you the key value to use in the first column. Then
|
||||
|
@ -205,79 +273,6 @@ static const char *KeyConfCommands[] =
|
|||
|
||||
// CODE --------------------------------------------------------------------
|
||||
|
||||
IMPLEMENT_CLASS(DWaitingCommand, false, false)
|
||||
|
||||
void DWaitingCommand::Serialize(FSerializer &arc)
|
||||
{
|
||||
Super::Serialize (arc);
|
||||
arc("command", Command)
|
||||
("ticsleft", TicsLeft)
|
||||
("unsafe", IsUnsafe);
|
||||
}
|
||||
|
||||
DWaitingCommand::DWaitingCommand ()
|
||||
{
|
||||
Command = NULL;
|
||||
TicsLeft = 1;
|
||||
IsUnsafe = false;
|
||||
}
|
||||
|
||||
DWaitingCommand::DWaitingCommand (const char *cmd, int tics, bool unsafe)
|
||||
{
|
||||
Command = copystring (cmd);
|
||||
TicsLeft = tics+1;
|
||||
IsUnsafe = unsafe;
|
||||
}
|
||||
|
||||
DWaitingCommand::~DWaitingCommand ()
|
||||
{
|
||||
if (Command != NULL)
|
||||
{
|
||||
delete[] Command;
|
||||
}
|
||||
}
|
||||
|
||||
void DWaitingCommand::Tick ()
|
||||
{
|
||||
if (--TicsLeft == 0)
|
||||
{
|
||||
UnsafeExecutionScope scope(IsUnsafe);
|
||||
AddCommandString (Command);
|
||||
Destroy ();
|
||||
}
|
||||
}
|
||||
|
||||
IMPLEMENT_CLASS(DStoredCommand, false, false)
|
||||
|
||||
DStoredCommand::DStoredCommand ()
|
||||
{
|
||||
Text = NULL;
|
||||
Destroy ();
|
||||
}
|
||||
|
||||
DStoredCommand::DStoredCommand (FConsoleCommand *command, const char *args)
|
||||
{
|
||||
Command = command;
|
||||
Text = copystring (args);
|
||||
}
|
||||
|
||||
DStoredCommand::~DStoredCommand ()
|
||||
{
|
||||
if (Text != NULL)
|
||||
{
|
||||
delete[] Text;
|
||||
}
|
||||
}
|
||||
|
||||
void DStoredCommand::Tick ()
|
||||
{
|
||||
if (Text != NULL && Command != NULL)
|
||||
{
|
||||
FCommandLine args (Text);
|
||||
Command->Run (args, players[consoleplayer].mo, 0);
|
||||
}
|
||||
Destroy ();
|
||||
}
|
||||
|
||||
static int ListActionCommands (const char *pattern)
|
||||
{
|
||||
|
@ -656,7 +651,8 @@ void C_DoCommand (const char *cmd, int keynum)
|
|||
}
|
||||
else
|
||||
{
|
||||
Create<DStoredCommand> (com, beg);
|
||||
auto cmd = new FStoredCommand(com, beg);
|
||||
delayedCommandQueue.AddCommand(cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -696,8 +692,12 @@ DEFINE_ACTION_FUNCTION(DOptionMenuItemCommand, DoCommand)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void AddCommandString (char *cmd, int keynum)
|
||||
void AddCommandString (const char *text, int keynum)
|
||||
{
|
||||
// Operate on a local copy instead of messing around with the data that's being passed in here.
|
||||
TArray<char> buffer(strlen(text) + 1, true);
|
||||
memcpy(buffer.Data(), text, buffer.Size());
|
||||
char *cmd = buffer.Data();
|
||||
char *brkpt;
|
||||
int more;
|
||||
|
||||
|
@ -752,7 +752,8 @@ void AddCommandString (char *cmd, int keynum)
|
|||
// Note that deferred commands lose track of which key
|
||||
// (if any) they were pressed from.
|
||||
*brkpt = ';';
|
||||
Create<DWaitingCommand> (brkpt, tics, UnsafeExecutionContext);
|
||||
auto cmd = new FWaitingCommand(brkpt, tics, UnsafeExecutionContext);
|
||||
delayedCommandQueue.AddCommand(cmd);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -1039,12 +1040,12 @@ FConsoleCommand::~FConsoleCommand ()
|
|||
delete[] m_Name;
|
||||
}
|
||||
|
||||
void FConsoleCommand::Run (FCommandLine &argv, APlayerPawn *who, int key)
|
||||
void FConsoleCommand::Run (FCommandLine &argv, AActor *who, int key)
|
||||
{
|
||||
m_RunFunc (argv, who, key);
|
||||
}
|
||||
|
||||
void FUnsafeConsoleCommand::Run (FCommandLine &args, APlayerPawn *instigator, int key)
|
||||
void FUnsafeConsoleCommand::Run (FCommandLine &args, AActor *instigator, int key)
|
||||
{
|
||||
if (UnsafeExecutionContext)
|
||||
{
|
||||
|
@ -1455,7 +1456,7 @@ bool FConsoleAlias::IsAlias ()
|
|||
return true;
|
||||
}
|
||||
|
||||
void FConsoleAlias::Run (FCommandLine &args, APlayerPawn *who, int key)
|
||||
void FConsoleAlias::Run (FCommandLine &args, AActor *who, int key)
|
||||
{
|
||||
if (bRunning)
|
||||
{
|
||||
|
@ -1477,8 +1478,7 @@ void FConsoleAlias::Run (FCommandLine &args, APlayerPawn *who, int key)
|
|||
}
|
||||
|
||||
bRunning = true;
|
||||
AddCommandString (mycommand.LockBuffer(), key);
|
||||
mycommand.UnlockBuffer();
|
||||
AddCommandString (mycommand, key);
|
||||
bRunning = false;
|
||||
if (m_Command[index].IsEmpty())
|
||||
{ // The alias is unchanged, so put the command back so it can be used again.
|
||||
|
@ -1519,7 +1519,7 @@ void FConsoleAlias::SafeDelete ()
|
|||
}
|
||||
}
|
||||
|
||||
void FUnsafeConsoleAlias::Run (FCommandLine &args, APlayerPawn *instigator, int key)
|
||||
void FUnsafeConsoleAlias::Run (FCommandLine &args, AActor *instigator, int key)
|
||||
{
|
||||
UnsafeExecutionScope scope;
|
||||
FConsoleAlias::Run(args, instigator, key);
|
||||
|
@ -1554,8 +1554,7 @@ void FExecList::ExecCommands() const
|
|||
{
|
||||
for (unsigned i = 0; i < Commands.Size(); ++i)
|
||||
{
|
||||
AddCommandString(Commands[i].LockBuffer());
|
||||
Commands[i].UnlockBuffer();
|
||||
AddCommandString(Commands[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
#include "doomtype.h"
|
||||
|
||||
class FConfigFile;
|
||||
class APlayerPawn;
|
||||
|
||||
// Class that can parse command lines
|
||||
class FCommandLine
|
||||
|
@ -78,7 +77,10 @@ FExecList *C_ParseCmdLineParams(FExecList *exec);
|
|||
// and semicolon-separated commands. This function may modify the source
|
||||
// string, but the string will be restored to its original state before
|
||||
// returning. Therefore, commands passed must not be in read-only memory.
|
||||
void AddCommandString (char *text, int keynum=0);
|
||||
void AddCommandString (const char *text, int keynum=0);
|
||||
|
||||
void C_RunDelayedCommands();
|
||||
void C_ClearDelayedCommands();
|
||||
|
||||
// Process a single console command. Does not handle wait.
|
||||
void C_DoCommand (const char *cmd, int keynum=0);
|
||||
|
@ -96,7 +98,8 @@ void C_ClearAliases ();
|
|||
// build a single string out of multiple strings
|
||||
FString BuildString (int argc, FString *argv);
|
||||
|
||||
typedef void (*CCmdRun) (FCommandLine &argv, APlayerPawn *instigator, int key);
|
||||
class AActor;
|
||||
typedef void (*CCmdRun) (FCommandLine &argv, AActor *instigator, int key);
|
||||
|
||||
class FConsoleCommand
|
||||
{
|
||||
|
@ -106,7 +109,7 @@ public:
|
|||
virtual bool IsAlias ();
|
||||
void PrintCommand () { Printf ("%s\n", m_Name); }
|
||||
|
||||
virtual void Run (FCommandLine &args, APlayerPawn *instigator, int key);
|
||||
virtual void Run (FCommandLine &args, AActor *instigator, int key);
|
||||
static FConsoleCommand* FindByName (const char* name);
|
||||
|
||||
FConsoleCommand *m_Next, **m_Prev;
|
||||
|
@ -123,9 +126,9 @@ protected:
|
|||
};
|
||||
|
||||
#define CCMD(n) \
|
||||
void Cmd_##n (FCommandLine &, APlayerPawn *, int key); \
|
||||
void Cmd_##n (FCommandLine &, AActor *, int key); \
|
||||
FConsoleCommand Cmd_##n##_Ref (#n, Cmd_##n); \
|
||||
void Cmd_##n (FCommandLine &argv, APlayerPawn *who, int key)
|
||||
void Cmd_##n (FCommandLine &argv, AActor *who, int key)
|
||||
|
||||
class FUnsafeConsoleCommand : public FConsoleCommand
|
||||
{
|
||||
|
@ -135,13 +138,13 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
virtual void Run (FCommandLine &args, APlayerPawn *instigator, int key) override;
|
||||
virtual void Run (FCommandLine &args, AActor *instigator, int key) override;
|
||||
};
|
||||
|
||||
#define UNSAFE_CCMD(n) \
|
||||
static void Cmd_##n (FCommandLine &, APlayerPawn *, int key); \
|
||||
static void Cmd_##n (FCommandLine &, AActor *, int key); \
|
||||
static FUnsafeConsoleCommand Cmd_##n##_Ref (#n, Cmd_##n); \
|
||||
void Cmd_##n (FCommandLine &argv, APlayerPawn *who, int key)
|
||||
void Cmd_##n (FCommandLine &argv, AActor *who, int key)
|
||||
|
||||
const int KEY_DBLCLICKED = 0x8000;
|
||||
|
||||
|
@ -150,7 +153,7 @@ class FConsoleAlias : public FConsoleCommand
|
|||
public:
|
||||
FConsoleAlias (const char *name, const char *command, bool noSave);
|
||||
~FConsoleAlias ();
|
||||
void Run (FCommandLine &args, APlayerPawn *Instigator, int key);
|
||||
void Run (FCommandLine &args, AActor *instigator, int key);
|
||||
bool IsAlias ();
|
||||
void PrintAlias ();
|
||||
void Archive (FConfigFile *f);
|
||||
|
@ -171,7 +174,7 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
virtual void Run (FCommandLine &args, APlayerPawn *instigator, int key) override;
|
||||
virtual void Run (FCommandLine &args, AActor *instigator, int key) override;
|
||||
};
|
||||
|
||||
// Actions
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
#ifndef COMPATIBILITY_H
|
||||
#define COMPATIBILITY_H
|
||||
|
||||
#include "doomtype.h"
|
||||
#include "tarray.h"
|
||||
#include "p_setup.h"
|
||||
|
||||
union FMD5Holder
|
||||
{
|
||||
uint8_t Bytes[16];
|
||||
uint32_t DWords[4];
|
||||
hash_t Hash;
|
||||
};
|
||||
|
||||
struct FCompatValues
|
||||
{
|
||||
int CompatFlags[3];
|
||||
unsigned int ExtCommandIndex;
|
||||
};
|
||||
|
||||
struct FMD5HashTraits
|
||||
{
|
||||
hash_t Hash(const FMD5Holder key)
|
||||
{
|
||||
return key.Hash;
|
||||
}
|
||||
int Compare(const FMD5Holder left, const FMD5Holder right)
|
||||
{
|
||||
return left.DWords[0] != right.DWords[0] ||
|
||||
left.DWords[1] != right.DWords[1] ||
|
||||
left.DWords[2] != right.DWords[2] ||
|
||||
left.DWords[3] != right.DWords[3];
|
||||
}
|
||||
};
|
||||
|
||||
extern TMap<FMD5Holder, FCompatValues, FMD5HashTraits> BCompatMap;
|
||||
|
||||
void ParseCompatibility();
|
||||
FName CheckCompatibility(MapData *map);
|
||||
void SetCompatibilityParams(FName);
|
||||
|
||||
#endif
|
|
@ -213,6 +213,7 @@ DEFINE_FIELD_X(DehInfo, DehInfo, ExplosionAlpha)
|
|||
DEFINE_FIELD_X(DehInfo, DehInfo, NoAutofreeze)
|
||||
DEFINE_FIELD_X(DehInfo, DehInfo, BFGCells)
|
||||
DEFINE_FIELD_X(DehInfo, DehInfo, BlueAC)
|
||||
DEFINE_FIELD_X(DehInfo, DehInfo, MaxHealth)
|
||||
|
||||
// Doom identified pickup items by their sprites. ZDoom prefers to use their
|
||||
// class type to identify them instead. To support the traditional Doom
|
||||
|
@ -807,6 +808,7 @@ void SetDehParams(FState *state, int codepointer)
|
|||
}
|
||||
fclose(dump);
|
||||
}
|
||||
#ifdef HAVE_VM_JIT
|
||||
if (Args->CheckParm("-dumpjit"))
|
||||
{
|
||||
FILE *dump = fopen("dumpjit.txt", "a");
|
||||
|
@ -816,6 +818,7 @@ void SetDehParams(FState *state, int codepointer)
|
|||
}
|
||||
fclose(dump);
|
||||
}
|
||||
#endif // HAVE_VM_JIT
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1988,7 +1991,7 @@ static int PatchMisc (int dummy)
|
|||
health->IntVar(NAME_Amount) = health->IntVar(NAME_MaxAmount) = deh.MegasphereHealth;
|
||||
}
|
||||
|
||||
APlayerPawn *player = static_cast<APlayerPawn *> (GetDefaultByName ("DoomPlayer"));
|
||||
AActor *player = GetDefaultByName ("DoomPlayer");
|
||||
if (player != NULL)
|
||||
{
|
||||
player->health = deh.StartHealth;
|
||||
|
|
|
@ -89,7 +89,6 @@
|
|||
#include "d_event.h"
|
||||
#include "d_netinf.h"
|
||||
#include "m_cheat.h"
|
||||
#include "compatibility.h"
|
||||
#include "m_joy.h"
|
||||
#include "po_man.h"
|
||||
#include "r_renderer.h"
|
||||
|
@ -750,8 +749,7 @@ void D_Display ()
|
|||
// Check for the presence of dynamic lights at the start of the frame once.
|
||||
if ((gl_lights && vid_rendermode == 4) || (r_dynlights && vid_rendermode != 4))
|
||||
{
|
||||
TThinkerIterator<ADynamicLight> it(STAT_DLIGHT);
|
||||
level.HasDynamicLights = !!it.Next();
|
||||
level.HasDynamicLights = !!level.lights;
|
||||
}
|
||||
else level.HasDynamicLights = false; // lights are off so effectively we have none.
|
||||
|
||||
|
@ -762,15 +760,15 @@ void D_Display ()
|
|||
{
|
||||
AM_Drawer (hud_althud? viewheight : StatusBar->GetTopOfStatusbar());
|
||||
}
|
||||
if (!automapactive || viewactive)
|
||||
{
|
||||
screen->RefreshViewBorder ();
|
||||
}
|
||||
|
||||
// for timing the statusbar code.
|
||||
//cycle_t stb;
|
||||
//stb.Reset();
|
||||
//stb.Clock();
|
||||
if (!automapactive || viewactive)
|
||||
{
|
||||
StatusBar->RefreshViewBorder ();
|
||||
}
|
||||
if (hud_althud && viewheight == SCREENHEIGHT && screenblocks > 10)
|
||||
{
|
||||
StatusBar->DrawBottomStuff (HUD_AltHud);
|
||||
|
@ -2432,8 +2430,6 @@ void D_DoomMain (void)
|
|||
StartScreen = new FStartupScreen(0);
|
||||
}
|
||||
|
||||
ParseCompatibility();
|
||||
|
||||
CheckCmdLine();
|
||||
|
||||
// [RH] Load sound environments
|
||||
|
@ -2583,7 +2579,7 @@ void D_DoomMain (void)
|
|||
// [RH] Run any saved commands from the command line or autoexec.cfg now.
|
||||
gamestate = GS_FULLCONSOLE;
|
||||
Net_NewMakeTic ();
|
||||
DThinker::RunThinkers ();
|
||||
C_RunDelayedCommands();
|
||||
gamestate = GS_STARTUP;
|
||||
|
||||
if (!restart)
|
||||
|
@ -2650,7 +2646,7 @@ void D_DoomMain (void)
|
|||
G_InitNew(startmap, false);
|
||||
if (StoredWarp.IsNotEmpty())
|
||||
{
|
||||
AddCommandString(StoredWarp.LockBuffer());
|
||||
AddCommandString(StoredWarp);
|
||||
StoredWarp = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -2702,7 +2698,6 @@ void D_DoomMain (void)
|
|||
DThinker::DestroyThinkersInList(STAT_STATIC);
|
||||
E_Shutdown(false);
|
||||
P_FreeLevelData();
|
||||
P_FreeExtraLevelData();
|
||||
|
||||
M_SaveDefaults(NULL); // save config before the restart
|
||||
|
||||
|
@ -2717,7 +2712,6 @@ void D_DoomMain (void)
|
|||
S_Shutdown(); // free all channels and delete playlist
|
||||
C_ClearAliases(); // CCMDs won't be reinitialized so these need to be deleted here
|
||||
DestroyCVarsFlagged(CVAR_MOD); // Delete any cvar left by mods
|
||||
FS_Close(); // destroy the global FraggleScript.
|
||||
DeinitMenus();
|
||||
LightDefaults.DeleteAndClear(); // this can leak heap memory if it isn't cleared.
|
||||
|
||||
|
|
|
@ -127,7 +127,7 @@ void G_BuildTiccmd (ticcmd_t *cmd);
|
|||
void D_DoAdvanceDemo (void);
|
||||
|
||||
static void SendSetup (uint32_t playersdetected[MAXNETNODES], uint8_t gotsetup[MAXNETNODES], int len);
|
||||
static void RunScript(uint8_t **stream, APlayerPawn *pawn, int snum, int argn, int always);
|
||||
static void RunScript(uint8_t **stream, AActor *pawn, int snum, int argn, int always);
|
||||
|
||||
int reboundpacket;
|
||||
uint8_t reboundstore[MAX_MSGLEN];
|
||||
|
@ -2487,10 +2487,10 @@ void Net_DoCommand (int type, uint8_t **stream, int player)
|
|||
|
||||
case DEM_RUNNAMEDSCRIPT:
|
||||
{
|
||||
char *sname = ReadString(stream);
|
||||
s = ReadString(stream);
|
||||
int argn = ReadByte(stream);
|
||||
|
||||
RunScript(stream, players[player].mo, -FName(sname), argn & 127, (argn & 128) ? ACS_ALWAYS : 0);
|
||||
RunScript(stream, players[player].mo, -FName(s), argn & 127, (argn & 128) ? ACS_ALWAYS : 0);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -2557,9 +2557,9 @@ void Net_DoCommand (int type, uint8_t **stream, int player)
|
|||
|
||||
case DEM_KILLCLASSCHEAT:
|
||||
{
|
||||
char *classname = ReadString (stream);
|
||||
s = ReadString (stream);
|
||||
int killcount = 0;
|
||||
PClassActor *cls = PClass::FindActor(classname);
|
||||
PClassActor *cls = PClass::FindActor(s);
|
||||
|
||||
if (cls != NULL)
|
||||
{
|
||||
|
@ -2569,20 +2569,20 @@ void Net_DoCommand (int type, uint8_t **stream, int player)
|
|||
{
|
||||
killcount += KillAll(cls_rep);
|
||||
}
|
||||
Printf ("Killed %d monsters of type %s.\n",killcount, classname);
|
||||
Printf ("Killed %d monsters of type %s.\n",killcount, s);
|
||||
}
|
||||
else
|
||||
{
|
||||
Printf ("%s is not an actor class.\n", classname);
|
||||
Printf ("%s is not an actor class.\n", s);
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case DEM_REMOVE:
|
||||
{
|
||||
char *classname = ReadString(stream);
|
||||
s = ReadString(stream);
|
||||
int removecount = 0;
|
||||
PClassActor *cls = PClass::FindActor(classname);
|
||||
PClassActor *cls = PClass::FindActor(s);
|
||||
if (cls != NULL && cls->IsDescendantOf(RUNTIME_CLASS(AActor)))
|
||||
{
|
||||
removecount = RemoveClass(cls);
|
||||
|
@ -2591,11 +2591,11 @@ void Net_DoCommand (int type, uint8_t **stream, int player)
|
|||
{
|
||||
removecount += RemoveClass(cls_rep);
|
||||
}
|
||||
Printf("Removed %d actors of type %s.\n", removecount, classname);
|
||||
Printf("Removed %d actors of type %s.\n", removecount, s);
|
||||
}
|
||||
else
|
||||
{
|
||||
Printf("%s is not an actor class.\n", classname);
|
||||
Printf("%s is not an actor class.\n", s);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -2688,7 +2688,7 @@ void Net_DoCommand (int type, uint8_t **stream, int player)
|
|||
}
|
||||
|
||||
// Used by DEM_RUNSCRIPT, DEM_RUNSCRIPT2, and DEM_RUNNAMEDSCRIPT
|
||||
static void RunScript(uint8_t **stream, APlayerPawn *pawn, int snum, int argn, int always)
|
||||
static void RunScript(uint8_t **stream, AActor *pawn, int snum, int argn, int always)
|
||||
{
|
||||
int arg[4] = { 0, 0, 0, 0 };
|
||||
int i;
|
||||
|
|
|
@ -138,12 +138,12 @@ int D_GenderToInt (const char *gender)
|
|||
{
|
||||
if (gender[0] == 'f')
|
||||
return GENDER_FEMALE;
|
||||
else if (gender[0] == 'm')
|
||||
return GENDER_MALE;
|
||||
else if (gender[0] == 'n')
|
||||
return GENDER_NEUTER;
|
||||
else
|
||||
else if (gender[0] == 'o')
|
||||
return GENDER_OBJECT;
|
||||
else
|
||||
return GENDER_MALE;
|
||||
}
|
||||
|
||||
int D_PlayerClassToInt (const char *classname)
|
||||
|
@ -728,8 +728,8 @@ void D_WriteUserInfoStrings (int pnum, uint8_t **stream, bool compact)
|
|||
case NAME_Gender:
|
||||
*stream += sprintf(*((char **)stream), "\\%s",
|
||||
*static_cast<FIntCVar *>(pair->Value) == GENDER_FEMALE ? "female" :
|
||||
*static_cast<FIntCVar *>(pair->Value) == GENDER_MALE ? "male" :
|
||||
*static_cast<FIntCVar *>(pair->Value) == GENDER_NEUTER ? "neutral" : "other");
|
||||
*static_cast<FIntCVar *>(pair->Value) == GENDER_NEUTER ? "neutral" :
|
||||
*static_cast<FIntCVar *>(pair->Value) == GENDER_OBJECT ? "other" : "male");
|
||||
break;
|
||||
|
||||
case NAME_PlayerClass:
|
||||
|
|
|
@ -79,84 +79,8 @@ extern ColorSetList ColorSets;
|
|||
|
||||
FString GetPrintableDisplayName(PClassActor *cls);
|
||||
|
||||
class APlayerPawn : public AActor
|
||||
{
|
||||
DECLARE_CLASS(APlayerPawn, AActor)
|
||||
HAS_OBJECT_POINTERS
|
||||
public:
|
||||
|
||||
virtual void Serialize(FSerializer &arc);
|
||||
void PlayIdle(AActor *player);
|
||||
|
||||
virtual void PostBeginPlay() override;
|
||||
virtual void Tick() override;
|
||||
virtual void BeginPlay () override;
|
||||
virtual bool UpdateWaterLevel (bool splash) override;
|
||||
|
||||
bool ResetAirSupply (bool playgasp = true);
|
||||
int GetMaxHealth(bool withupgrades = false) const;
|
||||
void GiveDeathmatchInventory ();
|
||||
|
||||
void GiveDefaultInventory ();
|
||||
|
||||
// These are virtual on the script side only.
|
||||
void PlayIdle();
|
||||
|
||||
const char *GetSoundClass () const;
|
||||
int hasBuddha(); // returns 0 for no buddha, 1 for regular buddha and 2 for strong buddha
|
||||
|
||||
enum EInvulState
|
||||
{
|
||||
INVUL_Start,
|
||||
INVUL_Active,
|
||||
INVUL_Stop,
|
||||
INVUL_GetAlpha
|
||||
};
|
||||
|
||||
|
||||
int crouchsprite;
|
||||
int MaxHealth;
|
||||
int BonusHealth;
|
||||
|
||||
int MugShotMaxHealth;
|
||||
int RunHealth;
|
||||
int PlayerFlags;
|
||||
double FullHeight;
|
||||
TObjPtr<AActor*> InvFirst; // first inventory item displayed on inventory bar
|
||||
TObjPtr<AActor*> InvSel; // selected inventory item
|
||||
|
||||
// [GRB] Player class properties
|
||||
double JumpZ;
|
||||
double GruntSpeed;
|
||||
double FallingScreamMinSpeed, FallingScreamMaxSpeed;
|
||||
double ViewHeight;
|
||||
double ForwardMove1, ForwardMove2;
|
||||
double SideMove1, SideMove2;
|
||||
FTextureID ScoreIcon;
|
||||
int SpawnMask;
|
||||
FName MorphWeapon;
|
||||
double AttackZOffset; // attack height, relative to player center
|
||||
double UseRange; // [NS] Distance at which player can +use
|
||||
double AirCapacity; // Multiplier for air supply underwater.
|
||||
PClassActor *FlechetteType;
|
||||
|
||||
|
||||
// [CW] Fades for when you are being damaged.
|
||||
PalEntry DamageFade;
|
||||
|
||||
// [SP] ViewBob Multiplier
|
||||
double ViewBob;
|
||||
double curBob;
|
||||
|
||||
// Former class properties that were moved into the object to get rid of the meta class.
|
||||
FName SoundClass; // Sound class
|
||||
FName Face; // Doom status bar face (when used)
|
||||
FName Portrait;
|
||||
FName Slot[10];
|
||||
double HexenArmor[5];
|
||||
uint8_t ColorRangeStart; // Skin color range
|
||||
uint8_t ColorRangeEnd;
|
||||
|
||||
};
|
||||
|
||||
//
|
||||
// PlayerPawn flags
|
||||
|
@ -164,8 +88,6 @@ public:
|
|||
enum
|
||||
{
|
||||
PPF_NOTHRUSTWHENINVUL = 1, // Attacks do not thrust the player if they are invulnerable.
|
||||
PPF_CANSUPERMORPH = 2, // Being remorphed into this class can give you a Tome of Power
|
||||
PPF_CROUCHABLEMORPH = 4, // This morphed player can crouch
|
||||
};
|
||||
|
||||
//
|
||||
|
@ -369,7 +291,7 @@ public:
|
|||
void SetLogText (const char *text);
|
||||
void SendPitchLimits() const;
|
||||
|
||||
APlayerPawn *mo = nullptr;
|
||||
AActor *mo = nullptr;
|
||||
uint8_t playerstate = 0;
|
||||
ticcmd_t cmd = {};
|
||||
usercmd_t original_cmd;
|
||||
|
@ -483,9 +405,15 @@ public:
|
|||
|
||||
double GetDeltaViewHeight() const
|
||||
{
|
||||
return (mo->ViewHeight + crouchviewdelta - viewheight) / 8;
|
||||
return (mo->FloatVar(NAME_ViewHeight) + crouchviewdelta - viewheight) / 8;
|
||||
}
|
||||
|
||||
double DefaultViewHeight() const
|
||||
{
|
||||
return mo->FloatVar(NAME_ViewHeight);
|
||||
}
|
||||
|
||||
|
||||
void Uncrouch()
|
||||
{
|
||||
if (crouchfactor != 1)
|
||||
|
@ -495,15 +423,10 @@ public:
|
|||
crouchdir = 0;
|
||||
crouching = 0;
|
||||
crouchviewdelta = 0;
|
||||
viewheight = mo ? mo->ViewHeight : 0;
|
||||
viewheight = mo ? mo->FloatVar(NAME_ViewHeight) : 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool CanCrouch() const
|
||||
{
|
||||
return morphTics == 0 || mo->PlayerFlags & PPF_CROUCHABLEMORPH;
|
||||
}
|
||||
|
||||
int GetSpawnClass();
|
||||
|
||||
// PSprite layers
|
||||
|
@ -515,8 +438,6 @@ public:
|
|||
// you are 100% sure the context already implies the layer exists.
|
||||
DPSprite *GetPSprite(PSPLayers layer);
|
||||
|
||||
bool GetPainFlash(FName type, PalEntry *color) const;
|
||||
|
||||
// [Nash] set player FOV
|
||||
void SetFOV(float fov);
|
||||
bool HasWeaponsInSlot(int slot) const;
|
||||
|
|
|
@ -503,7 +503,7 @@ void DObject::StaticPointerSubstitution (AActor *old, AActor *notOld)
|
|||
{
|
||||
if (playeringame[i])
|
||||
{
|
||||
APlayerPawn *replacement = static_cast<APlayerPawn *>(notOld);
|
||||
AActor *replacement = notOld;
|
||||
auto &p = players[i];
|
||||
|
||||
if (p.mo == old) p.mo = replacement, changed++;
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include <type_traits>
|
||||
#include "doomtype.h"
|
||||
#include "i_system.h"
|
||||
#include "vectors.h"
|
||||
|
||||
class PClass;
|
||||
class PType;
|
||||
|
@ -238,6 +239,7 @@ public:
|
|||
inline PalEntry &ColorVar(FName field);
|
||||
inline FName &NameVar(FName field);
|
||||
inline double &FloatVar(FName field);
|
||||
inline DAngle &AngleVar(FName field);
|
||||
inline FString &StringVar(FName field);
|
||||
template<class T> T*& PointerVar(FName field);
|
||||
|
||||
|
@ -456,6 +458,11 @@ inline double &DObject::FloatVar(FName field)
|
|||
return *(double*)ScriptVar(field, nullptr);
|
||||
}
|
||||
|
||||
inline DAngle &DObject::AngleVar(FName field)
|
||||
{
|
||||
return *(DAngle*)ScriptVar(field, nullptr);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline T *&DObject::PointerVar(FName field)
|
||||
{
|
||||
|
|
|
@ -190,24 +190,6 @@ size_t PropagateMark()
|
|||
obj->GetClass()->Size;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// PropagateAll
|
||||
//
|
||||
// Empties the gray list by propagating every single object in it.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static size_t PropagateAll()
|
||||
{
|
||||
size_t m = 0;
|
||||
while (Gray != NULL)
|
||||
{
|
||||
m += PropagateMark();
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// SweepList
|
||||
|
@ -273,7 +255,7 @@ void Mark(DObject **obj)
|
|||
{
|
||||
DObject *lobj = *obj;
|
||||
|
||||
assert(lobj == nullptr || !(lobj->ObjectFlags & OF_Released));
|
||||
//assert(lobj == nullptr || !(lobj->ObjectFlags & OF_Released));
|
||||
if (lobj != nullptr && !(lobj->ObjectFlags & OF_Released))
|
||||
{
|
||||
if (lobj->ObjectFlags & OF_EuthanizeMe)
|
||||
|
@ -668,14 +650,14 @@ size_t DSectorMarker::PropagateMark()
|
|||
moretodo = true;
|
||||
}
|
||||
|
||||
if (!moretodo && polyobjs != NULL)
|
||||
if (!moretodo && level.Polyobjects.Size() > 0)
|
||||
{
|
||||
for (i = 0; i < POLYSTEPSIZE && PolyNum + i < po_NumPolyobjs; ++i)
|
||||
for (i = 0; i < POLYSTEPSIZE && PolyNum + i < (int)level.Polyobjects.Size(); ++i)
|
||||
{
|
||||
GC::Mark(polyobjs[PolyNum + i].interpolation);
|
||||
GC::Mark(level.Polyobjects[PolyNum + i].interpolation);
|
||||
}
|
||||
marked += i * sizeof(FPolyObj);
|
||||
if (PolyNum + i < po_NumPolyobjs)
|
||||
if (PolyNum + i < (int)level.Polyobjects.Size())
|
||||
{
|
||||
PolyNum += i;
|
||||
moretodo = true;
|
||||
|
@ -686,7 +668,7 @@ size_t DSectorMarker::PropagateMark()
|
|||
for (i = 0; i < SIDEDEFSTEPSIZE && SideNum + i < (int)level.sides.Size(); ++i)
|
||||
{
|
||||
side_t *side = &level.sides[SideNum + i];
|
||||
for(int j=0;j<3;j++) GC::Mark(side->textures[j].interpolation);
|
||||
for (int j = 0; j < 3; j++) GC::Mark(side->textures[j].interpolation);
|
||||
}
|
||||
marked += i * sizeof(side_t);
|
||||
if (SideNum + i < (int)level.sides.Size())
|
||||
|
|
29
src/dobjgc.h
29
src/dobjgc.h
|
@ -180,6 +180,28 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
T operator=(std::nullptr_t nul)
|
||||
{
|
||||
o = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// To allow NULL, too.
|
||||
T operator=(const int val)
|
||||
{
|
||||
assert(val == 0);
|
||||
o = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// To allow NULL, too. In Clang NULL is a long.
|
||||
T operator=(const long val)
|
||||
{
|
||||
assert(val == 0);
|
||||
o = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
operator T() throw()
|
||||
{
|
||||
return GC::ReadBarrier(pp);
|
||||
|
@ -190,13 +212,6 @@ public:
|
|||
assert(q != NULL);
|
||||
return *q;
|
||||
}
|
||||
T *operator&() throw()
|
||||
{
|
||||
// Does not perform a read barrier. The only real use for this is with
|
||||
// the DECLARE_POINTER macro, where a read barrier would be a very bad
|
||||
// thing.
|
||||
return &pp;
|
||||
}
|
||||
T operator->() throw()
|
||||
{
|
||||
return GC::ReadBarrier(pp);
|
||||
|
|
|
@ -267,7 +267,17 @@ inline VersionInfo MakeVersion(unsigned int ma, unsigned int mi, unsigned int re
|
|||
return{ (uint16_t)ma, (uint16_t)mi, (uint32_t)re };
|
||||
}
|
||||
|
||||
|
||||
enum class ELightMode : int8_t
|
||||
{
|
||||
NotSet = -1,
|
||||
LinearStandard = 0,
|
||||
DoomBright = 1,
|
||||
Doom = 2,
|
||||
DoomDark = 3,
|
||||
DoomLegacy = 4,
|
||||
ZDoomSoftware = 8,
|
||||
DoomSoftware = 16
|
||||
};
|
||||
|
||||
// Screenshot buffer image data types
|
||||
enum ESSType
|
||||
|
|
|
@ -39,7 +39,7 @@ IMPLEMENT_CLASS(DSectorEffect, false, false)
|
|||
DSectorEffect::DSectorEffect ()
|
||||
: DThinker(STAT_SECTOREFFECT)
|
||||
{
|
||||
m_Sector = NULL;
|
||||
m_Sector = nullptr;
|
||||
}
|
||||
|
||||
void DSectorEffect::OnDestroy()
|
||||
|
@ -48,15 +48,15 @@ void DSectorEffect::OnDestroy()
|
|||
{
|
||||
if (m_Sector->floordata == this)
|
||||
{
|
||||
m_Sector->floordata = NULL;
|
||||
m_Sector->floordata = nullptr;
|
||||
}
|
||||
if (m_Sector->ceilingdata == this)
|
||||
{
|
||||
m_Sector->ceilingdata = NULL;
|
||||
m_Sector->ceilingdata = nullptr;
|
||||
}
|
||||
if (m_Sector->lightingdata == this)
|
||||
{
|
||||
m_Sector->lightingdata = NULL;
|
||||
m_Sector->lightingdata = nullptr;
|
||||
}
|
||||
}
|
||||
Super::OnDestroy();
|
||||
|
@ -91,7 +91,7 @@ IMPLEMENT_POINTERS_END
|
|||
DMover::DMover (sector_t *sector)
|
||||
: DSectorEffect (sector)
|
||||
{
|
||||
interpolation = NULL;
|
||||
interpolation = nullptr;
|
||||
}
|
||||
|
||||
void DMover::OnDestroy()
|
||||
|
@ -108,10 +108,10 @@ void DMover::Serialize(FSerializer &arc)
|
|||
|
||||
void DMover::StopInterpolation(bool force)
|
||||
{
|
||||
if (interpolation != NULL)
|
||||
if (interpolation != nullptr)
|
||||
{
|
||||
interpolation->DelRef(force);
|
||||
interpolation = NULL;
|
||||
interpolation = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -40,6 +40,8 @@
|
|||
#include "vm.h"
|
||||
#include "c_dispatch.h"
|
||||
#include "v_text.h"
|
||||
#include "g_levellocals.h"
|
||||
#include "a_dynlight.h"
|
||||
|
||||
|
||||
static int ThinkCount;
|
||||
|
@ -617,6 +619,13 @@ void DThinker::RunThinkers ()
|
|||
count += TickThinkers(&FreshThinkers[i], &Thinkers[i]);
|
||||
}
|
||||
} while (count != 0);
|
||||
|
||||
for (auto light = level.lights; light;)
|
||||
{
|
||||
auto next = light->next;
|
||||
light->Tick();
|
||||
light = next;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -637,6 +646,19 @@ void DThinker::RunThinkers ()
|
|||
}
|
||||
} while (count != 0);
|
||||
|
||||
// Also profile the internal dynamic lights, even though they are not implemented as thinkers.
|
||||
auto &prof = Profiles[NAME_InternalDynamicLight];
|
||||
prof.timer.Clock();
|
||||
for (auto light = level.lights; light;)
|
||||
{
|
||||
prof.numcalls++;
|
||||
auto next = light->next;
|
||||
light->Tick();
|
||||
light = next;
|
||||
}
|
||||
prof.timer.Unclock();
|
||||
|
||||
|
||||
struct SortedProfileInfo
|
||||
{
|
||||
const char* className;
|
||||
|
|
|
@ -75,6 +75,11 @@ bool E_RegisterHandler(DStaticEventHandler* handler)
|
|||
{
|
||||
// if before is not null, link it before the existing handler.
|
||||
// note that before can be first handler, check for this.
|
||||
if (before->prev != nullptr)
|
||||
{
|
||||
before->prev->next = handler;
|
||||
GC::WriteBarrier(before->prev, handler);
|
||||
}
|
||||
handler->next = before;
|
||||
GC::WriteBarrier(handler, before);
|
||||
handler->prev = before->prev;
|
||||
|
@ -530,6 +535,14 @@ bool E_CheckReplacement( PClassActor *replacee, PClassActor **replacement )
|
|||
return final;
|
||||
}
|
||||
|
||||
bool E_CheckReplacee(PClassActor **replacee, PClassActor *replacement)
|
||||
{
|
||||
bool final = false;
|
||||
for (DStaticEventHandler *handler = E_FirstEventHandler; handler; handler = handler->next)
|
||||
handler->CheckReplacee(replacee, replacement, &final);
|
||||
return final;
|
||||
}
|
||||
|
||||
void E_NewGame(EventHandlerType handlerType)
|
||||
{
|
||||
bool isStatic = handlerType == EventHandlerType::Global;
|
||||
|
@ -621,6 +634,10 @@ DEFINE_FIELD_X(ReplaceEvent, FReplaceEvent, Replacee)
|
|||
DEFINE_FIELD_X(ReplaceEvent, FReplaceEvent, Replacement)
|
||||
DEFINE_FIELD_X(ReplaceEvent, FReplaceEvent, IsFinal)
|
||||
|
||||
DEFINE_FIELD_X(ReplacedEvent, FReplacedEvent, Replacee)
|
||||
DEFINE_FIELD_X(ReplacedEvent, FReplacedEvent, Replacement)
|
||||
DEFINE_FIELD_X(ReplacedEvent, FReplacedEvent, IsFinal)
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DStaticEventHandler, SetOrder)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DStaticEventHandler);
|
||||
|
@ -1187,6 +1204,21 @@ void DStaticEventHandler::CheckReplacement( PClassActor *replacee, PClassActor *
|
|||
}
|
||||
}
|
||||
|
||||
void DStaticEventHandler::CheckReplacee(PClassActor **replacee, PClassActor *replacement, bool *final)
|
||||
{
|
||||
IFVIRTUAL(DStaticEventHandler, CheckReplacee)
|
||||
{
|
||||
// don't create excessive DObjects if not going to be processed anyway
|
||||
if (isEmpty(func)) return;
|
||||
FReplacedEvent e = { *replacee, replacement, *final };
|
||||
VMValue params[2] = { (DStaticEventHandler*)this, &e };
|
||||
VMCall(func, params, 2, nullptr, 0);
|
||||
if (e.Replacee != replacement) // prevent infinite recursion
|
||||
*replacee = e.Replacee;
|
||||
*final = e.IsFinal;
|
||||
}
|
||||
}
|
||||
|
||||
void DStaticEventHandler::NewGame()
|
||||
{
|
||||
IFVIRTUAL(DStaticEventHandler, NewGame)
|
||||
|
|
10
src/events.h
10
src/events.h
|
@ -81,6 +81,8 @@ void E_Console(int player, FString name, int arg1, int arg2, int arg3, bool manu
|
|||
|
||||
// called when looking up the replacement for an actor class
|
||||
bool E_CheckReplacement(PClassActor* replacee, PClassActor** replacement);
|
||||
// called when looking up the replaced for an actor class
|
||||
bool E_CheckReplacee(PClassActor** replacee, PClassActor* replacement);
|
||||
|
||||
// called on new game
|
||||
void E_NewGame(EventHandlerType handlerType);
|
||||
|
@ -187,6 +189,7 @@ public:
|
|||
|
||||
//
|
||||
void CheckReplacement(PClassActor* replacee, PClassActor** replacement, bool* final);
|
||||
void CheckReplacee(PClassActor** replacee, PClassActor* replacement, bool* final);
|
||||
|
||||
//
|
||||
void NewGame();
|
||||
|
@ -301,4 +304,11 @@ struct FReplaceEvent
|
|||
bool IsFinal;
|
||||
};
|
||||
|
||||
struct FReplacedEvent
|
||||
{
|
||||
PClassActor* Replacee;
|
||||
PClassActor* Replacement;
|
||||
bool IsFinal;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -117,7 +117,7 @@ void FS_MapCmd(FScanner &sc)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void FS_EmulateCmd(char * string)
|
||||
void FS_EmulateCmd(FLevelLocals *Level, char * string)
|
||||
{
|
||||
FScanner sc;
|
||||
sc.OpenMem("RUNCMD", string, (int)strlen(string));
|
||||
|
@ -144,7 +144,7 @@ void FS_EmulateCmd(char * string)
|
|||
else if (sc.Compare("gravity"))
|
||||
{
|
||||
sc.MustGetFloat();
|
||||
level.gravity=(float)(sc.Float*800);
|
||||
Level->gravity=(float)(sc.Float*800);
|
||||
while (sc.GetString())
|
||||
{
|
||||
if (sc.Compare(";")) break;
|
||||
|
@ -157,7 +157,7 @@ void FS_EmulateCmd(char * string)
|
|||
for(int i=0;i<MAXPLAYERS;i++)
|
||||
{
|
||||
// No, this is not correct. But this is the way Legacy WADs expect it to be handled!
|
||||
if (players[i].mo != NULL) players[i].mo->ViewHeight = playerviewheight;
|
||||
if (players[i].mo != NULL) players[i].mo->FloatVar(NAME_ViewHeight) = playerviewheight;
|
||||
players[i].viewheight = playerviewheight;
|
||||
players[i].Uncrouch();
|
||||
}
|
||||
|
@ -174,15 +174,15 @@ void FS_EmulateCmd(char * string)
|
|||
{
|
||||
sc.MustGetNumber();
|
||||
// Using this disables most MAPINFO fog options!
|
||||
level.fogdensity = sc.Number * 70 / 400;
|
||||
level.outsidefogdensity = 0;
|
||||
level.skyfog = 0;
|
||||
level.info->outsidefog = 0;
|
||||
Level->fogdensity = sc.Number * 70 / 400;
|
||||
Level->outsidefogdensity = 0;
|
||||
Level->skyfog = 0;
|
||||
Level->info->outsidefog = 0;
|
||||
}
|
||||
else if (sc.Compare("gr_fogcolor"))
|
||||
{
|
||||
sc.MustGetString();
|
||||
level.fadeto = (uint32_t)strtoull(sc.String, NULL, 16);
|
||||
Level->fadeto = (uint32_t)strtoull(sc.String, NULL, 16);
|
||||
}
|
||||
|
||||
else
|
||||
|
|
|
@ -7,10 +7,9 @@
|
|||
struct MapData;
|
||||
class AActor;
|
||||
|
||||
void T_PreprocessScripts();
|
||||
void T_LoadScripts(MapData * map);
|
||||
void T_AddSpawnedThing(AActor * );
|
||||
bool T_RunScript(int snum, AActor * t_trigger);
|
||||
void FS_Close();
|
||||
void T_PreprocessScripts(FLevelLocals *Level);
|
||||
void T_LoadScripts(FLevelLocals *Level, MapData * map);
|
||||
void T_AddSpawnedThing(FLevelLocals *Level, AActor * );
|
||||
bool T_RunScript(FLevelLocals *l, int snum, AActor * t_trigger);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -222,7 +222,7 @@ static PClassActor * ActorTypes[countof(ActorNames_init)];
|
|||
// Doom index is only supported for the original things up to MBF
|
||||
//
|
||||
//==========================================================================
|
||||
PClassActor * T_GetMobjType(svalue_t arg)
|
||||
PClassActor * FParser::T_GetMobjType(svalue_t arg)
|
||||
{
|
||||
PClassActor * pclass=NULL;
|
||||
|
||||
|
@ -256,7 +256,7 @@ PClassActor * T_GetMobjType(svalue_t arg)
|
|||
// Input can be either an actor variable or an index value
|
||||
//
|
||||
//==========================================================================
|
||||
static int T_GetPlayerNum(const svalue_t &arg)
|
||||
int FParser::T_GetPlayerNum(const svalue_t &arg)
|
||||
{
|
||||
int playernum;
|
||||
if(arg.type == svt_mobj)
|
||||
|
@ -285,7 +285,7 @@ static int T_GetPlayerNum(const svalue_t &arg)
|
|||
return playernum;
|
||||
}
|
||||
|
||||
APlayerPawn *T_GetPlayerActor(const svalue_t &arg)
|
||||
AActor *FParser::T_GetPlayerActor(const svalue_t &arg)
|
||||
{
|
||||
int num = T_GetPlayerNum(arg);
|
||||
return num == -1 ? nullptr : players[num].mo;
|
||||
|
@ -887,12 +887,12 @@ void FParser::SF_Spawn(void)
|
|||
{
|
||||
t_return.value.mobj->Angles.Yaw = angle;
|
||||
|
||||
if (!DFraggleThinker::ActiveThinker->nocheckposition)
|
||||
if (!Level->info->fs_nocheckposition)
|
||||
{
|
||||
if (!P_TestMobjLocation(t_return.value.mobj))
|
||||
{
|
||||
if (t_return.value.mobj->flags&MF_COUNTKILL) level.total_monsters--;
|
||||
if (t_return.value.mobj->flags&MF_COUNTITEM) level.total_items--;
|
||||
if (t_return.value.mobj->flags&MF_COUNTKILL) Level->total_monsters--;
|
||||
if (t_return.value.mobj->flags&MF_COUNTITEM) Level->total_items--;
|
||||
t_return.value.mobj->Destroy();
|
||||
t_return.value.mobj = NULL;
|
||||
}
|
||||
|
@ -1521,7 +1521,7 @@ void FParser::SF_StartSectorSound(void)
|
|||
FSSectorTagIterator itr(tagnum);
|
||||
while ((i = itr.Next()) >= 0)
|
||||
{
|
||||
sector = &level.sectors[i];
|
||||
sector = &Level->sectors[i];
|
||||
S_Sound(sector, CHAN_BODY, T_FindSound(stringvalue(t_argv[1])), 1.0f, ATTN_NORM);
|
||||
}
|
||||
}
|
||||
|
@ -1558,7 +1558,7 @@ void FParser::SF_FloorHeight(void)
|
|||
FSSectorTagIterator itr(tagnum);
|
||||
while ((i = itr.Next()) >= 0)
|
||||
{
|
||||
auto &sec = level.sectors[i];
|
||||
auto &sec = Level->sectors[i];
|
||||
if (sec.floordata) continue; // don't move floors that are active!
|
||||
|
||||
if (sec.MoveFloor(
|
||||
|
@ -1580,7 +1580,7 @@ void FParser::SF_FloorHeight(void)
|
|||
script_error("sector not found with tagnum %i\n", tagnum);
|
||||
return;
|
||||
}
|
||||
returnval = level.sectors[secnum].CenterFloor();
|
||||
returnval = Level->sectors[secnum].CenterFloor();
|
||||
}
|
||||
|
||||
// return floor height
|
||||
|
@ -1613,7 +1613,7 @@ void FParser::SF_MoveFloor(void)
|
|||
FSSectorTagIterator itr(tagnum);
|
||||
while ((secnum = itr.Next()) >= 0)
|
||||
{
|
||||
P_CreateFloor(&level.sectors[secnum], DFloor::floorMoveToValue, NULL, platspeed, destheight, crush, 0, false, false);
|
||||
P_CreateFloor(&Level->sectors[secnum], DFloor::floorMoveToValue, NULL, platspeed, destheight, crush, 0, false, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1648,7 +1648,7 @@ void FParser::SF_CeilingHeight(void)
|
|||
FSSectorTagIterator itr(tagnum);
|
||||
while ((i = itr.Next()) >= 0)
|
||||
{
|
||||
auto &sec = level.sectors[i];
|
||||
auto &sec = Level->sectors[i];
|
||||
if (sec.ceilingdata) continue; // don't move ceilings that are active!
|
||||
|
||||
if (sec.MoveCeiling(
|
||||
|
@ -1670,7 +1670,7 @@ void FParser::SF_CeilingHeight(void)
|
|||
script_error("sector not found with tagnum %i\n", tagnum);
|
||||
return;
|
||||
}
|
||||
returnval = level.sectors[secnum].CenterCeiling();
|
||||
returnval = Level->sectors[secnum].CenterCeiling();
|
||||
}
|
||||
|
||||
// return ceiling height
|
||||
|
@ -1705,7 +1705,7 @@ void FParser::SF_MoveCeiling(void)
|
|||
FSSectorTagIterator itr(tagnum);
|
||||
while ((secnum = itr.Next()) >= 0)
|
||||
{
|
||||
P_CreateCeiling(&level.sectors[secnum], DCeiling::ceilMoveToValue, NULL, tagnum, platspeed, platspeed, destheight, crush, silent | 4, 0, DCeiling::ECrushMode::crushDoom);
|
||||
P_CreateCeiling(&Level->sectors[secnum], DCeiling::ceilMoveToValue, NULL, tagnum, platspeed, platspeed, destheight, crush, silent | 4, 0, DCeiling::ECrushMode::crushDoom);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1734,7 +1734,7 @@ void FParser::SF_LightLevel(void)
|
|||
return;
|
||||
}
|
||||
|
||||
sector = &level.sectors[secnum];
|
||||
sector = &Level->sectors[secnum];
|
||||
|
||||
if(t_argc > 1) // > 1: set light level
|
||||
{
|
||||
|
@ -1744,7 +1744,7 @@ void FParser::SF_LightLevel(void)
|
|||
FSSectorTagIterator itr(tagnum);
|
||||
while ((i = itr.Next()) >= 0)
|
||||
{
|
||||
level.sectors[i].SetLightLevel(intvalue(t_argv[1]));
|
||||
Level->sectors[i].SetLightLevel(intvalue(t_argv[1]));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1768,7 +1768,7 @@ class DLightLevel : public DLighting
|
|||
unsigned char destlevel;
|
||||
unsigned char speed;
|
||||
|
||||
DLightLevel() {}
|
||||
DLightLevel() = default;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -1862,7 +1862,7 @@ void FParser::SF_FadeLight(void)
|
|||
FSectorTagIterator it(sectag);
|
||||
while ((i = it.Next()) >= 0)
|
||||
{
|
||||
if (!level.sectors[i].lightingdata) Create<DLightLevel>(&level.sectors[i],destlevel,speed);
|
||||
if (!Level->sectors[i].lightingdata) Create<DLightLevel>(&Level->sectors[i],destlevel,speed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1887,7 +1887,7 @@ void FParser::SF_FloorTexture(void)
|
|||
if(secnum < 0)
|
||||
{ script_error("sector not found with tagnum %i\n", tagnum); return;}
|
||||
|
||||
sector = &level.sectors[secnum];
|
||||
sector = &Level->sectors[secnum];
|
||||
|
||||
if(t_argc > 1)
|
||||
{
|
||||
|
@ -1898,7 +1898,7 @@ void FParser::SF_FloorTexture(void)
|
|||
FSSectorTagIterator itr(tagnum);
|
||||
while ((i = itr.Next()) >= 0)
|
||||
{
|
||||
level.sectors[i].SetTexture(sector_t::floor, picnum);
|
||||
Level->sectors[i].SetTexture(sector_t::floor, picnum);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1939,7 +1939,7 @@ void FParser::SF_SectorColormap(void)
|
|||
if(secnum < 0)
|
||||
{ script_error("sector not found with tagnum %i\n", tagnum); return;}
|
||||
|
||||
sector = &level.sectors[secnum];
|
||||
sector = &Level->sectors[secnum];
|
||||
|
||||
if (t_argv[1].type==svt_string)
|
||||
{
|
||||
|
@ -1949,7 +1949,7 @@ void FParser::SF_SectorColormap(void)
|
|||
while ((i = itr.Next()) >= 0)
|
||||
{
|
||||
sectors[i].midmap=cm;
|
||||
sectors[i].heightsec=&level.sectors[i];
|
||||
sectors[i].heightsec=&Level->sectors[i];
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
@ -1977,7 +1977,7 @@ void FParser::SF_CeilingTexture(void)
|
|||
if(secnum < 0)
|
||||
{ script_error("sector not found with tagnum %i\n", tagnum); return;}
|
||||
|
||||
sector = &level.sectors[secnum];
|
||||
sector = &Level->sectors[secnum];
|
||||
|
||||
if(t_argc > 1)
|
||||
{
|
||||
|
@ -1988,7 +1988,7 @@ void FParser::SF_CeilingTexture(void)
|
|||
FSSectorTagIterator itr(tagnum);
|
||||
while ((i = itr.Next()) >= 0)
|
||||
{
|
||||
level.sectors[i].SetTexture(sector_t::ceiling, picnum);
|
||||
Level->sectors[i].SetTexture(sector_t::ceiling, picnum);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2080,7 +2080,7 @@ void FParser::SF_CloseDoor(void)
|
|||
// run console cmd
|
||||
void FParser::SF_RunCommand(void)
|
||||
{
|
||||
FS_EmulateCmd(GetFormatString(0).LockBuffer());
|
||||
FS_EmulateCmd(Level, GetFormatString(0).LockBuffer());
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -2161,7 +2161,7 @@ void FParser::SF_SetLineBlocking(void)
|
|||
int i;
|
||||
while ((i = itr.Next()) >= 0)
|
||||
{
|
||||
level.lines[i].flags = (level.lines[i].flags & ~(ML_BLOCKING | ML_BLOCKEVERYTHING)) | blocking;
|
||||
Level->lines[i].flags = (Level->lines[i].flags & ~(ML_BLOCKING | ML_BLOCKEVERYTHING)) | blocking;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2184,7 +2184,7 @@ void FParser::SF_SetLineMonsterBlocking(void)
|
|||
int i;
|
||||
while ((i = itr.Next()) >= 0)
|
||||
{
|
||||
level.lines[i].flags = (level.lines[i].flags & ~ML_BLOCKMONSTERS) | blocking;
|
||||
Level->lines[i].flags = (Level->lines[i].flags & ~ML_BLOCKMONSTERS) | blocking;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2241,11 +2241,11 @@ void FParser::SF_SetLineTexture(void)
|
|||
while ((i = itr.Next()) >= 0)
|
||||
{
|
||||
// bad sidedef, Hexen just SEGV'd here!
|
||||
if (level.lines[i].sidedef[side] != NULL)
|
||||
if (Level->lines[i].sidedef[side] != NULL)
|
||||
{
|
||||
if (position >= 0 && position <= 2)
|
||||
{
|
||||
level.lines[i].sidedef[side]->SetTexture(position, texturenum);
|
||||
Level->lines[i].sidedef[side]->SetTexture(position, texturenum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2260,7 +2260,7 @@ void FParser::SF_SetLineTexture(void)
|
|||
FLineIdIterator itr(tag);
|
||||
while ((i = itr.Next()) >= 0)
|
||||
{
|
||||
side_t *sided = level.lines[i].sidedef[side];
|
||||
side_t *sided = Level->lines[i].sidedef[side];
|
||||
if(sided != NULL)
|
||||
{
|
||||
if(sections & 1) sided->SetTexture(side_t::top, picnum);
|
||||
|
@ -3108,7 +3108,7 @@ void FParser::SF_SpawnMissile()
|
|||
|
||||
void FParser::SF_MapThingNumExist()
|
||||
{
|
||||
auto &SpawnedThings = DFraggleThinker::ActiveThinker->SpawnedThings;
|
||||
auto &SpawnedThings = Level->FraggleScriptThinker->SpawnedThings;
|
||||
|
||||
int intval;
|
||||
|
||||
|
@ -3137,7 +3137,7 @@ void FParser::SF_MapThingNumExist()
|
|||
|
||||
void FParser::SF_MapThings()
|
||||
{
|
||||
auto &SpawnedThings = DFraggleThinker::ActiveThinker->SpawnedThings;
|
||||
auto &SpawnedThings = Level->FraggleScriptThinker->SpawnedThings;
|
||||
|
||||
t_return.type = svt_int;
|
||||
t_return.value.i = SpawnedThings.Size();
|
||||
|
@ -3204,13 +3204,13 @@ void FParser::SF_LineFlag()
|
|||
if (CheckArgs(2))
|
||||
{
|
||||
linenum = intvalue(t_argv[0]);
|
||||
if(linenum >= level.lines.Size())
|
||||
if(linenum >= Level->lines.Size())
|
||||
{
|
||||
script_error("LineFlag: Invalid line number.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
line = &level.lines[linenum];
|
||||
line = &Level->lines[linenum];
|
||||
|
||||
flagnum = intvalue(t_argv[1]);
|
||||
if(flagnum < 0 || (flagnum > 8 && flagnum!=15))
|
||||
|
@ -3311,7 +3311,7 @@ void FParser::SF_Resurrect()
|
|||
mo->Height = mo->GetDefault()->Height;
|
||||
mo->radius = mo->GetDefault()->radius;
|
||||
mo->Revive();
|
||||
mo->target = NULL;
|
||||
mo->target = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3573,7 +3573,7 @@ void FParser::SF_SetCorona(void)
|
|||
void FParser::SF_LevelNum()
|
||||
{
|
||||
t_return.type = svt_int;
|
||||
t_return.value.f = level.levelnum;
|
||||
t_return.value.f = Level->levelnum;
|
||||
}
|
||||
|
||||
|
||||
|
@ -3724,19 +3724,7 @@ void FParser::SF_SetColor(void)
|
|||
FSSectorTagIterator itr(tagnum);
|
||||
while ((i = itr.Next()) >= 0)
|
||||
{
|
||||
if (!DFraggleThinker::ActiveThinker->setcolormaterial)
|
||||
{
|
||||
level.sectors[i].SetColor(color, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// little hack for testing the D64 color stuff.
|
||||
for (int j = 0; j < 4; j++) level.sectors[i].SetSpecialColor(j, color);
|
||||
// simulates 'nocoloredspritelighting' settings.
|
||||
int v = (color.r + color.g + color.b) / 3;
|
||||
v = (255 + v + v) / 3;
|
||||
level.sectors[i].SetSpecialColor(sector_t::sprites, v, v, v);
|
||||
}
|
||||
Level->sectors[i].SetColor(color, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3833,9 +3821,9 @@ void FParser::SF_SetLineTrigger()
|
|||
mld.special = spec;
|
||||
mld.tag = tag;
|
||||
mld.flags = 0;
|
||||
int f = level.lines[i].flags;
|
||||
P_TranslateLineDef(&level.lines[i], &mld);
|
||||
level.lines[i].flags = (level.lines[i].flags & (ML_MONSTERSCANACTIVATE | ML_REPEAT_SPECIAL | ML_SPAC_MASK | ML_FIRSTSIDEONLY)) |
|
||||
int f = Level->lines[i].flags;
|
||||
P_TranslateLineDef(&Level->lines[i], &mld);
|
||||
Level->lines[i].flags = (Level->lines[i].flags & (ML_MONSTERSCANACTIVATE | ML_REPEAT_SPECIAL | ML_SPAC_MASK | ML_FIRSTSIDEONLY)) |
|
||||
(f & ~(ML_MONSTERSCANACTIVATE | ML_REPEAT_SPECIAL | ML_SPAC_MASK | ML_FIRSTSIDEONLY));
|
||||
|
||||
}
|
||||
|
@ -3873,7 +3861,7 @@ void FParser::RunLineSpecial(const FLineSpecial *spec)
|
|||
|
||||
DRunningScript *FParser::SaveCurrentScript()
|
||||
{
|
||||
DFraggleThinker *th = DFraggleThinker::ActiveThinker;
|
||||
DFraggleThinker *th = Level->FraggleScriptThinker;
|
||||
if (th)
|
||||
{
|
||||
DRunningScript *runscr = Create<DRunningScript>(Script->trigger, Script, Script->MakeIndex(Rover));
|
||||
|
@ -3999,7 +3987,7 @@ void FParser::SF_StartScript()
|
|||
return;
|
||||
}
|
||||
|
||||
DFraggleThinker *th = DFraggleThinker::ActiveThinker;
|
||||
DFraggleThinker *th = Level->FraggleScriptThinker;
|
||||
if (th)
|
||||
{
|
||||
|
||||
|
@ -4035,7 +4023,7 @@ void FParser::SF_ScriptRunning()
|
|||
|
||||
snum = intvalue(t_argv[0]);
|
||||
|
||||
for(current = DFraggleThinker::ActiveThinker->RunningScripts->next; current; current=current->next)
|
||||
for(current = Level->FraggleScriptThinker->RunningScripts->next; current; current=current->next)
|
||||
{
|
||||
if(current->script->scriptnum == snum)
|
||||
{
|
||||
|
@ -4058,16 +4046,14 @@ void FParser::SF_ScriptRunning()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
static int zoom=1; // Dummy - no longer needed!
|
||||
|
||||
void init_functions(void)
|
||||
void DFraggleThinker::InitFunctions()
|
||||
{
|
||||
for(unsigned i=0;i<countof(ActorNames_init);i++)
|
||||
{
|
||||
ActorTypes[i]=PClass::FindActor(ActorNames_init[i]);
|
||||
}
|
||||
|
||||
DFsScript * gscr = global_script;
|
||||
DFsScript * gscr = GlobalScript;
|
||||
|
||||
// add all the functions
|
||||
gscr->NewVariable("consoleplayer", svt_pInt)->value.pI = &consoleplayer;
|
||||
|
|
|
@ -33,8 +33,7 @@
|
|||
#include "gi.h"
|
||||
#include "g_levellocals.h"
|
||||
#include "xlat/xlat.h"
|
||||
|
||||
void T_Init();
|
||||
#include "maploader/maploader.h"
|
||||
|
||||
class FScriptLoader
|
||||
{
|
||||
|
@ -49,62 +48,17 @@ class FScriptLoader
|
|||
int drownflag;
|
||||
bool HasScripts;
|
||||
bool IgnoreInfo;
|
||||
FLevelLocals *Level;
|
||||
|
||||
void ParseInfoCmd(char *line, FString &scriptsrc);
|
||||
public:
|
||||
FScriptLoader(FLevelLocals *l)
|
||||
{
|
||||
Level = l;
|
||||
}
|
||||
bool ParseInfo(MapData * map);
|
||||
};
|
||||
|
||||
struct FFsOptions : public FOptionalMapinfoData
|
||||
{
|
||||
FFsOptions()
|
||||
{
|
||||
identifier = "fragglescript";
|
||||
nocheckposition = false;
|
||||
setcolormaterial = false;
|
||||
}
|
||||
virtual FOptionalMapinfoData *Clone() const
|
||||
{
|
||||
FFsOptions *newopt = new FFsOptions;
|
||||
newopt->identifier = identifier;
|
||||
newopt->nocheckposition = nocheckposition;
|
||||
newopt->setcolormaterial = setcolormaterial;
|
||||
return newopt;
|
||||
}
|
||||
bool nocheckposition;
|
||||
bool setcolormaterial;
|
||||
};
|
||||
|
||||
DEFINE_MAP_OPTION(fs_nocheckposition, false)
|
||||
{
|
||||
FFsOptions *opt = info->GetOptData<FFsOptions>("fragglescript");
|
||||
|
||||
if (parse.CheckAssign())
|
||||
{
|
||||
parse.sc.MustGetNumber();
|
||||
opt->nocheckposition = !!parse.sc.Number;
|
||||
}
|
||||
else
|
||||
{
|
||||
opt->nocheckposition = true;
|
||||
}
|
||||
}
|
||||
|
||||
DEFINE_MAP_OPTION(fs_setcolormaterial, false)
|
||||
{
|
||||
FFsOptions *opt = info->GetOptData<FFsOptions>("fragglescript");
|
||||
|
||||
if (parse.CheckAssign())
|
||||
{
|
||||
parse.sc.MustGetNumber();
|
||||
opt->setcolormaterial = !!parse.sc.Number;
|
||||
}
|
||||
else
|
||||
{
|
||||
opt->setcolormaterial = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Process the lump to strip all unneeded information from it
|
||||
|
@ -165,13 +119,13 @@ void FScriptLoader::ParseInfoCmd(char *line, FString &scriptsrc)
|
|||
while (*beg<=' ') beg++;
|
||||
char * comm = strstr(beg, "//");
|
||||
if (comm) *comm=0;
|
||||
level.LevelName = beg;
|
||||
Level->LevelName = beg;
|
||||
}
|
||||
else if (sc.Compare("partime"))
|
||||
{
|
||||
sc.MustGetStringName("=");
|
||||
sc.MustGetNumber();
|
||||
level.partime=sc.Number;
|
||||
Level->partime=sc.Number;
|
||||
}
|
||||
else if (sc.Compare("music"))
|
||||
{
|
||||
|
@ -181,7 +135,7 @@ void FScriptLoader::ParseInfoCmd(char *line, FString &scriptsrc)
|
|||
sc.MustGetString();
|
||||
if (!FS_ChangeMusic(sc.String))
|
||||
{
|
||||
S_ChangeMusic(level.Music, level.musicorder);
|
||||
S_ChangeMusic(Level->Music, Level->musicorder);
|
||||
}
|
||||
}
|
||||
else if (sc.Compare("skyname"))
|
||||
|
@ -189,32 +143,32 @@ void FScriptLoader::ParseInfoCmd(char *line, FString &scriptsrc)
|
|||
sc.MustGetStringName("=");
|
||||
sc.MustGetString();
|
||||
|
||||
sky2texture = sky1texture = level.skytexture1 = level.skytexture2 = TexMan.GetTextureID (sc.String, ETextureType::Wall, FTextureManager::TEXMAN_Overridable|FTextureManager::TEXMAN_ReturnFirst);
|
||||
sky2texture = sky1texture = Level->skytexture1 = Level->skytexture2 = TexMan.GetTextureID (sc.String, ETextureType::Wall, FTextureManager::TEXMAN_Overridable|FTextureManager::TEXMAN_ReturnFirst);
|
||||
R_InitSkyMap ();
|
||||
}
|
||||
else if (sc.Compare("interpic"))
|
||||
{
|
||||
sc.MustGetStringName("=");
|
||||
sc.MustGetString();
|
||||
level.info->ExitPic = sc.String;
|
||||
Level->info->ExitPic = sc.String;
|
||||
}
|
||||
else if (sc.Compare("gravity"))
|
||||
{
|
||||
sc.MustGetStringName("=");
|
||||
sc.MustGetNumber();
|
||||
level.gravity=sc.Number*8.f;
|
||||
Level->gravity=sc.Number*8.f;
|
||||
}
|
||||
else if (sc.Compare("nextlevel"))
|
||||
{
|
||||
sc.MustGetStringName("=");
|
||||
sc.MustGetString();
|
||||
level.NextMap = sc.String;
|
||||
Level->NextMap = sc.String;
|
||||
}
|
||||
else if (sc.Compare("nextsecret"))
|
||||
{
|
||||
sc.MustGetStringName("=");
|
||||
sc.MustGetString();
|
||||
level.NextSecretMap = sc.String;
|
||||
Level->NextSecretMap = sc.String;
|
||||
}
|
||||
else if (sc.Compare("drown"))
|
||||
{
|
||||
|
@ -228,7 +182,7 @@ void FScriptLoader::ParseInfoCmd(char *line, FString &scriptsrc)
|
|||
while (*beg<' ') beg++;
|
||||
char * comm = strstr(beg, "//");
|
||||
if (comm) *comm=0;
|
||||
FS_EmulateCmd(beg);
|
||||
FS_EmulateCmd(Level, beg);
|
||||
}
|
||||
else if (sc.Compare("ignore"))
|
||||
{
|
||||
|
@ -303,23 +257,17 @@ bool FScriptLoader::ParseInfo(MapData * map)
|
|||
}
|
||||
if (HasScripts)
|
||||
{
|
||||
Create<DFraggleThinker>();
|
||||
DFraggleThinker::ActiveThinker->LevelScript->data = copystring(scriptsrc.GetChars());
|
||||
|
||||
if (drownflag==-1) drownflag = (level.maptype != MAPTYPE_DOOM || fsglobal);
|
||||
if (!drownflag) level.airsupply=0; // Legacy doesn't to water damage so we need to check if it has to be disabled here.
|
||||
|
||||
FFsOptions *opt = level.info->GetOptData<FFsOptions>("fragglescript", false);
|
||||
if (opt != NULL)
|
||||
if (Level->FraggleScriptThinker)
|
||||
{
|
||||
DFraggleThinker::ActiveThinker->nocheckposition = opt->nocheckposition;
|
||||
DFraggleThinker::ActiveThinker->setcolormaterial = opt->setcolormaterial;
|
||||
}
|
||||
else
|
||||
{
|
||||
DFraggleThinker::ActiveThinker->nocheckposition = false;
|
||||
DFraggleThinker::ActiveThinker->setcolormaterial = false;
|
||||
I_Error("Only one FraggleThinker is allowed to exist at a time.\nCheck your code.");
|
||||
}
|
||||
|
||||
auto th = Create<DFraggleThinker>();
|
||||
th->LevelScript->data = copystring(scriptsrc.GetChars());
|
||||
Level->FraggleScriptThinker = th;
|
||||
|
||||
if (drownflag==-1) drownflag = (Level->maptype != MAPTYPE_DOOM || fsglobal);
|
||||
if (!drownflag) Level->airsupply=0; // Legacy doesn't to water damage so we need to check if it has to be disabled here.
|
||||
}
|
||||
|
||||
|
||||
|
@ -334,12 +282,9 @@ bool FScriptLoader::ParseInfo(MapData * map)
|
|||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void T_LoadScripts(MapData *map)
|
||||
void T_LoadScripts(FLevelLocals *Level, MapData *map)
|
||||
{
|
||||
FScriptLoader parser;
|
||||
|
||||
T_Init();
|
||||
|
||||
FScriptLoader parser(Level);
|
||||
bool HasScripts = parser.ParseInfo(map);
|
||||
|
||||
// Hack for Legacy compatibility: Since 272 is normally an MBF sky transfer we have to patch it.
|
||||
|
@ -348,12 +293,10 @@ void T_LoadScripts(MapData *map)
|
|||
// This code then then swaps 270 and 272 - but only if this is either Doom or Heretic and
|
||||
// the default translator is being used.
|
||||
// Custom translators will not be patched.
|
||||
if ((gameinfo.gametype == GAME_Doom || gameinfo.gametype == GAME_Heretic) && level.info->Translator.IsEmpty() &&
|
||||
level.maptype == MAPTYPE_DOOM && SimpleLineTranslations.Size() > 272 && SimpleLineTranslations[272 - 2*HasScripts].special == FS_Execute)
|
||||
if ((gameinfo.gametype == GAME_Doom || gameinfo.gametype == GAME_Heretic) && Level->info->Translator.IsEmpty() &&
|
||||
Level->maptype == MAPTYPE_DOOM && SimpleLineTranslations.Size() > 272 && SimpleLineTranslations[272 - 2*HasScripts].special == FS_Execute)
|
||||
{
|
||||
FLineTrans t = SimpleLineTranslations[270];
|
||||
SimpleLineTranslations[270] = SimpleLineTranslations[272];
|
||||
SimpleLineTranslations[272] = t;
|
||||
std::swap(SimpleLineTranslations[270], SimpleLineTranslations[272]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -364,11 +307,11 @@ void T_LoadScripts(MapData *map)
|
|||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void T_AddSpawnedThing(AActor * ac)
|
||||
void T_AddSpawnedThing(FLevelLocals *Level, AActor * ac)
|
||||
{
|
||||
if (DFraggleThinker::ActiveThinker)
|
||||
if (Level->FraggleScriptThinker)
|
||||
{
|
||||
auto &SpawnedThings = DFraggleThinker::ActiveThinker->SpawnedThings;
|
||||
auto &SpawnedThings = Level->FraggleScriptThinker->SpawnedThings;
|
||||
SpawnedThings.Push(GC::ReadBarrier(ac));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -89,7 +89,7 @@ void FParser::OPequals(svalue_t &result, int start, int n, int stop)
|
|||
if(var)
|
||||
{
|
||||
EvaluateExpression(result, n+1, stop);
|
||||
var->SetValue (result);
|
||||
var->SetValue(Level, result);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -490,12 +490,12 @@ void FParser::OPincrement(svalue_t &result, int start, int n, int stop)
|
|||
{
|
||||
result.value.i = intvalue(result) + 1;
|
||||
result.type = svt_int;
|
||||
var->SetValue (result);
|
||||
var->SetValue(Level, result);
|
||||
}
|
||||
else
|
||||
{
|
||||
result.setDouble(floatvalue(result)+1);
|
||||
var->SetValue (result);
|
||||
var->SetValue(Level, result);
|
||||
}
|
||||
}
|
||||
else if(stop == n) // n++
|
||||
|
@ -515,12 +515,12 @@ void FParser::OPincrement(svalue_t &result, int start, int n, int stop)
|
|||
{
|
||||
newvalue.type = svt_int;
|
||||
newvalue.value.i = intvalue(result) + 1;
|
||||
var->SetValue (newvalue);
|
||||
var->SetValue(Level, newvalue);
|
||||
}
|
||||
else
|
||||
{
|
||||
newvalue.setDouble(floatvalue(result)+1);
|
||||
var->SetValue (newvalue);
|
||||
var->SetValue(Level, newvalue);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -553,13 +553,13 @@ void FParser::OPdecrement(svalue_t &result, int start, int n, int stop)
|
|||
{
|
||||
result.value.i = intvalue(result) - 1;
|
||||
result.type = svt_int;
|
||||
var->SetValue (result);
|
||||
var->SetValue(Level, result);
|
||||
}
|
||||
else
|
||||
{
|
||||
result.setDouble(floatvalue(result)-1);
|
||||
result.type = svt_fixed;
|
||||
var->SetValue (result);
|
||||
var->SetValue(Level, result);
|
||||
}
|
||||
}
|
||||
else if(stop == n) // n++
|
||||
|
@ -579,12 +579,12 @@ void FParser::OPdecrement(svalue_t &result, int start, int n, int stop)
|
|||
{
|
||||
newvalue.type = svt_int;
|
||||
newvalue.value.i = intvalue(result) - 1;
|
||||
var->SetValue (newvalue);
|
||||
var->SetValue(Level, newvalue);
|
||||
}
|
||||
else
|
||||
{
|
||||
newvalue.setDouble(floatvalue(result)-1);
|
||||
var->SetValue (newvalue);
|
||||
var->SetValue(Level, newvalue);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include "t_script.h"
|
||||
#include "w_wad.h"
|
||||
#include "serializer.h"
|
||||
#include "g_levellocals.h"
|
||||
|
||||
|
||||
//==========================================================================
|
||||
|
@ -129,7 +130,7 @@ void DFsScript::ClearSections()
|
|||
var->Destroy();
|
||||
var = next;
|
||||
}
|
||||
sections[i] = NULL;
|
||||
sections[i] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -338,7 +339,7 @@ void DFsScript::DryRunScript()
|
|||
char *rover = data;
|
||||
|
||||
// allocate space for the tokens
|
||||
FParser parse(this);
|
||||
FParser parse(&level, this);
|
||||
try
|
||||
{
|
||||
while(rover < end && *rover)
|
||||
|
@ -428,7 +429,7 @@ void DFsScript::ParseInclude(char *lumpname)
|
|||
ProcessFindChar(lump, 0);
|
||||
|
||||
// now parse the lump
|
||||
FParser parse(this);
|
||||
FParser parse(&level, this);
|
||||
parse.Run(lump, lump, lump+lumplen);
|
||||
|
||||
// free the lump
|
||||
|
|
|
@ -40,19 +40,6 @@
|
|||
#include "serializer.h"
|
||||
#include "g_levellocals.h"
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// global variables
|
||||
// These two are the last remaining ones:
|
||||
// - The global script contains static data so it must be global
|
||||
// - The trigger is referenced by a global variable. However, it is set
|
||||
// each time a script is started so that's not a problem.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
DFsScript *global_script;
|
||||
AActor *trigger_obj;
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
|
@ -122,7 +109,7 @@ void DFsScript::ClearChildren()
|
|||
for(j=0;j<MAXSCRIPTS;j++) if (children[j])
|
||||
{
|
||||
children[j]->Destroy();
|
||||
children[j]=NULL;
|
||||
children[j]=nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -136,15 +123,15 @@ DFsScript::DFsScript()
|
|||
{
|
||||
int i;
|
||||
|
||||
for(i=0; i<SECTIONSLOTS; i++) sections[i] = NULL;
|
||||
for(i=0; i<VARIABLESLOTS; i++) variables[i] = NULL;
|
||||
for(i=0; i<MAXSCRIPTS; i++) children[i] = NULL;
|
||||
for(i=0; i<SECTIONSLOTS; i++) sections[i] = nullptr;
|
||||
for(i=0; i<VARIABLESLOTS; i++) variables[i] = nullptr;
|
||||
for(i=0; i<MAXSCRIPTS; i++) children[i] = nullptr;
|
||||
|
||||
data = NULL;
|
||||
data = nullptr;
|
||||
scriptnum = -1;
|
||||
len = 0;
|
||||
parent = NULL;
|
||||
trigger = NULL;
|
||||
parent = nullptr;
|
||||
trigger = nullptr;
|
||||
lastiftrue = false;
|
||||
}
|
||||
|
||||
|
@ -157,8 +144,8 @@ DFsScript::DFsScript()
|
|||
|
||||
DFsScript::~DFsScript()
|
||||
{
|
||||
if (data != NULL) delete[] data;
|
||||
data = NULL;
|
||||
if (data != nullptr) delete[] data;
|
||||
data = nullptr;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -172,11 +159,11 @@ void DFsScript::OnDestroy()
|
|||
ClearVariables(true);
|
||||
ClearSections();
|
||||
ClearChildren();
|
||||
parent = NULL;
|
||||
if (data != NULL) delete [] data;
|
||||
data = NULL;
|
||||
parent = NULL;
|
||||
trigger = NULL;
|
||||
parent = nullptr;
|
||||
if (data != nullptr) delete [] data;
|
||||
data = nullptr;
|
||||
parent = nullptr;
|
||||
trigger = nullptr;
|
||||
Super::OnDestroy();
|
||||
}
|
||||
|
||||
|
@ -189,8 +176,8 @@ void DFsScript::OnDestroy()
|
|||
void DFsScript::Serialize(FSerializer &arc)
|
||||
{
|
||||
Super::Serialize(arc);
|
||||
// don't save a reference to the global script
|
||||
if (parent == global_script) parent = nullptr;
|
||||
// don't save a reference to the global script, which contains unserializable data.
|
||||
if (parent == level.FraggleScriptThinker->GlobalScript) parent = nullptr;
|
||||
|
||||
arc("data", data)
|
||||
("scriptnum", scriptnum)
|
||||
|
@ -202,7 +189,7 @@ void DFsScript::Serialize(FSerializer &arc)
|
|||
.Array("variables", variables, VARIABLESLOTS)
|
||||
.Array("children", children, MAXSCRIPTS);
|
||||
|
||||
if (parent == nullptr) parent = global_script;
|
||||
if (parent == nullptr) parent = level.FraggleScriptThinker->GlobalScript;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -215,7 +202,7 @@ void DFsScript::Serialize(FSerializer &arc)
|
|||
|
||||
void DFsScript::ParseScript(char *position)
|
||||
{
|
||||
if (position == NULL)
|
||||
if (position == nullptr)
|
||||
{
|
||||
lastiftrue = false;
|
||||
position = data;
|
||||
|
@ -228,11 +215,11 @@ void DFsScript::ParseScript(char *position)
|
|||
return;
|
||||
}
|
||||
|
||||
trigger_obj = trigger; // set trigger
|
||||
level.FraggleScriptThinker->trigger_obj = trigger; // set trigger
|
||||
|
||||
try
|
||||
{
|
||||
FParser parse(this);
|
||||
FParser parse(&level, this);
|
||||
parse.Run(position, data, data + len);
|
||||
}
|
||||
catch (CFraggleScriptError &err)
|
||||
|
@ -270,7 +257,7 @@ IMPLEMENT_POINTERS_END
|
|||
|
||||
DRunningScript::DRunningScript(AActor *trigger, DFsScript *owner, int index)
|
||||
{
|
||||
prev = next = NULL;
|
||||
prev = next = nullptr;
|
||||
script = owner;
|
||||
GC::WriteBarrier(this, script);
|
||||
save_point = index;
|
||||
|
@ -278,9 +265,9 @@ DRunningScript::DRunningScript(AActor *trigger, DFsScript *owner, int index)
|
|||
wait_data = 0;
|
||||
|
||||
this->trigger = trigger;
|
||||
if (owner == NULL)
|
||||
if (owner == nullptr)
|
||||
{
|
||||
for(int i=0; i< VARIABLESLOTS; i++) variables[i] = NULL;
|
||||
for(int i=0; i< VARIABLESLOTS; i++) variables[i] = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -333,7 +320,7 @@ void DRunningScript::OnDestroy()
|
|||
current->Destroy();
|
||||
current = next; // go to next in chain
|
||||
}
|
||||
variables[i] = NULL;
|
||||
variables[i] = nullptr;
|
||||
}
|
||||
Super::OnDestroy();
|
||||
}
|
||||
|
@ -369,10 +356,9 @@ IMPLEMENT_CLASS(DFraggleThinker, false, true)
|
|||
IMPLEMENT_POINTERS_START(DFraggleThinker)
|
||||
IMPLEMENT_POINTER(RunningScripts)
|
||||
IMPLEMENT_POINTER(LevelScript)
|
||||
IMPLEMENT_POINTER(GlobalScript)
|
||||
IMPLEMENT_POINTERS_END
|
||||
|
||||
TObjPtr<DFraggleThinker*> DFraggleThinker::ActiveThinker;
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
|
@ -382,20 +368,18 @@ TObjPtr<DFraggleThinker*> DFraggleThinker::ActiveThinker;
|
|||
DFraggleThinker::DFraggleThinker()
|
||||
: DThinker(STAT_SCRIPTS)
|
||||
{
|
||||
if (ActiveThinker)
|
||||
GlobalScript = Create<DFsScript>();
|
||||
GC::WriteBarrier(this, GlobalScript);
|
||||
// do not create resources which will be filled in by the serializer if being called from there.
|
||||
if (!bSerialOverride)
|
||||
{
|
||||
I_Error ("Only one FraggleThinker is allowed to exist at a time.\nCheck your code.");
|
||||
}
|
||||
else
|
||||
{
|
||||
ActiveThinker = this;
|
||||
RunningScripts = Create<DRunningScript>();
|
||||
LevelScript = Create<DFsScript>();
|
||||
LevelScript->parent = global_script;
|
||||
GC::WriteBarrier(this, RunningScripts);
|
||||
LevelScript = Create<DFsScript>();
|
||||
LevelScript->parent = GlobalScript;
|
||||
GC::WriteBarrier(this, LevelScript);
|
||||
nocheckposition = false;
|
||||
}
|
||||
InitFunctions();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -411,16 +395,18 @@ void DFraggleThinker::OnDestroy()
|
|||
{
|
||||
DRunningScript *q = p;
|
||||
p = p->next;
|
||||
q->prev = q->next = NULL;
|
||||
q->prev = q->next = nullptr;
|
||||
q->Destroy();
|
||||
}
|
||||
RunningScripts = NULL;
|
||||
RunningScripts = nullptr;
|
||||
|
||||
GlobalScript->Destroy();
|
||||
GlobalScript = nullptr;
|
||||
|
||||
LevelScript->Destroy();
|
||||
LevelScript = NULL;
|
||||
LevelScript = nullptr;
|
||||
|
||||
SpawnedThings.Clear();
|
||||
ActiveThinker = NULL;
|
||||
Super::OnDestroy();
|
||||
}
|
||||
|
||||
|
@ -432,11 +418,11 @@ void DFraggleThinker::OnDestroy()
|
|||
|
||||
void DFraggleThinker::Serialize(FSerializer &arc)
|
||||
{
|
||||
// The global script is not serialized because the data it points to is not serializable.
|
||||
Super::Serialize(arc);
|
||||
arc("levelscript", LevelScript)
|
||||
("runningscripts", RunningScripts)
|
||||
("spawnedthings", SpawnedThings)
|
||||
("nocheckposition", nocheckposition);
|
||||
("spawnedthings", SpawnedThings);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -522,7 +508,7 @@ void DFraggleThinker::Tick()
|
|||
{
|
||||
current->script->variables[i] = current->variables[i];
|
||||
GC::WriteBarrier(current->script, current->variables[i]);
|
||||
current->variables[i] = NULL;
|
||||
current->variables[i] = nullptr;
|
||||
}
|
||||
current->script->trigger = current->trigger; // copy trigger
|
||||
|
||||
|
@ -616,9 +602,9 @@ void DFraggleThinker::AddRunningScript(DRunningScript *runscr)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void T_PreprocessScripts()
|
||||
void T_PreprocessScripts(FLevelLocals *Level)
|
||||
{
|
||||
DFraggleThinker *th = DFraggleThinker::ActiveThinker;
|
||||
DFraggleThinker *th = Level->FraggleScriptThinker;
|
||||
if (th)
|
||||
{
|
||||
// run the levelscript first
|
||||
|
@ -638,9 +624,9 @@ void T_PreprocessScripts()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
bool T_RunScript(int snum, AActor * t_trigger)
|
||||
bool T_RunScript(FLevelLocals *Level, int snum, AActor * t_trigger)
|
||||
{
|
||||
DFraggleThinker *th = DFraggleThinker::ActiveThinker;
|
||||
DFraggleThinker *th = Level->FraggleScriptThinker;
|
||||
if (th)
|
||||
{
|
||||
// [CO] It is far too dangerous to start the script right away.
|
||||
|
@ -662,35 +648,7 @@ bool T_RunScript(int snum, AActor * t_trigger)
|
|||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FS_Close()
|
||||
{
|
||||
if (global_script != NULL)
|
||||
{
|
||||
GC::DelSoftRoot(global_script);
|
||||
global_script->Destroy();
|
||||
global_script = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void T_Init()
|
||||
{
|
||||
void init_functions();
|
||||
|
||||
if (global_script == NULL)
|
||||
{
|
||||
global_script = Create<DFsScript>();
|
||||
GC::AddSoftRoot(global_script);
|
||||
init_functions();
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
// This isn't network safe. FraggleScript as a whole most likely isn't...
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
|
@ -704,6 +662,6 @@ CCMD(fpuke)
|
|||
}
|
||||
else
|
||||
{
|
||||
T_RunScript(atoi(argv[1]), players[consoleplayer].mo);
|
||||
T_RunScript(&level, atoi(argv[1]), players[consoleplayer].mo);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -129,7 +129,7 @@ int intvalue(const svalue_t & v);
|
|||
fsfix fixedvalue(const svalue_t & v);
|
||||
double floatvalue(const svalue_t & v);
|
||||
const char *stringvalue(const svalue_t & v);
|
||||
AActor *actorvalue(const svalue_t &svalue);
|
||||
AActor *actorvalue(FLevelLocals *Level, const svalue_t &svalue);
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -185,7 +185,7 @@ public:
|
|||
DFsVariable(const char *_name = "");
|
||||
|
||||
void GetValue(svalue_t &result);
|
||||
void SetValue(const svalue_t &newvalue);
|
||||
void SetValue(FLevelLocals *Level, const svalue_t &newvalue);
|
||||
void Serialize(FSerializer &ar);
|
||||
};
|
||||
|
||||
|
@ -232,7 +232,7 @@ public:
|
|||
|
||||
DFsSection()
|
||||
{
|
||||
next = NULL;
|
||||
next = nullptr;
|
||||
}
|
||||
|
||||
void Serialize(FSerializer &ar);
|
||||
|
@ -398,6 +398,7 @@ struct FParser
|
|||
char *Tokens[T_MAXTOKENS];
|
||||
tokentype_t TokenType[T_MAXTOKENS];
|
||||
int NumTokens;
|
||||
FLevelLocals *Level;
|
||||
DFsScript *Script; // the current script
|
||||
DFsSection *Section;
|
||||
DFsSection *PrevSection;
|
||||
|
@ -408,8 +409,9 @@ struct FParser
|
|||
svalue_t t_return; // returned value
|
||||
FString t_func; // name of current function
|
||||
|
||||
FParser(DFsScript *scr)
|
||||
FParser(FLevelLocals *l, DFsScript *scr)
|
||||
{
|
||||
Level = l;
|
||||
LineStart = NULL;
|
||||
Rover = NULL;
|
||||
Tokens[0] = new char[scr->len+32]; // 32 for safety. FS seems to need a few bytes more than the script's actual length.
|
||||
|
@ -482,6 +484,15 @@ struct FParser
|
|||
FString GetFormatString(int startarg);
|
||||
bool CheckArgs(int cnt);
|
||||
|
||||
PClassActor * T_GetMobjType(svalue_t arg);
|
||||
int T_GetPlayerNum(const svalue_t &arg);
|
||||
AActor *T_GetPlayerActor(const svalue_t &arg);
|
||||
|
||||
AActor* actorvalue(const svalue_t &svalue)
|
||||
{
|
||||
return ::actorvalue(Level, svalue);
|
||||
}
|
||||
|
||||
void SF_Print();
|
||||
void SF_Rnd();
|
||||
void SF_Continue();
|
||||
|
@ -678,11 +689,12 @@ class DFraggleThinker : public DThinker
|
|||
HAS_OBJECT_POINTERS
|
||||
public:
|
||||
|
||||
int zoom = 1;
|
||||
AActor *trigger_obj; // this is a transient pointer not being subjected to GC.
|
||||
TObjPtr<DFsScript*> GlobalScript;
|
||||
TObjPtr<DFsScript*> LevelScript;
|
||||
TObjPtr<DRunningScript*> RunningScripts;
|
||||
TArray<TObjPtr<AActor*> > SpawnedThings;
|
||||
bool nocheckposition = false;
|
||||
bool setcolormaterial = false;
|
||||
|
||||
DFraggleThinker();
|
||||
void OnDestroy() override;
|
||||
|
@ -690,6 +702,7 @@ public:
|
|||
|
||||
void Serialize(FSerializer & arc);
|
||||
void Tick();
|
||||
void InitFunctions();
|
||||
size_t PropagateMark();
|
||||
size_t PointerSubstitution (DObject *old, DObject *notOld);
|
||||
bool wait_finished(DRunningScript *script);
|
||||
|
@ -707,11 +720,7 @@ public:
|
|||
#include "t_fs.h"
|
||||
|
||||
void script_error(const char *s, ...) GCCPRINTF(1,2);
|
||||
void FS_EmulateCmd(char * string);
|
||||
|
||||
extern AActor *trigger_obj;
|
||||
extern DFsScript *global_script;
|
||||
|
||||
void FS_EmulateCmd(FLevelLocals *l, char * string);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
//
|
||||
|
||||
#include "t_script.h"
|
||||
#include "g_levellocals.h"
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -467,7 +468,7 @@ void FParser::EvaluateFunction(svalue_t &result, int start, int stop)
|
|||
}
|
||||
|
||||
// all the functions are stored in the global script
|
||||
else if( !(func = global_script->VariableForName (Tokens[start])) )
|
||||
else if( !(func = Level->FraggleScriptThinker->GlobalScript->VariableForName (Tokens[start])) )
|
||||
{
|
||||
script_error("no such function: '%s'\n",Tokens[start]);
|
||||
}
|
||||
|
@ -551,7 +552,7 @@ void FParser::OPstructure(svalue_t &result, int start, int n, int stop)
|
|||
svalue_t argv[MAXARGS];
|
||||
|
||||
// all the functions are stored in the global script
|
||||
if( !(func = global_script->VariableForName (Tokens[n+1])) )
|
||||
if( !(func = Level->FraggleScriptThinker->GlobalScript->VariableForName (Tokens[n+1])) )
|
||||
{
|
||||
script_error("no such function: '%s'\n",Tokens[n+1]);
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "t_script.h"
|
||||
#include "a_pickups.h"
|
||||
#include "serializer.h"
|
||||
#include "g_levellocals.h"
|
||||
|
||||
|
||||
//==========================================================================
|
||||
|
@ -122,7 +123,7 @@ const char *stringvalue(const svalue_t & v)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
AActor* actorvalue(const svalue_t &svalue)
|
||||
AActor* actorvalue(FLevelLocals *Level, const svalue_t &svalue)
|
||||
{
|
||||
int intval;
|
||||
|
||||
|
@ -138,9 +139,9 @@ AActor* actorvalue(const svalue_t &svalue)
|
|||
}
|
||||
else
|
||||
{
|
||||
auto &SpawnedThings = DFraggleThinker::ActiveThinker->SpawnedThings;
|
||||
auto &SpawnedThings = Level->FraggleScriptThinker->SpawnedThings;
|
||||
// this requires some creativity. We use the intvalue
|
||||
// as the thing number of a thing in the level.
|
||||
// as the thing number of a thing in the level
|
||||
intval = intvalue(svalue);
|
||||
|
||||
if(intval < 0 || intval >= (int)SpawnedThings.Size())
|
||||
|
@ -178,9 +179,9 @@ DFsVariable::DFsVariable(const char * _name)
|
|||
{
|
||||
Name=_name;
|
||||
type=svt_int;
|
||||
actor = NULL;
|
||||
actor = nullptr;
|
||||
value.i=0;
|
||||
next=NULL;
|
||||
next = nullptr;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -234,7 +235,7 @@ void DFsVariable::GetValue(svalue_t &returnvar)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void DFsVariable::SetValue(const svalue_t &newvalue)
|
||||
void DFsVariable::SetValue(FLevelLocals *Level, const svalue_t &newvalue)
|
||||
{
|
||||
if(type == svt_const)
|
||||
{
|
||||
|
@ -264,7 +265,7 @@ void DFsVariable::SetValue(const svalue_t &newvalue)
|
|||
break;
|
||||
|
||||
case svt_mobj:
|
||||
actor = actorvalue(newvalue);
|
||||
actor = actorvalue(Level, newvalue);
|
||||
break;
|
||||
|
||||
case svt_pInt:
|
||||
|
@ -272,7 +273,7 @@ void DFsVariable::SetValue(const svalue_t &newvalue)
|
|||
break;
|
||||
|
||||
case svt_pMobj:
|
||||
*value.pMobj = actorvalue(newvalue);
|
||||
*value.pMobj = actorvalue(Level, newvalue);
|
||||
break;
|
||||
|
||||
case svt_function:
|
||||
|
|
103
src/g_game.cpp
103
src/g_game.cpp
|
@ -71,6 +71,7 @@
|
|||
#include "serializer.h"
|
||||
#include "vm.h"
|
||||
#include "dobjgc.h"
|
||||
#include "gi.h"
|
||||
|
||||
#include "g_hub.h"
|
||||
#include "g_levellocals.h"
|
||||
|
@ -181,8 +182,6 @@ short consistancy[MAXPLAYERS][BACKUPTICS];
|
|||
|
||||
#define TURBOTHRESHOLD 12800
|
||||
|
||||
float normforwardmove[2] = {0x19, 0x32}; // [RH] For setting turbo from console
|
||||
float normsidemove[2] = {0x18, 0x28}; // [RH] Ditto
|
||||
|
||||
int forwardmove[2], sidemove[2];
|
||||
int angleturn[4] = {640, 1280, 320, 320}; // + slow turn
|
||||
|
@ -223,8 +222,14 @@ EXTERN_CVAR (Int, team)
|
|||
|
||||
CVAR (Bool, teamplay, false, CVAR_SERVERINFO)
|
||||
|
||||
// Workaround for x64 code generation bug in MSVC 2015
|
||||
// Optimized targets contain illegal instructions in the function below
|
||||
#if defined _M_X64 && _MSC_VER < 1910
|
||||
#pragma optimize("", off)
|
||||
#endif // _M_X64 && _MSC_VER < 1910
|
||||
|
||||
// [RH] Allow turbo setting anytime during game
|
||||
CUSTOM_CVAR (Float, turbo, 100.f, 0)
|
||||
CUSTOM_CVAR (Float, turbo, 100.f, CVAR_NOINITCALL)
|
||||
{
|
||||
if (self < 10.f)
|
||||
{
|
||||
|
@ -238,13 +243,17 @@ CUSTOM_CVAR (Float, turbo, 100.f, 0)
|
|||
{
|
||||
double scale = self * 0.01;
|
||||
|
||||
forwardmove[0] = (int)(normforwardmove[0]*scale);
|
||||
forwardmove[1] = (int)(normforwardmove[1]*scale);
|
||||
sidemove[0] = (int)(normsidemove[0]*scale);
|
||||
sidemove[1] = (int)(normsidemove[1]*scale);
|
||||
forwardmove[0] = (int)(gameinfo.normforwardmove[0]*scale);
|
||||
forwardmove[1] = (int)(gameinfo.normforwardmove[1]*scale);
|
||||
sidemove[0] = (int)(gameinfo.normsidemove[0]*scale);
|
||||
sidemove[1] = (int)(gameinfo.normsidemove[1]*scale);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined _M_X64 && _MSC_VER < 1910
|
||||
#pragma optimize("", on)
|
||||
#endif // _M_X64 && _MSC_VER < 1910
|
||||
|
||||
CCMD (turnspeeds)
|
||||
{
|
||||
if (argv.argc() == 1)
|
||||
|
@ -285,7 +294,7 @@ CCMD (slot)
|
|||
if (slot < NUM_WEAPON_SLOTS && mo)
|
||||
{
|
||||
// Needs to be redone
|
||||
IFVIRTUALPTR(mo, APlayerPawn, PickWeapon)
|
||||
IFVIRTUALPTRNAME(mo, NAME_PlayerPawn, PickWeapon)
|
||||
{
|
||||
VMValue param[] = { mo, slot, !(dmflags2 & DF2_DONTCHECKAMMO) };
|
||||
VMReturn ret((void**)&SendItemUse);
|
||||
|
@ -326,7 +335,7 @@ CCMD (weapnext)
|
|||
if (mo)
|
||||
{
|
||||
// Needs to be redone
|
||||
IFVIRTUALPTR(mo, APlayerPawn, PickNextWeapon)
|
||||
IFVIRTUALPTRNAME(mo, NAME_PlayerPawn, PickNextWeapon)
|
||||
{
|
||||
VMValue param[] = { mo };
|
||||
VMReturn ret((void**)&SendItemUse);
|
||||
|
@ -352,7 +361,7 @@ CCMD (weapprev)
|
|||
if (mo)
|
||||
{
|
||||
// Needs to be redone
|
||||
IFVIRTUALPTR(mo, APlayerPawn, PickPrevWeapon)
|
||||
IFVIRTUALPTRNAME(mo, NAME_PlayerPawn, PickPrevWeapon)
|
||||
{
|
||||
VMValue param[] = { mo };
|
||||
VMReturn ret((void**)&SendItemUse);
|
||||
|
@ -421,14 +430,14 @@ CCMD (invuse)
|
|||
{
|
||||
if (players[consoleplayer].inventorytics == 0)
|
||||
{
|
||||
if (players[consoleplayer].mo) SendItemUse = players[consoleplayer].mo->InvSel;
|
||||
if (players[consoleplayer].mo) SendItemUse = players[consoleplayer].mo->PointerVar<AActor>(NAME_InvSel);
|
||||
}
|
||||
players[consoleplayer].inventorytics = 0;
|
||||
}
|
||||
|
||||
CCMD(invquery)
|
||||
{
|
||||
AActor *inv = players[consoleplayer].mo->InvSel;
|
||||
AActor *inv = players[consoleplayer].mo->PointerVar<AActor>(NAME_InvSel);
|
||||
if (inv != NULL)
|
||||
{
|
||||
Printf(PRINT_HIGH, "%s (%dx)\n", inv->GetTag(), inv->IntVar(NAME_Amount));
|
||||
|
@ -447,7 +456,7 @@ CCMD (invdrop)
|
|||
{
|
||||
if (players[consoleplayer].mo)
|
||||
{
|
||||
SendItemDrop = players[consoleplayer].mo->InvSel;
|
||||
SendItemDrop = players[consoleplayer].mo->PointerVar<AActor>(NAME_InvSel);
|
||||
SendItemDropAmount = -1;
|
||||
}
|
||||
}
|
||||
|
@ -467,40 +476,17 @@ CCMD (drop)
|
|||
}
|
||||
}
|
||||
|
||||
PClassActor *GetFlechetteType(AActor *other);
|
||||
|
||||
CCMD (useflechette)
|
||||
{ // Select from one of arti_poisonbag1-3, whichever the player has
|
||||
static const ENamedName bagnames[3] =
|
||||
{
|
||||
if (who == nullptr) return;
|
||||
IFVIRTUALPTRNAME(who, NAME_PlayerPawn, GetFlechetteItem)
|
||||
{
|
||||
NAME_ArtiPoisonBag3, // use type 3 first because that's the default when the player has none specified.
|
||||
NAME_ArtiPoisonBag1,
|
||||
NAME_ArtiPoisonBag2
|
||||
};
|
||||
VMValue params[] = { who };
|
||||
AActor *cls;
|
||||
VMReturn ret((void**)&cls);
|
||||
VMCall(func, params, 1, &ret, 1);
|
||||
|
||||
if (who == NULL)
|
||||
return;
|
||||
|
||||
PClassActor *type = who->FlechetteType;
|
||||
if (type != NULL)
|
||||
{
|
||||
AActor *item;
|
||||
if ( (item = who->FindInventory (type) ))
|
||||
{
|
||||
SendItemUse = item;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// The default flechette could not be found, or the player had no default. Try all 3 types then.
|
||||
for (int j = 0; j < 3; ++j)
|
||||
{
|
||||
AActor *item;
|
||||
if ( (item = who->FindInventory (bagnames[j])) )
|
||||
{
|
||||
SendItemUse = item;
|
||||
break;
|
||||
}
|
||||
if (cls != nullptr) SendItemUse = cls;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -511,7 +497,7 @@ CCMD (select)
|
|||
auto item = who->FindInventory(argv[1]);
|
||||
if (item != NULL)
|
||||
{
|
||||
who->InvSel = item;
|
||||
who->PointerVar<AActor>(NAME_InvSel) = item;
|
||||
}
|
||||
}
|
||||
who->player->inventorytics = 5*TICRATE;
|
||||
|
@ -1035,9 +1021,8 @@ void G_Ticker ()
|
|||
|
||||
if (ToggleFullscreen)
|
||||
{
|
||||
static char toggle_fullscreen[] = "toggle fullscreen";
|
||||
ToggleFullscreen = false;
|
||||
AddCommandString (toggle_fullscreen);
|
||||
AddCommandString ("toggle fullscreen");
|
||||
}
|
||||
|
||||
// do things to change the game state
|
||||
|
@ -1187,6 +1172,7 @@ void G_Ticker ()
|
|||
|
||||
// [ZZ] also tick the UI part of the events
|
||||
E_UiTick();
|
||||
C_RunDelayedCommands();
|
||||
|
||||
// do main actions
|
||||
switch (gamestate)
|
||||
|
@ -1266,7 +1252,7 @@ void G_PlayerReborn (int player)
|
|||
int chasecam;
|
||||
uint8_t currclass;
|
||||
userinfo_t userinfo; // [RH] Save userinfo
|
||||
APlayerPawn *actor;
|
||||
AActor *actor;
|
||||
PClassActor *cls;
|
||||
FString log;
|
||||
DBot *Bot; //Added by MC:
|
||||
|
@ -1313,7 +1299,12 @@ void G_PlayerReborn (int player)
|
|||
if (gamestate != GS_TITLELEVEL)
|
||||
{
|
||||
// [GRB] Give inventory specified in DECORATE
|
||||
actor->GiveDefaultInventory ();
|
||||
|
||||
IFVIRTUALPTRNAME(actor, NAME_PlayerPawn, GiveDefaultInventory)
|
||||
{
|
||||
VMValue params[1] = { actor };
|
||||
VMCall(func, params, 1, nullptr, 0);
|
||||
}
|
||||
p->ReadyWeapon = p->PendingWeapon;
|
||||
}
|
||||
|
||||
|
@ -1701,11 +1692,11 @@ void G_DoPlayerPop(int playernum)
|
|||
}
|
||||
|
||||
// [RH] Make the player disappear
|
||||
FBehavior::StaticStopMyScripts(players[playernum].mo);
|
||||
level.Behaviors.StopMyScripts(players[playernum].mo);
|
||||
// [ZZ] fire player disconnect hook
|
||||
E_PlayerDisconnected(playernum);
|
||||
// [RH] Let the scripts know the player left
|
||||
FBehavior::StaticStartTypedScripts(SCRIPT_Disconnect, players[playernum].mo, true, playernum, true);
|
||||
level.Behaviors.StartTypedScripts(SCRIPT_Disconnect, players[playernum].mo, true, playernum, true);
|
||||
if (players[playernum].mo != NULL)
|
||||
{
|
||||
P_DisconnectEffect(players[playernum].mo);
|
||||
|
@ -1717,7 +1708,7 @@ void G_DoPlayerPop(int playernum)
|
|||
players[playernum].mo->Destroy();
|
||||
}
|
||||
players[playernum].mo = NULL;
|
||||
players[playernum].camera = NULL;
|
||||
players[playernum].camera = nullptr;
|
||||
}
|
||||
|
||||
players[playernum].DestroyPSprites();
|
||||
|
@ -2024,8 +2015,6 @@ CUSTOM_CVAR (Int, autosavecount, 4, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
|||
self = 0;
|
||||
}
|
||||
|
||||
extern void P_CalcHeight (player_t *);
|
||||
|
||||
void G_DoAutoSave ()
|
||||
{
|
||||
FString description;
|
||||
|
@ -2095,9 +2084,9 @@ static void PutSaveComment (FSerializer &arc)
|
|||
comment.Format("%s - %s\n", level.MapName.GetChars(), level.LevelName.GetChars());
|
||||
|
||||
// Append elapsed time
|
||||
const char *const time = GStrings("SAVECOMMENT_TIME");
|
||||
levelTime = level.time / TICRATE;
|
||||
comment.AppendFormat("time: %02d:%02d:%02d",
|
||||
levelTime/3600, (levelTime%3600)/60, levelTime%60);
|
||||
comment.AppendFormat("%s: %02d:%02d:%02d", time, levelTime/3600, (levelTime%3600)/60, levelTime%60);
|
||||
|
||||
// Write out the comment
|
||||
arc.AddString("Comment", comment);
|
||||
|
@ -2783,7 +2772,7 @@ bool G_CheckDemoStatus (void)
|
|||
for (int i = 1; i < MAXPLAYERS; i++)
|
||||
playeringame[i] = 0;
|
||||
consoleplayer = 0;
|
||||
players[0].camera = NULL;
|
||||
players[0].camera = nullptr;
|
||||
if (StatusBar != NULL)
|
||||
{
|
||||
StatusBar->AttachToPlayer (&players[0]);
|
||||
|
|
|
@ -104,22 +104,11 @@ struct Keygroup
|
|||
|
||||
struct Lock
|
||||
{
|
||||
TArray<Keygroup *> keylist;
|
||||
TArray<Keygroup> keylist;
|
||||
TArray<FSoundID> locksound;
|
||||
FString Message;
|
||||
FString RemoteMsg;
|
||||
int rgb;
|
||||
|
||||
Lock()
|
||||
{
|
||||
rgb=0;
|
||||
}
|
||||
|
||||
~Lock()
|
||||
{
|
||||
for(unsigned int i=0;i<keylist.Size();i++) delete keylist[i];
|
||||
keylist.Clear();
|
||||
}
|
||||
int rgb = 0;
|
||||
|
||||
bool check(AActor * owner)
|
||||
{
|
||||
|
@ -138,25 +127,21 @@ struct Lock
|
|||
}
|
||||
else for(unsigned int i=0;i<keylist.Size();i++)
|
||||
{
|
||||
if (!keylist[i]->check(owner)) return false;
|
||||
if (!keylist[i].check(owner)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
static TMap<int, Lock> Locks;
|
||||
static bool keysdone = false; // have the locks been initialized?
|
||||
static TArray<PClassActor *> KeyTypes; // List of all keys sorted by lock. This is for use by the status bar to draw ordered key lists.
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
static Lock *locks[256]; // all valid locks
|
||||
static bool keysdone=false; // have the locks been initialized?
|
||||
static int currentnumber; // number to be assigned to next key
|
||||
static bool ignorekey; // set to true when the current lock is not being used
|
||||
static TArray<PClassActor *> KeyTypes; // List of all keys sorted by lock.
|
||||
|
||||
static void ClearLocks();
|
||||
|
||||
static const char * keywords_lock[]={
|
||||
"ANY",
|
||||
"MESSAGE",
|
||||
|
@ -171,7 +156,7 @@ static const char * keywords_lock[]={
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
static void AddOneKey(Keygroup *keygroup, PClassActor *mi, FScanner &sc)
|
||||
static void AddOneKey(Keygroup *keygroup, PClassActor *mi, FScanner &sc, bool ignorekey, int ¤tnumber)
|
||||
{
|
||||
if (mi)
|
||||
{
|
||||
|
@ -208,26 +193,18 @@ static void AddOneKey(Keygroup *keygroup, PClassActor *mi, FScanner &sc)
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
static Keygroup *ParseKeygroup(FScanner &sc)
|
||||
static void ParseKeygroup(Keygroup *keygroup, FScanner &sc, bool ignorekey, int ¤tnumber)
|
||||
{
|
||||
Keygroup *keygroup;
|
||||
PClassActor *mi;
|
||||
|
||||
sc.MustGetStringName("{");
|
||||
keygroup = new Keygroup;
|
||||
while (!sc.CheckString("}"))
|
||||
{
|
||||
sc.MustGetString();
|
||||
mi = PClass::FindActor(sc.String);
|
||||
AddOneKey(keygroup, mi, sc);
|
||||
}
|
||||
if (keygroup->anykeylist.Size() == 0)
|
||||
{
|
||||
delete keygroup;
|
||||
return NULL;
|
||||
AddOneKey(keygroup, mi, sc, ignorekey, currentnumber);
|
||||
}
|
||||
keygroup->anykeylist.ShrinkToFit();
|
||||
return keygroup;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -252,13 +229,11 @@ static void PrintMessage (const char *str)
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
static void ParseLock(FScanner &sc)
|
||||
static void ParseLock(FScanner &sc, int ¤tnumber)
|
||||
{
|
||||
int i,r,g,b;
|
||||
int keynum;
|
||||
Lock sink;
|
||||
Lock *lock = &sink;
|
||||
Keygroup *keygroup;
|
||||
PClassActor *mi;
|
||||
|
||||
sc.MustGetNumber();
|
||||
|
@ -271,23 +246,16 @@ static void ParseLock(FScanner &sc)
|
|||
sc.MustGetStringName("{");
|
||||
}
|
||||
|
||||
ignorekey = true;
|
||||
if (keynum > 0 && keynum <= 255)
|
||||
{
|
||||
lock = new Lock;
|
||||
if (locks[keynum])
|
||||
{
|
||||
delete locks[keynum];
|
||||
}
|
||||
locks[keynum] = lock;
|
||||
locks[keynum]->locksound.Push("*keytry");
|
||||
locks[keynum]->locksound.Push("misc/keytry");
|
||||
ignorekey=false;
|
||||
}
|
||||
else if (keynum != -1)
|
||||
if (keynum == 0 || keynum < -1)
|
||||
{
|
||||
sc.ScriptError("Lock index %d out of range", keynum);
|
||||
}
|
||||
bool ignorekey = keynum == -1; // tell the parsing functions to ignore what they read for other games' keys.
|
||||
|
||||
auto lock = keynum == -1? &sink : &Locks.InsertNew(keynum);
|
||||
|
||||
lock->locksound.Push("*keytry");
|
||||
lock->locksound.Push("misc/keytry");
|
||||
|
||||
while (!sc.CheckString("}"))
|
||||
{
|
||||
|
@ -295,12 +263,15 @@ static void ParseLock(FScanner &sc)
|
|||
switch(i = sc.MatchString(keywords_lock))
|
||||
{
|
||||
case 0: // Any
|
||||
keygroup = ParseKeygroup(sc);
|
||||
if (keygroup)
|
||||
{
|
||||
lock->keylist.Reserve(1);
|
||||
ParseKeygroup(&lock->keylist.Last(), sc, ignorekey, currentnumber);
|
||||
if (lock->keylist.Last().anykeylist.Size() == 0)
|
||||
{
|
||||
lock->keylist.Push(keygroup);
|
||||
lock->keylist.Pop();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 1: // message
|
||||
sc.MustGetString();
|
||||
|
@ -344,12 +315,11 @@ static void ParseLock(FScanner &sc)
|
|||
mi = PClass::FindActor(sc.String);
|
||||
if (mi)
|
||||
{
|
||||
keygroup = new Keygroup;
|
||||
AddOneKey(keygroup, mi, sc);
|
||||
if (keygroup)
|
||||
lock->keylist.Reserve(1);
|
||||
AddOneKey(&lock->keylist.Last(), mi, sc, ignorekey, currentnumber);
|
||||
if (lock->keylist.Last().anykeylist.Size() == 0)
|
||||
{
|
||||
keygroup->anykeylist.ShrinkToFit();
|
||||
lock->keylist.Push(keygroup);
|
||||
lock->keylist.Pop();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -389,15 +359,7 @@ static void ClearLocks()
|
|||
}
|
||||
}
|
||||
}
|
||||
for(i = 0; i < 256; i++)
|
||||
{
|
||||
if (locks[i] != NULL)
|
||||
{
|
||||
delete locks[i];
|
||||
locks[i] = NULL;
|
||||
}
|
||||
}
|
||||
currentnumber = 0;
|
||||
Locks.Clear();
|
||||
keysdone = false;
|
||||
}
|
||||
|
||||
|
@ -455,7 +417,7 @@ static void CreateSortedKeyList()
|
|||
|
||||
void P_InitKeyMessages()
|
||||
{
|
||||
int lastlump, lump;
|
||||
int lastlump, lump, currentnumber = 0;
|
||||
|
||||
lastlump = 0;
|
||||
|
||||
|
@ -467,12 +429,13 @@ void P_InitKeyMessages()
|
|||
{
|
||||
if (sc.Compare("LOCK"))
|
||||
{
|
||||
ParseLock(sc);
|
||||
ParseLock(sc, currentnumber);
|
||||
}
|
||||
else if (sc.Compare("CLEARLOCKS"))
|
||||
{
|
||||
// clear all existing lock definitions and key numbers
|
||||
ClearLocks();
|
||||
currentnumber = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -485,17 +448,6 @@ void P_InitKeyMessages()
|
|||
keysdone = true;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// P_DeinitKeyMessages
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void P_DeinitKeyMessages()
|
||||
{
|
||||
ClearLocks();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// P_CheckKeys
|
||||
|
@ -513,13 +465,14 @@ int P_CheckKeys (AActor *owner, int keynum, bool remote, bool quiet)
|
|||
int numfailsounds;
|
||||
|
||||
if (owner == NULL) return false;
|
||||
if (keynum<=0 || keynum>255) return true;
|
||||
if (keynum<=0) return true;
|
||||
// Just a safety precaution. The messages should have been initialized upon game start.
|
||||
if (!keysdone) P_InitKeyMessages();
|
||||
|
||||
FSoundID failage[2] = { "*keytry", "misc/keytry" };
|
||||
|
||||
if (!locks[keynum])
|
||||
auto lock = Locks.CheckKey(keynum);
|
||||
if (!lock)
|
||||
{
|
||||
if (quiet) return false;
|
||||
if (keynum == 103 && (gameinfo.flags & GI_SHAREWARE))
|
||||
|
@ -532,11 +485,11 @@ int P_CheckKeys (AActor *owner, int keynum, bool remote, bool quiet)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (locks[keynum]->check(owner)) return true;
|
||||
if (lock->check(owner)) return true;
|
||||
if (quiet) return false;
|
||||
failtext = remote? locks[keynum]->RemoteMsg : locks[keynum]->Message;
|
||||
failsound = &locks[keynum]->locksound[0];
|
||||
numfailsounds = locks[keynum]->locksound.Size();
|
||||
failtext = remote? lock->RemoteMsg : lock->Message;
|
||||
failsound = &lock->locksound[0];
|
||||
numfailsounds = lock->locksound.Size();
|
||||
}
|
||||
|
||||
// If we get here, that means the actor isn't holding an appropriate key.
|
||||
|
@ -570,11 +523,13 @@ int P_CheckKeys (AActor *owner, int keynum, bool remote, bool quiet)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
int P_GetMapColorForLock (int lock)
|
||||
int P_GetMapColorForLock (int locknum)
|
||||
{
|
||||
if (lock > 0 && lock < 256)
|
||||
if (locknum > 0)
|
||||
{
|
||||
if (locks[lock]) return locks[lock]->rgb;
|
||||
auto lock = Locks.CheckKey(locknum);
|
||||
|
||||
if (lock) return lock->rgb;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
@ -587,13 +542,20 @@ int P_GetMapColorForLock (int lock)
|
|||
|
||||
int P_GetMapColorForKey (AActor * key)
|
||||
{
|
||||
int i;
|
||||
decltype(Locks)::Iterator it(Locks);
|
||||
decltype(Locks)::Pair *pair;
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
int foundlock = INT_MAX;
|
||||
int rgb = 0;
|
||||
while (it.NextPair(pair))
|
||||
{
|
||||
if (locks[i] && locks[i]->check(key)) return locks[i]->rgb;
|
||||
if (pair->Key < foundlock && pair->Value.check(key))
|
||||
{
|
||||
rgb = pair->Value.rgb;
|
||||
foundlock = pair->Key;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return rgb;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@ class PClassActor;
|
|||
|
||||
int P_CheckKeys (AActor *owner, int keynum, bool remote, bool quiet = false);
|
||||
void P_InitKeyMessages ();
|
||||
void P_DeinitKeyMessages ();
|
||||
int P_GetMapColorForLock (int lock);
|
||||
int P_GetMapColorForKey (AActor *key);
|
||||
int P_GetKeyTypeCount();
|
||||
|
|
|
@ -53,12 +53,12 @@
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
FString WeaponSection;
|
||||
static FString WeaponSection;
|
||||
TArray<FString> KeyConfWeapons;
|
||||
FWeaponSlots *PlayingKeyConf;
|
||||
static FWeaponSlots *PlayingKeyConf;
|
||||
|
||||
TArray<PClassActor *> Weapons_ntoh;
|
||||
TMap<PClassActor *, int> Weapons_hton;
|
||||
static TArray<PClassActor *> Weapons_ntoh;
|
||||
static TMap<PClassActor *, int> Weapons_hton;
|
||||
|
||||
static int ntoh_cmp(const void *a, const void *b);
|
||||
|
||||
|
@ -491,7 +491,7 @@ void FWeaponSlots::SendDifferences(int playernum, const FWeaponSlots &other)
|
|||
void FWeaponSlots::SetFromPlayer(PClassActor *type)
|
||||
{
|
||||
Clear();
|
||||
auto Slot = ((APlayerPawn*)GetDefaultByType(type))->Slot;
|
||||
auto Slot = &GetDefaultByType(type)->NameVar(NAME_Slot);
|
||||
for (int i = 0; i < NUM_WEAPON_SLOTS; ++i)
|
||||
{
|
||||
if (Slot[i] != NAME_None)
|
||||
|
@ -748,15 +748,14 @@ void P_PlaybackKeyConfWeapons(FWeaponSlots *slots)
|
|||
PlayingKeyConf = slots;
|
||||
for (unsigned int i = 0; i < KeyConfWeapons.Size(); ++i)
|
||||
{
|
||||
FString cmd(KeyConfWeapons[i]);
|
||||
AddCommandString(cmd.LockBuffer());
|
||||
AddCommandString(KeyConfWeapons[i]);
|
||||
}
|
||||
PlayingKeyConf = nullptr;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// APlayerPawn :: SetupWeaponSlots
|
||||
// SetupWeaponSlots
|
||||
//
|
||||
// Sets up the default weapon slots for this player. If this is also the
|
||||
// local player, determines local modifications and sends those across the
|
||||
|
@ -764,7 +763,7 @@ void P_PlaybackKeyConfWeapons(FWeaponSlots *slots)
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
void FWeaponSlots::SetupWeaponSlots(APlayerPawn *pp)
|
||||
void FWeaponSlots::SetupWeaponSlots(AActor *pp)
|
||||
{
|
||||
auto player = pp->player;
|
||||
if (player != nullptr && player->mo == pp)
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
#include "a_pickups.h"
|
||||
class PClassActor;
|
||||
class APlayerPawn;
|
||||
|
||||
class FWeaponSlot
|
||||
{
|
||||
|
@ -69,7 +68,7 @@ public:
|
|||
void SendDifferences(int playernum, const FWeaponSlots &other);
|
||||
int RestoreSlots (FConfigFile *config, const char *section);
|
||||
void PrintSettings();
|
||||
static void SetupWeaponSlots(APlayerPawn *pp);
|
||||
static void SetupWeaponSlots(AActor *pp);
|
||||
|
||||
void AddSlot(int slot, PClassActor *type, bool feedback);
|
||||
void AddSlotDefault(int slot, PClassActor *type, bool feedback);
|
||||
|
|
|
@ -78,6 +78,7 @@
|
|||
#include "vm.h"
|
||||
#include "events.h"
|
||||
#include "i_music.h"
|
||||
#include "a_dynlight.h"
|
||||
|
||||
#include "gi.h"
|
||||
|
||||
|
@ -88,7 +89,7 @@
|
|||
#include "p_maputl.h"
|
||||
|
||||
void STAT_StartNewGame(const char *lev);
|
||||
void STAT_ChangeLevel(const char *newl);
|
||||
void STAT_ChangeLevel(const char *newl, FLevelLocals *Level);
|
||||
|
||||
EXTERN_CVAR(Bool, save_formatted)
|
||||
EXTERN_CVAR (Float, sv_gravity)
|
||||
|
@ -127,7 +128,7 @@ CUSTOM_CVAR(Int, gl_lightmode, 3, CVAR_ARCHIVE | CVAR_NOINITCALL)
|
|||
else if (newself > 4) newself = 8;
|
||||
else if (newself < 0) newself = 0;
|
||||
if (self != newself) self = newself;
|
||||
else if ((level.info == nullptr || level.info->lightmode == ELightMode::NotSet)) level.lightmode = (ELightMode)*self;
|
||||
else if ((level.info == nullptr || level.info->lightmode == ELightMode::NotSet)) level.lightMode = (ELightMode)*self;
|
||||
}
|
||||
|
||||
|
||||
|
@ -340,8 +341,8 @@ void G_NewInit ()
|
|||
int i;
|
||||
|
||||
// Destory all old player refrences that may still exist
|
||||
TThinkerIterator<APlayerPawn> it(STAT_TRAVELLING);
|
||||
APlayerPawn *pawn, *next;
|
||||
TThinkerIterator<AActor> it(NAME_PlayerPawn, STAT_TRAVELLING);
|
||||
AActor *pawn, *next;
|
||||
|
||||
next = it.Next();
|
||||
while ((pawn = next) != NULL)
|
||||
|
@ -464,13 +465,16 @@ void G_InitNew (const char *mapname, bool bTitleLevel)
|
|||
ST_CreateStatusBar(bTitleLevel);
|
||||
setsizeneeded = true;
|
||||
|
||||
if (gameinfo.gametype == GAME_Strife || (SBarInfoScript[SCRIPT_CUSTOM] != NULL && SBarInfoScript[SCRIPT_CUSTOM]->GetGameType() == GAME_Strife))
|
||||
const bool setlogtext = !savegamerestore && (gameinfo.gametype == GAME_Strife
|
||||
|| (SBarInfoScript[SCRIPT_CUSTOM] != nullptr && SBarInfoScript[SCRIPT_CUSTOM]->GetGameType() == GAME_Strife));
|
||||
|
||||
if (setlogtext)
|
||||
{
|
||||
// Set the initial quest log text for Strife.
|
||||
for (i = 0; i < MAXPLAYERS; ++i)
|
||||
{
|
||||
if (playeringame[i])
|
||||
players[i].SetLogText ("Find help");
|
||||
players[i].SetLogText ("$TXT_FINDHELP");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -640,14 +644,14 @@ void G_ChangeLevel(const char *levelname, int position, int flags, int nextSkill
|
|||
|
||||
// [RH] Give scripts a chance to do something
|
||||
unloading = true;
|
||||
FBehavior::StaticStartTypedScripts (SCRIPT_Unloading, NULL, false, 0, true);
|
||||
level.Behaviors.StartTypedScripts (SCRIPT_Unloading, NULL, false, 0, true);
|
||||
// [ZZ] safe world unload
|
||||
E_WorldUnloaded();
|
||||
// [ZZ] unsafe world unload (changemap != map)
|
||||
E_WorldUnloadedUnsafe();
|
||||
unloading = false;
|
||||
|
||||
STAT_ChangeLevel(nextlevel);
|
||||
STAT_ChangeLevel(nextlevel, &level);
|
||||
|
||||
if (thiscluster && (thiscluster->flags & CLUSTER_HUB))
|
||||
{
|
||||
|
@ -853,7 +857,7 @@ void G_DoCompleted (void)
|
|||
G_SnapshotLevel ();
|
||||
// Do not free any global strings this level might reference
|
||||
// while it's not loaded.
|
||||
FBehavior::StaticLockLevelVarStrings();
|
||||
level.Behaviors.LockLevelVarStrings(level.levelnum);
|
||||
}
|
||||
else
|
||||
{ // Make sure we don't have a snapshot lying around from before.
|
||||
|
@ -1088,7 +1092,7 @@ void G_DoLoadLevel (int position, bool autosave, bool newGame)
|
|||
if (fromSnapshot)
|
||||
{
|
||||
// ENTER scripts are being handled when the player gets spawned, this cannot be changed due to its effect on voodoo dolls.
|
||||
FBehavior::StaticStartTypedScripts(SCRIPT_Return, players[ii].mo, true);
|
||||
level.Behaviors.StartTypedScripts(SCRIPT_Return, players[ii].mo, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1096,7 +1100,7 @@ void G_DoLoadLevel (int position, bool autosave, bool newGame)
|
|||
if (level.FromSnapshot)
|
||||
{
|
||||
// [Nash] run REOPEN scripts upon map re-entry
|
||||
FBehavior::StaticStartTypedScripts(SCRIPT_Reopen, NULL, false);
|
||||
level.Behaviors.StartTypedScripts(SCRIPT_Reopen, NULL, false);
|
||||
}
|
||||
|
||||
StatusBar->AttachToPlayer (&players[consoleplayer]);
|
||||
|
@ -1288,7 +1292,7 @@ void G_StartTravel ()
|
|||
{
|
||||
AActor *pawn = players[i].mo;
|
||||
AActor *inv;
|
||||
players[i].camera = NULL;
|
||||
players[i].camera = nullptr;
|
||||
|
||||
// Only living players travel. Dead ones get a new body on the new level.
|
||||
if (players[i].health > 0)
|
||||
|
@ -1298,11 +1302,13 @@ void G_StartTravel ()
|
|||
pawn->RemoveFromHash ();
|
||||
pawn->tid = tid; // Restore TID (but no longer linked into the hash chain)
|
||||
pawn->ChangeStatNum (STAT_TRAVELLING);
|
||||
pawn->DeleteAttachedLights();
|
||||
|
||||
for (inv = pawn->Inventory; inv != NULL; inv = inv->Inventory)
|
||||
{
|
||||
inv->ChangeStatNum (STAT_TRAVELLING);
|
||||
inv->UnlinkFromWorld (nullptr);
|
||||
inv->DeleteAttachedLights();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1324,15 +1330,15 @@ void G_StartTravel ()
|
|||
|
||||
int G_FinishTravel ()
|
||||
{
|
||||
TThinkerIterator<APlayerPawn> it (STAT_TRAVELLING);
|
||||
APlayerPawn *pawn, *pawndup, *oldpawn, *next;
|
||||
TThinkerIterator<AActor> it (NAME_PlayerPawn, STAT_TRAVELLING);
|
||||
AActor *pawn, *pawndup, *oldpawn, *next;
|
||||
AActor *inv;
|
||||
FPlayerStart *start;
|
||||
int pnum;
|
||||
int failnum = 0;
|
||||
|
||||
//
|
||||
APlayerPawn* pawns[MAXPLAYERS];
|
||||
AActor* pawns[MAXPLAYERS];
|
||||
int pawnsnum = 0;
|
||||
|
||||
next = it.Next ();
|
||||
|
@ -1388,11 +1394,11 @@ int G_FinishTravel ()
|
|||
{
|
||||
P_FindFloorCeiling(pawn);
|
||||
}
|
||||
pawn->target = NULL;
|
||||
pawn->lastenemy = NULL;
|
||||
pawn->target = nullptr;
|
||||
pawn->lastenemy = nullptr;
|
||||
pawn->player->mo = pawn;
|
||||
pawn->player->camera = pawn;
|
||||
pawn->player->viewheight = pawn->ViewHeight;
|
||||
pawn->player->viewheight = pawn->player->DefaultViewHeight();
|
||||
pawn->flags2 &= ~MF2_BLASTED;
|
||||
if (oldpawn != nullptr)
|
||||
{
|
||||
|
@ -1527,11 +1533,12 @@ void G_InitLevelLocals ()
|
|||
|
||||
level.DefaultEnvironment = info->DefaultEnvironment;
|
||||
|
||||
level.lightmode = info->lightmode == ELightMode::NotSet? (ELightMode)*gl_lightmode : info->lightmode;
|
||||
level.lightMode = info->lightmode == ELightMode::NotSet? (ELightMode)*gl_lightmode : info->lightmode;
|
||||
level.brightfog = info->brightfog < 0? gl_brightfog : !!info->brightfog;
|
||||
level.lightadditivesurfaces = info->lightadditivesurfaces < 0 ? gl_lightadditivesurfaces : !!info->lightadditivesurfaces;
|
||||
level.notexturefill = info->notexturefill < 0 ? gl_notexturefill : !!info->notexturefill;
|
||||
|
||||
FLightDefaults::SetAttenuationForLevel();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -1682,8 +1689,8 @@ void G_UnSnapshotLevel (bool hubLoad)
|
|||
G_SerializeLevel (arc, hubLoad);
|
||||
level.FromSnapshot = true;
|
||||
|
||||
TThinkerIterator<APlayerPawn> it;
|
||||
APlayerPawn *pawn, *next;
|
||||
TThinkerIterator<AActor> it(NAME_PlayerPawn);
|
||||
AActor *pawn, *next;
|
||||
|
||||
next = it.Next();
|
||||
while ((pawn = next) != 0)
|
||||
|
@ -1714,7 +1721,7 @@ void G_UnSnapshotLevel (bool hubLoad)
|
|||
if (hubLoad)
|
||||
{
|
||||
// Unlock ACS global strings that were locked when the snapshot was made.
|
||||
FBehavior::StaticUnlockLevelVarStrings();
|
||||
level.Behaviors.UnlockLevelVarStrings(level.levelnum);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1964,7 +1971,14 @@ void FLevelLocals::Tick ()
|
|||
|
||||
void FLevelLocals::Mark()
|
||||
{
|
||||
GC::Mark(SpotState);
|
||||
GC::Mark(FraggleScriptThinker);
|
||||
GC::Mark(ACSThinker);
|
||||
canvasTextureInfo.Mark();
|
||||
for (auto &c : CorpseQueue)
|
||||
{
|
||||
GC::Mark(c);
|
||||
}
|
||||
for (auto &s : sectorPortals)
|
||||
{
|
||||
GC::Mark(s.mSkybox);
|
||||
|
@ -2132,7 +2146,7 @@ DEFINE_ACTION_FUNCTION(FLevelLocals, SphericalCoords)
|
|||
|
||||
ACTION_RETURN_VEC3(DVector3(
|
||||
deltaangle(vecTo.Angle(), viewYaw).Degrees,
|
||||
deltaangle(-vecTo.Pitch(), viewPitch).Degrees,
|
||||
deltaangle(vecTo.Pitch(), viewPitch).Degrees,
|
||||
vecTo.Length()
|
||||
));
|
||||
}
|
||||
|
|
|
@ -263,25 +263,6 @@ class DScroller;
|
|||
class FScanner;
|
||||
struct level_info_t;
|
||||
|
||||
struct FOptionalMapinfoData
|
||||
{
|
||||
FOptionalMapinfoData *Next = nullptr;
|
||||
FName identifier = NAME_None;
|
||||
virtual ~FOptionalMapinfoData() {}
|
||||
virtual FOptionalMapinfoData *Clone() const = 0;
|
||||
};
|
||||
|
||||
struct FOptionalMapinfoDataPtr
|
||||
{
|
||||
FOptionalMapinfoData *Ptr;
|
||||
|
||||
FOptionalMapinfoDataPtr() throw() : Ptr(NULL) {}
|
||||
~FOptionalMapinfoDataPtr() { if (Ptr!=NULL) delete Ptr; }
|
||||
FOptionalMapinfoDataPtr(const FOptionalMapinfoDataPtr &p) throw() : Ptr(p.Ptr->Clone()) {}
|
||||
FOptionalMapinfoDataPtr &operator= (FOptionalMapinfoDataPtr &p) throw() { Ptr = p.Ptr->Clone(); return *this; }
|
||||
};
|
||||
|
||||
typedef TMap<FName, FOptionalMapinfoDataPtr> FOptData;
|
||||
typedef TMap<int, FName> FMusicMap;
|
||||
|
||||
enum EMapType : int
|
||||
|
@ -315,18 +296,6 @@ struct FExitText
|
|||
}
|
||||
};
|
||||
|
||||
enum class ELightMode : int8_t
|
||||
{
|
||||
NotSet = -1,
|
||||
LinearStandard = 0,
|
||||
DoomBright = 1,
|
||||
Doom = 2,
|
||||
DoomDark = 3,
|
||||
DoomLegacy = 4,
|
||||
ZDoomSoftware = 8,
|
||||
DoomSoftware = 16
|
||||
};
|
||||
|
||||
|
||||
struct level_info_t
|
||||
{
|
||||
|
@ -398,7 +367,6 @@ struct level_info_t
|
|||
|
||||
double teamdamage;
|
||||
|
||||
FOptData optdata;
|
||||
FMusicMap MusicMap;
|
||||
|
||||
TArray<FSpecialAction> specialactions;
|
||||
|
@ -416,6 +384,10 @@ struct level_info_t
|
|||
FVector3 skyrotatevector;
|
||||
FVector3 skyrotatevector2;
|
||||
|
||||
FString EDName;
|
||||
FString acsName;
|
||||
bool fs_nocheckposition;
|
||||
|
||||
|
||||
level_info_t()
|
||||
{
|
||||
|
@ -434,24 +406,6 @@ struct level_info_t
|
|||
deferred.Clear();
|
||||
}
|
||||
level_info_t *CheckLevelRedirect ();
|
||||
|
||||
template<class T>
|
||||
T *GetOptData(FName id, bool create = true)
|
||||
{
|
||||
FOptionalMapinfoDataPtr *pdat = optdata.CheckKey(id);
|
||||
|
||||
if (pdat != NULL)
|
||||
{
|
||||
return static_cast<T*>(pdat->Ptr);
|
||||
}
|
||||
else if (create)
|
||||
{
|
||||
T *newobj = new T;
|
||||
optdata[id].Ptr = newobj;
|
||||
return newobj;
|
||||
}
|
||||
else return NULL;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -42,18 +42,25 @@
|
|||
#include "portal.h"
|
||||
#include "p_blockmap.h"
|
||||
#include "p_local.h"
|
||||
#include "po_man.h"
|
||||
#include "p_acs.h"
|
||||
#include "p_destructible.h"
|
||||
#include "r_data/r_sections.h"
|
||||
#include "r_data/r_canvastexture.h"
|
||||
|
||||
class DACSThinker;
|
||||
class DFraggleThinker;
|
||||
class DSpotState;
|
||||
|
||||
struct FLevelData
|
||||
{
|
||||
TArray<vertex_t> vertexes;
|
||||
TArray<sector_t> sectors;
|
||||
TArray<line_t*> linebuffer; // contains the line lists for the sectors.
|
||||
TArray<subsector_t*> subsectorbuffer; // contains the subsector lists for the sectors.
|
||||
TArray<line_t> lines;
|
||||
TArray<side_t> sides;
|
||||
TArray<seg_t *> segbuffer; // contains the seg links for the sidedefs.
|
||||
TArray<seg_t> segs;
|
||||
TArray<subsector_t> subsectors;
|
||||
TArray<node_t> nodes;
|
||||
|
@ -62,6 +69,7 @@ struct FLevelData
|
|||
node_t *headgamenode;
|
||||
TArray<uint8_t> rejectmatrix;
|
||||
TArray<zone_t> Zones;
|
||||
TArray<FPolyObj> Polyobjects;
|
||||
|
||||
TArray<FSectorPortal> sectorPortals;
|
||||
TArray<FLinePortal> linePortals;
|
||||
|
@ -79,6 +87,7 @@ struct FLevelData
|
|||
TMap<int, FHealthGroup> healthGroups;
|
||||
|
||||
FBlockmap blockmap;
|
||||
TArray<polyblock_t *> PolyBlockMap;
|
||||
|
||||
// These are copies of the loaded map data that get used by the savegame code to skip unaltered fields
|
||||
// Without such a mechanism the savegame format would become too slow and large because more than 80-90% are normally still unaltered.
|
||||
|
@ -91,6 +100,7 @@ struct FLevelData
|
|||
FPlayerStart playerstarts[MAXPLAYERS];
|
||||
TArray<FPlayerStart> AllPlayerStarts;
|
||||
|
||||
FBehaviorContainer Behaviors;
|
||||
};
|
||||
|
||||
struct FLevelLocals : public FLevelData
|
||||
|
@ -100,6 +110,8 @@ struct FLevelLocals : public FLevelData
|
|||
void AddScroller(int secnum);
|
||||
void SetInterMusic(const char *nextmap);
|
||||
void SetMusicVolume(float v);
|
||||
void ClearLevelData();
|
||||
void ClearPortals();
|
||||
|
||||
uint8_t md5[16]; // for savegame validation. If the MD5 does not match the savegame won't be loaded.
|
||||
int time; // time in the hub
|
||||
|
@ -186,10 +198,20 @@ struct FLevelLocals : public FLevelData
|
|||
float MusicVolume;
|
||||
|
||||
// Hardware render stuff that can either be set via CVAR or MAPINFO
|
||||
ELightMode lightmode;
|
||||
ELightMode lightMode;
|
||||
bool brightfog;
|
||||
bool lightadditivesurfaces;
|
||||
bool notexturefill;
|
||||
int ImpactDecalCount;
|
||||
|
||||
FDynamicLight *lights;
|
||||
|
||||
// links to global game objects
|
||||
TArray<TObjPtr<AActor *>> CorpseQueue;
|
||||
TObjPtr<DFraggleThinker *> FraggleScriptThinker = nullptr;
|
||||
TObjPtr<DACSThinker*> ACSThinker = nullptr;
|
||||
|
||||
TObjPtr<DSpotState *> SpotState = nullptr;
|
||||
|
||||
bool IsJumpingAllowed() const;
|
||||
bool IsCrouchingAllowed() const;
|
||||
|
@ -210,67 +232,17 @@ struct FLevelLocals : public FLevelData
|
|||
return savegamerestore
|
||||
|| (info != nullptr && info->Snapshot.mBuffer != nullptr && info->isValid());
|
||||
}
|
||||
|
||||
bool isSoftwareLighting() const
|
||||
{
|
||||
return lightmode >= ELightMode::ZDoomSoftware;
|
||||
}
|
||||
|
||||
bool isDarkLightMode() const
|
||||
{
|
||||
return !!((int)lightmode & (int)ELightMode::Doom);
|
||||
}
|
||||
|
||||
void SetFallbackLightMode()
|
||||
{
|
||||
lightmode = ELightMode::Doom;
|
||||
}
|
||||
};
|
||||
|
||||
#ifndef NO_DEFINE_LEVEL
|
||||
|
||||
extern FLevelLocals level;
|
||||
|
||||
inline int vertex_t::Index() const
|
||||
{
|
||||
return int(this - &level.vertexes[0]);
|
||||
}
|
||||
|
||||
inline int side_t::Index() const
|
||||
{
|
||||
return int(this - &level.sides[0]);
|
||||
}
|
||||
|
||||
inline int line_t::Index() const
|
||||
{
|
||||
return int(this - &level.lines[0]);
|
||||
}
|
||||
|
||||
inline int seg_t::Index() const
|
||||
{
|
||||
return int(this - &level.segs[0]);
|
||||
}
|
||||
|
||||
inline int subsector_t::Index() const
|
||||
{
|
||||
return int(this - &level.subsectors[0]);
|
||||
}
|
||||
|
||||
inline int node_t::Index() const
|
||||
{
|
||||
return int(this - &level.nodes[0]);
|
||||
}
|
||||
|
||||
inline FSectorPortal *line_t::GetTransferredPortal()
|
||||
{
|
||||
return portaltransferred >= level.sectorPortals.Size() ? (FSectorPortal*)nullptr : &level.sectorPortals[portaltransferred];
|
||||
}
|
||||
|
||||
inline int sector_t::Index() const
|
||||
{
|
||||
return int(this - &level.sectors[0]);
|
||||
}
|
||||
|
||||
inline FSectorPortal *sector_t::GetPortal(int plane)
|
||||
{
|
||||
return &level.sectorPortals[Portals[plane]];
|
||||
|
|
|
@ -1445,6 +1445,34 @@ DEFINE_MAP_OPTION(skyrotate2, false)
|
|||
info->skyrotatevector2.MakeUnit();
|
||||
}
|
||||
|
||||
DEFINE_MAP_OPTION(fs_nocheckposition, false)
|
||||
{
|
||||
if (parse.CheckAssign())
|
||||
{
|
||||
parse.sc.MustGetNumber();
|
||||
info->fs_nocheckposition = !!parse.sc.Number;
|
||||
}
|
||||
else
|
||||
{
|
||||
info->fs_nocheckposition = true;
|
||||
}
|
||||
}
|
||||
|
||||
DEFINE_MAP_OPTION(edata, false)
|
||||
{
|
||||
parse.ParseAssign();
|
||||
parse.sc.MustGetString();
|
||||
info->EDName = parse.sc.String;
|
||||
}
|
||||
|
||||
DEFINE_MAP_OPTION(loadacs, false)
|
||||
{
|
||||
parse.ParseAssign();
|
||||
parse.sc.MustGetString();
|
||||
info->acsName = parse.sc.String;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// All flag based map options
|
||||
|
|
|
@ -60,7 +60,7 @@ void A_Unblock(AActor *self, bool drop)
|
|||
self->Conversation = NULL;
|
||||
|
||||
// If the actor has attached metadata for items to drop, drop those.
|
||||
if (drop && !self->IsKindOf (RUNTIME_CLASS (APlayerPawn))) // [GRB]
|
||||
if (drop && !self->IsKindOf(NAME_PlayerPawn)) // [GRB]
|
||||
{
|
||||
auto di = self->GetDropItems();
|
||||
|
||||
|
@ -88,109 +88,21 @@ void A_Unblock(AActor *self, bool drop)
|
|||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
// Corpse queue for monsters - this should be saved out
|
||||
|
||||
class DCorpsePointer : public DThinker
|
||||
{
|
||||
DECLARE_CLASS (DCorpsePointer, DThinker)
|
||||
HAS_OBJECT_POINTERS
|
||||
public:
|
||||
DCorpsePointer (AActor *ptr);
|
||||
void Queue();
|
||||
void OnDestroy() override;
|
||||
void Serialize(FSerializer &arc);
|
||||
TObjPtr<AActor*> Corpse;
|
||||
uint32_t Count; // Only the first corpse pointer's count is valid.
|
||||
private:
|
||||
DCorpsePointer () {}
|
||||
};
|
||||
|
||||
IMPLEMENT_CLASS(DCorpsePointer, false, true)
|
||||
|
||||
IMPLEMENT_POINTERS_START(DCorpsePointer)
|
||||
IMPLEMENT_POINTER(Corpse)
|
||||
IMPLEMENT_POINTERS_END
|
||||
|
||||
CUSTOM_CVAR(Int, sv_corpsequeuesize, 64, CVAR_ARCHIVE|CVAR_SERVERINFO)
|
||||
{
|
||||
if (self > 0)
|
||||
{
|
||||
TThinkerIterator<DCorpsePointer> iterator (STAT_CORPSEPOINTER);
|
||||
DCorpsePointer *first = iterator.Next ();
|
||||
while (first != NULL && first->Count > (uint32_t)self)
|
||||
auto &corpsequeue = level.CorpseQueue;
|
||||
while (corpsequeue.Size() > (unsigned)self)
|
||||
{
|
||||
DCorpsePointer *next = iterator.Next ();
|
||||
first->Destroy ();
|
||||
first = next;
|
||||
AActor *corpse = corpsequeue[0];
|
||||
if (corpse) corpse->Destroy();
|
||||
corpsequeue.Delete(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DCorpsePointer::DCorpsePointer(AActor *ptr)
|
||||
: DThinker(STAT_CORPSEPOINTER), Corpse(ptr)
|
||||
{
|
||||
Count = 0;
|
||||
}
|
||||
|
||||
void DCorpsePointer::Queue()
|
||||
{
|
||||
// Thinkers are added to the end of their respective lists, so
|
||||
// the first thinker in the list is the oldest one.
|
||||
TThinkerIterator<DCorpsePointer> iterator (STAT_CORPSEPOINTER);
|
||||
DCorpsePointer *first = iterator.Next ();
|
||||
|
||||
if (first != nullptr)
|
||||
{
|
||||
if (first != this)
|
||||
{
|
||||
if (first->Count >= (uint32_t)sv_corpsequeuesize)
|
||||
{
|
||||
DCorpsePointer *next = iterator.Next();
|
||||
first->Destroy();
|
||||
first = next;
|
||||
}
|
||||
}
|
||||
++first->Count;
|
||||
}
|
||||
}
|
||||
|
||||
void DCorpsePointer::OnDestroy ()
|
||||
{
|
||||
// Store the count of corpses in the first thinker in the list
|
||||
TThinkerIterator<DCorpsePointer> iterator (STAT_CORPSEPOINTER);
|
||||
DCorpsePointer *first = iterator.Next ();
|
||||
|
||||
// During a serialization unwind the thinker list won't be available.
|
||||
if (first != nullptr)
|
||||
{
|
||||
int prevCount = first->Count;
|
||||
|
||||
if (first == this)
|
||||
{
|
||||
first = iterator.Next();
|
||||
}
|
||||
|
||||
if (first != NULL)
|
||||
{
|
||||
first->Count = prevCount - 1;
|
||||
}
|
||||
|
||||
}
|
||||
if (Corpse != NULL)
|
||||
{
|
||||
Corpse->Destroy();
|
||||
}
|
||||
Super::OnDestroy();
|
||||
}
|
||||
|
||||
void DCorpsePointer::Serialize(FSerializer &arc)
|
||||
{
|
||||
Super::Serialize(arc);
|
||||
arc("corpse", Corpse)
|
||||
("count", Count);
|
||||
}
|
||||
|
||||
|
||||
// throw another corpse on the queue
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_QueueCorpse)
|
||||
|
@ -199,28 +111,28 @@ DEFINE_ACTION_FUNCTION(AActor, A_QueueCorpse)
|
|||
|
||||
if (sv_corpsequeuesize > 0)
|
||||
{
|
||||
auto p = Create<DCorpsePointer> (self);
|
||||
p->Queue();
|
||||
auto &corpsequeue = level.CorpseQueue;
|
||||
while (corpsequeue.Size() >= (unsigned)sv_corpsequeuesize)
|
||||
{
|
||||
AActor *corpse = corpsequeue[0];
|
||||
if (corpse) corpse->Destroy();
|
||||
corpsequeue.Delete(0);
|
||||
}
|
||||
corpsequeue.Push(self);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Remove an self from the queue (for resurrection)
|
||||
// Remove an actor from the queue (for resurrection)
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_DeQueueCorpse)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
|
||||
TThinkerIterator<DCorpsePointer> iterator (STAT_CORPSEPOINTER);
|
||||
DCorpsePointer *corpsePtr;
|
||||
|
||||
while ((corpsePtr = iterator.Next()) != NULL)
|
||||
auto &corpsequeue = level.CorpseQueue;
|
||||
auto index = corpsequeue.FindEx([=](auto &element) { return element == self; });
|
||||
if (index < corpsequeue.Size())
|
||||
{
|
||||
if (corpsePtr->Corpse == self)
|
||||
{
|
||||
corpsePtr->Corpse = NULL;
|
||||
corpsePtr->Destroy ();
|
||||
return 0;
|
||||
}
|
||||
corpsequeue.Delete(index);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -45,11 +45,14 @@
|
|||
#include "g_levellocals.h"
|
||||
#include "vm.h"
|
||||
|
||||
static double DecalWidth, DecalLeft, DecalRight;
|
||||
static double SpreadZ;
|
||||
static const DBaseDecal *SpreadSource;
|
||||
static const FDecalTemplate *SpreadTemplate;
|
||||
static TArray<side_t *> SpreadStack;
|
||||
struct SpreadInfo
|
||||
{
|
||||
double DecalWidth, DecalLeft, DecalRight;
|
||||
double SpreadZ;
|
||||
const DBaseDecal *SpreadSource;
|
||||
const FDecalTemplate *SpreadTemplate;
|
||||
TArray<side_t *> SpreadStack;
|
||||
};
|
||||
|
||||
static int ImpactCount;
|
||||
|
||||
|
@ -399,11 +402,11 @@ static side_t *NextWall (const side_t *wall)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void DBaseDecal::SpreadLeft (double r, vertex_t *v1, side_t *feelwall, F3DFloor *ffloor)
|
||||
void DBaseDecal::SpreadLeft (double r, vertex_t *v1, side_t *feelwall, F3DFloor *ffloor, SpreadInfo *spread)
|
||||
{
|
||||
double ldx, ldy;
|
||||
|
||||
SpreadStack.Push (feelwall);
|
||||
spread->SpreadStack.Push (feelwall);
|
||||
|
||||
while (r < 0 && feelwall->LeftSide != NO_SIDE)
|
||||
{
|
||||
|
@ -415,21 +418,21 @@ void DBaseDecal::SpreadLeft (double r, vertex_t *v1, side_t *feelwall, F3DFloor
|
|||
feelwall = &level.sides[feelwall->LeftSide];
|
||||
GetWallStuff (feelwall, v1, ldx, ldy);
|
||||
double wallsize = Length (ldx, ldy);
|
||||
r += DecalLeft;
|
||||
r += spread->DecalLeft;
|
||||
x += r*ldx / wallsize;
|
||||
y += r*ldy / wallsize;
|
||||
r = wallsize + startr;
|
||||
SpreadSource->CloneSelf (SpreadTemplate, x, y, SpreadZ, feelwall, ffloor);
|
||||
SpreadStack.Push (feelwall);
|
||||
spread->SpreadSource->CloneSelf (spread->SpreadTemplate, x, y, spread->SpreadZ, feelwall, ffloor);
|
||||
spread->SpreadStack.Push (feelwall);
|
||||
|
||||
side_t *nextwall = NextWall (feelwall);
|
||||
if (nextwall != NULL && nextwall->LeftSide != NO_SIDE)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = SpreadStack.Size(); i-- > 0; )
|
||||
for (i = spread->SpreadStack.Size(); i-- > 0; )
|
||||
{
|
||||
if (SpreadStack[i] == nextwall)
|
||||
if (spread->SpreadStack[i] == nextwall)
|
||||
break;
|
||||
}
|
||||
if (i == -1)
|
||||
|
@ -437,18 +440,18 @@ void DBaseDecal::SpreadLeft (double r, vertex_t *v1, side_t *feelwall, F3DFloor
|
|||
vertex_t *v2;
|
||||
|
||||
GetWallStuff (nextwall, v2, ldx, ldy);
|
||||
SpreadLeft (startr, v2, nextwall, ffloor);
|
||||
SpreadLeft (startr, v2, nextwall, ffloor, spread);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DBaseDecal::SpreadRight (double r, side_t *feelwall, double wallsize, F3DFloor *ffloor)
|
||||
void DBaseDecal::SpreadRight (double r, side_t *feelwall, double wallsize, F3DFloor *ffloor, SpreadInfo *spread)
|
||||
{
|
||||
vertex_t *v1;
|
||||
double x, y, ldx, ldy;
|
||||
|
||||
SpreadStack.Push (feelwall);
|
||||
spread->SpreadStack.Push (feelwall);
|
||||
|
||||
while (r > wallsize && feelwall->RightSide != NO_SIDE)
|
||||
{
|
||||
|
@ -459,32 +462,33 @@ void DBaseDecal::SpreadRight (double r, side_t *feelwall, double wallsize, F3DFl
|
|||
{
|
||||
int i;
|
||||
|
||||
for (i = SpreadStack.Size(); i-- > 0; )
|
||||
for (i = spread->SpreadStack.Size(); i-- > 0; )
|
||||
{
|
||||
if (SpreadStack[i] == nextwall)
|
||||
if (spread->SpreadStack[i] == nextwall)
|
||||
break;
|
||||
}
|
||||
if (i == -1)
|
||||
{
|
||||
SpreadRight (r, nextwall, wallsize, ffloor);
|
||||
SpreadRight (r, nextwall, wallsize, ffloor, spread);
|
||||
}
|
||||
}
|
||||
|
||||
r = DecalWidth - r + wallsize - DecalLeft;
|
||||
r = spread->DecalWidth - r + wallsize - spread->DecalLeft;
|
||||
GetWallStuff (feelwall, v1, ldx, ldy);
|
||||
x = v1->fX();
|
||||
y = v1->fY();
|
||||
wallsize = Length (ldx, ldy);
|
||||
x -= r*ldx / wallsize;
|
||||
y -= r*ldy / wallsize;
|
||||
r = DecalRight - r;
|
||||
SpreadSource->CloneSelf (SpreadTemplate, x, y, SpreadZ, feelwall, ffloor);
|
||||
SpreadStack.Push (feelwall);
|
||||
r = spread->DecalRight - r;
|
||||
spread->SpreadSource->CloneSelf (spread->SpreadTemplate, x, y, spread->SpreadZ, feelwall, ffloor);
|
||||
spread->SpreadStack.Push (feelwall);
|
||||
}
|
||||
}
|
||||
|
||||
void DBaseDecal::Spread (const FDecalTemplate *tpl, side_t *wall, double x, double y, double z, F3DFloor * ffloor)
|
||||
{
|
||||
SpreadInfo spread;
|
||||
FTexture *tex;
|
||||
vertex_t *v1;
|
||||
double rorg, ldx, ldy;
|
||||
|
@ -499,21 +503,20 @@ void DBaseDecal::Spread (const FDecalTemplate *tpl, side_t *wall, double x, doub
|
|||
|
||||
int dwidth = tex->GetDisplayWidth ();
|
||||
|
||||
DecalWidth = dwidth * ScaleX;
|
||||
DecalLeft = tex->GetDisplayLeftOffset() * ScaleX;
|
||||
DecalRight = DecalWidth - DecalLeft;
|
||||
SpreadSource = this;
|
||||
SpreadTemplate = tpl;
|
||||
SpreadZ = z;
|
||||
spread.DecalWidth = dwidth * ScaleX;
|
||||
spread.DecalLeft = tex->GetDisplayLeftOffset() * ScaleX;
|
||||
spread.DecalRight = spread.DecalWidth - spread.DecalLeft;
|
||||
spread.SpreadSource = this;
|
||||
spread.SpreadTemplate = tpl;
|
||||
spread.SpreadZ = z;
|
||||
|
||||
// Try spreading left first
|
||||
SpreadLeft (rorg - DecalLeft, v1, wall, ffloor);
|
||||
SpreadStack.Clear ();
|
||||
SpreadLeft (rorg - spread.DecalLeft, v1, wall, ffloor, &spread);
|
||||
spread.SpreadStack.Clear ();
|
||||
|
||||
// Then try spreading right
|
||||
SpreadRight (rorg + DecalRight, wall,
|
||||
Length (wall->linedef->Delta().X, wall->linedef->Delta().Y), ffloor);
|
||||
SpreadStack.Clear ();
|
||||
SpreadRight (rorg + spread.DecalRight, wall,
|
||||
Length (wall->linedef->Delta().X, wall->linedef->Delta().Y), ffloor, &spread);
|
||||
}
|
||||
|
||||
DBaseDecal *DBaseDecal::CloneSelf (const FDecalTemplate *tpl, double ix, double iy, double iz, side_t *wall, F3DFloor * ffloor) const
|
||||
|
@ -545,9 +548,9 @@ CUSTOM_CVAR (Int, cl_maxdecals, 1024, CVAR_ARCHIVE)
|
|||
}
|
||||
else
|
||||
{
|
||||
while (ImpactCount > self)
|
||||
while (level.ImpactDecalCount > self)
|
||||
{
|
||||
DThinker *thinker = DThinker::FirstThinker (STAT_AUTODECAL);
|
||||
DThinker *thinker = DThinker::FirstThinker(STAT_AUTODECAL);
|
||||
if (thinker != NULL)
|
||||
{
|
||||
thinker->Destroy();
|
||||
|
@ -559,23 +562,22 @@ CUSTOM_CVAR (Int, cl_maxdecals, 1024, CVAR_ARCHIVE)
|
|||
DImpactDecal::DImpactDecal ()
|
||||
: DBaseDecal (STAT_AUTODECAL, 0.)
|
||||
{
|
||||
ImpactCount++;
|
||||
}
|
||||
|
||||
DImpactDecal::DImpactDecal (double z)
|
||||
: DBaseDecal (STAT_AUTODECAL, z)
|
||||
{
|
||||
ImpactCount++;
|
||||
}
|
||||
|
||||
void DImpactDecal::CheckMax ()
|
||||
{
|
||||
if (ImpactCount >= cl_maxdecals)
|
||||
if (++level.ImpactDecalCount >= cl_maxdecals)
|
||||
{
|
||||
DThinker *thinker = DThinker::FirstThinker (STAT_AUTODECAL);
|
||||
if (thinker != NULL)
|
||||
{
|
||||
thinker->Destroy();
|
||||
level.ImpactDecalCount--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -610,7 +612,6 @@ DImpactDecal *DImpactDecal::StaticCreate (const FDecalTemplate *tpl, const DVect
|
|||
else lowercolor = color;
|
||||
StaticCreate (tpl_low, pos, wall, ffloor, lowercolor);
|
||||
}
|
||||
DImpactDecal::CheckMax();
|
||||
decal = Create<DImpactDecal>(pos.Z);
|
||||
if (decal == NULL)
|
||||
{
|
||||
|
@ -621,6 +622,7 @@ DImpactDecal *DImpactDecal::StaticCreate (const FDecalTemplate *tpl, const DVect
|
|||
{
|
||||
return NULL;
|
||||
}
|
||||
decal->CheckMax();
|
||||
|
||||
tpl->ApplyToDecal (decal, wall);
|
||||
if (color != 0)
|
||||
|
@ -646,12 +648,12 @@ DBaseDecal *DImpactDecal::CloneSelf (const FDecalTemplate *tpl, double ix, doubl
|
|||
return NULL;
|
||||
}
|
||||
|
||||
DImpactDecal::CheckMax();
|
||||
DImpactDecal *decal = Create<DImpactDecal>(iz);
|
||||
if (decal != NULL)
|
||||
{
|
||||
if (decal->StickToWall (wall, ix, iy, ffloor).isValid())
|
||||
{
|
||||
decal->CheckMax();
|
||||
tpl->ApplyToDecal (decal, wall);
|
||||
decal->AlphaColor = AlphaColor;
|
||||
decal->RenderFlags = (decal->RenderFlags & RF_DECALMASK) |
|
||||
|
@ -666,12 +668,6 @@ DBaseDecal *DImpactDecal::CloneSelf (const FDecalTemplate *tpl, double ix, doubl
|
|||
return decal;
|
||||
}
|
||||
|
||||
void DImpactDecal::OnDestroy ()
|
||||
{
|
||||
ImpactCount--;
|
||||
Super::OnDestroy();
|
||||
}
|
||||
|
||||
CCMD (countdecals)
|
||||
{
|
||||
Printf ("%d impact decals\n", ImpactCount);
|
||||
|
|
|
@ -63,7 +63,11 @@
|
|||
#include "g_levellocals.h"
|
||||
#include "a_dynlight.h"
|
||||
#include "actorinlines.h"
|
||||
#include "memarena.h"
|
||||
|
||||
static FMemArena DynLightArena(sizeof(FDynamicLight) * 200);
|
||||
static TArray<FDynamicLight*> FreeList;
|
||||
static FRandom randLight;
|
||||
|
||||
CUSTOM_CVAR (Bool, gl_lights, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
|
||||
{
|
||||
|
@ -71,8 +75,6 @@ CUSTOM_CVAR (Bool, gl_lights, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOIN
|
|||
else AActor::DeleteAllAttachedLights();
|
||||
}
|
||||
|
||||
CVAR (Bool, gl_attachedlights, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
|
@ -87,105 +89,142 @@ DEFINE_CLASS_PROPERTY(type, S, DynamicLight)
|
|||
|
||||
int style = MatchString(str, ltype_names);
|
||||
if (style < 0) I_Error("Unknown light type '%s'", str);
|
||||
defaults->lighttype = ltype_values[style];
|
||||
defaults->IntVar(NAME_lighttype) = ltype_values[style];
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Actor classes
|
||||
//
|
||||
// For flexibility all functionality has been packed into a single class
|
||||
// which is controlled by flags
|
||||
//
|
||||
//==========================================================================
|
||||
IMPLEMENT_CLASS(ADynamicLight, false, false)
|
||||
|
||||
DEFINE_FIELD(ADynamicLight, SpotInnerAngle)
|
||||
DEFINE_FIELD(ADynamicLight, SpotOuterAngle)
|
||||
|
||||
static FRandom randLight;
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Base class
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
void ADynamicLight::Serialize(FSerializer &arc)
|
||||
static FDynamicLight *GetLight()
|
||||
{
|
||||
Super::Serialize (arc);
|
||||
auto def = static_cast<ADynamicLight*>(GetDefault());
|
||||
arc("lightflags", lightflags, def->lightflags)
|
||||
("lighttype", lighttype, def->lighttype)
|
||||
("tickcount", m_tickCount, def->m_tickCount)
|
||||
("currentradius", m_currentRadius, def->m_currentRadius)
|
||||
("spotinnerangle", SpotInnerAngle, def->SpotInnerAngle)
|
||||
("spotouterangle", SpotOuterAngle, def->SpotOuterAngle);
|
||||
|
||||
if (lighttype == PulseLight)
|
||||
arc("lastupdate", m_lastUpdate, def->m_lastUpdate)
|
||||
("cycler", m_cycler, def->m_cycler);
|
||||
|
||||
// Remap the old flags.
|
||||
if (SaveVersion < 4552)
|
||||
FDynamicLight *ret;
|
||||
if (FreeList.Size())
|
||||
{
|
||||
lightflags = 0;
|
||||
if (flags4 & MF4_MISSILEEVENMORE) lightflags |= LF_SUBTRACTIVE;
|
||||
if (flags4 & MF4_MISSILEMORE) lightflags |= LF_ADDITIVE;
|
||||
if (flags4 & MF4_SEESDAGGERS) lightflags |= LF_DONTLIGHTSELF;
|
||||
if (flags4 & MF4_INCOMBAT) lightflags |= LF_ATTENUATE;
|
||||
if (flags4 & MF4_STANDSTILL) lightflags |= LF_NOSHADOWMAP;
|
||||
if (flags4 & MF4_EXTREMEDEATH) lightflags |= LF_DONTLIGHTACTORS;
|
||||
flags4 &= ~(MF4_SEESDAGGERS); // this flag is dangerous and must be cleared. The others do not matter.
|
||||
FreeList.Pop(ret);
|
||||
}
|
||||
else ret = (FDynamicLight*)DynLightArena.Alloc(sizeof(FDynamicLight));
|
||||
memset(ret, 0, sizeof(*ret));
|
||||
ret->next = level.lights;
|
||||
level.lights = ret;
|
||||
if (ret->next) ret->next->prev = ret;
|
||||
ret->visibletoplayer = true;
|
||||
ret->mShadowmapIndex = 1024;
|
||||
ret->Pos.X = -10000000; // not a valid coordinate.
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Attaches a dynamic light descriptor to a dynamic light actor.
|
||||
// Owned lights do not use this function.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void AttachLight(AActor *self)
|
||||
{
|
||||
auto light = GetLight();
|
||||
|
||||
light->pSpotInnerAngle = &self->AngleVar(NAME_SpotInnerAngle);
|
||||
light->pSpotOuterAngle = &self->AngleVar(NAME_SpotOuterAngle);
|
||||
light->pPitch = &self->Angles.Pitch;
|
||||
light->pLightFlags = (LightFlags*)&self->IntVar(NAME_lightflags);
|
||||
light->pArgs = self->args;
|
||||
light->specialf1 = DAngle(double(self->SpawnAngle)).Normalized360().Degrees;
|
||||
light->Sector = self->Sector;
|
||||
light->target = self;
|
||||
light->mShadowmapIndex = 1024;
|
||||
light->m_active = false;
|
||||
light->visibletoplayer = true;
|
||||
light->lighttype = (uint8_t)self->IntVar(NAME_lighttype);
|
||||
self->AttachedLights.Push(light);
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(ADynamicLight, AttachLight, AttachLight)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
AttachLight(self);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void ActivateLight(AActor *self)
|
||||
{
|
||||
for (auto l : self->AttachedLights) l->Activate();
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(ADynamicLight, ActivateLight, ActivateLight)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
ActivateLight(self);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void DeactivateLight(AActor *self)
|
||||
{
|
||||
for (auto l : self->AttachedLights) l->Deactivate();
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(ADynamicLight, DeactivateLight, DeactivateLight)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
DeactivateLight(self);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void SetOffset(AActor *self, double x, double y, double z)
|
||||
{
|
||||
for (auto l : self->AttachedLights)
|
||||
{
|
||||
l->SetOffset(DVector3(x, y, z));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ADynamicLight::PostSerialize()
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(ADynamicLight, SetOffset, SetOffset)
|
||||
{
|
||||
Super::PostSerialize();
|
||||
// The default constructor which is used for creating objects before deserialization will not set this variable.
|
||||
// It needs to be true for all placed lights.
|
||||
visibletoplayer = true;
|
||||
mShadowmapIndex = 1024;
|
||||
LinkLight();
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_FLOAT(x);
|
||||
PARAM_FLOAT(y);
|
||||
PARAM_FLOAT(z);
|
||||
SetOffset(self, x, y, z);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// [TS]
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
void ADynamicLight::BeginPlay()
|
||||
|
||||
void FDynamicLight::ReleaseLight()
|
||||
{
|
||||
//Super::BeginPlay();
|
||||
ChangeStatNum(STAT_DLIGHT);
|
||||
|
||||
specialf1 = DAngle(double(SpawnAngle)).Normalized360().Degrees;
|
||||
visibletoplayer = true;
|
||||
mShadowmapIndex = 1024;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// [TS]
|
||||
//
|
||||
//==========================================================================
|
||||
void ADynamicLight::PostBeginPlay()
|
||||
{
|
||||
Super::PostBeginPlay();
|
||||
|
||||
if (!(SpawnFlags & MTF_DORMANT))
|
||||
{
|
||||
Activate (nullptr);
|
||||
}
|
||||
|
||||
subsector = R_PointInSubsector(Pos());
|
||||
assert(prev != nullptr || this == level.lights);
|
||||
if (prev != nullptr) prev->next = next;
|
||||
else level.lights = next;
|
||||
if (next != nullptr) next->prev = prev;
|
||||
next = prev = nullptr;
|
||||
FreeList.Push(this);
|
||||
}
|
||||
|
||||
|
||||
|
@ -194,21 +233,19 @@ void ADynamicLight::PostBeginPlay()
|
|||
// [TS]
|
||||
//
|
||||
//==========================================================================
|
||||
void ADynamicLight::Activate(AActor *activator)
|
||||
void FDynamicLight::Activate()
|
||||
{
|
||||
//Super::Activate(activator);
|
||||
flags2&=~MF2_DORMANT;
|
||||
|
||||
m_currentRadius = float(args[LIGHT_INTENSITY]);
|
||||
m_active = true;
|
||||
m_currentRadius = float(GetIntensity());
|
||||
m_tickCount = 0;
|
||||
|
||||
if (lighttype == PulseLight)
|
||||
{
|
||||
float pulseTime = float(specialf1 / TICRATE);
|
||||
|
||||
|
||||
m_lastUpdate = level.maptime;
|
||||
if (!swapped) m_cycler.SetParams(float(args[LIGHT_SECONDARY_INTENSITY]), float(args[LIGHT_INTENSITY]), pulseTime);
|
||||
else m_cycler.SetParams(float(args[LIGHT_INTENSITY]), float(args[LIGHT_SECONDARY_INTENSITY]), pulseTime);
|
||||
if (!swapped) m_cycler.SetParams(float(GetSecondaryIntensity()), float(GetIntensity()), pulseTime);
|
||||
else m_cycler.SetParams(float(GetIntensity()), float(GetSecondaryIntensity()), pulseTime);
|
||||
m_cycler.ShouldCycle(true);
|
||||
m_cycler.SetCycleType(CYCLE_Sin);
|
||||
m_currentRadius = float(m_cycler.GetVal());
|
||||
|
@ -222,28 +259,27 @@ void ADynamicLight::Activate(AActor *activator)
|
|||
// [TS]
|
||||
//
|
||||
//==========================================================================
|
||||
void ADynamicLight::Deactivate(AActor *activator)
|
||||
void FDynamicLight::Tick()
|
||||
{
|
||||
//Super::Deactivate(activator);
|
||||
flags2|=MF2_DORMANT;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// [TS]
|
||||
//
|
||||
//==========================================================================
|
||||
void ADynamicLight::Tick()
|
||||
{
|
||||
if (IsOwned())
|
||||
if (!target)
|
||||
{
|
||||
if (!target || !target->state)
|
||||
// How did we get here? :?
|
||||
ReleaseLight();
|
||||
return;
|
||||
}
|
||||
|
||||
if (owned)
|
||||
{
|
||||
if (!target->state)
|
||||
{
|
||||
this->Destroy();
|
||||
Deactivate();
|
||||
return;
|
||||
}
|
||||
if (target->flags & MF_UNMORPHED)
|
||||
{
|
||||
m_active = false;
|
||||
return;
|
||||
}
|
||||
if (target->flags & MF_UNMORPHED) return;
|
||||
visibletoplayer = target->IsVisibleToPlayer(); // cache this value for the renderer to speed up calculations.
|
||||
}
|
||||
|
||||
|
@ -266,25 +302,23 @@ void ADynamicLight::Tick()
|
|||
|
||||
case FlickerLight:
|
||||
{
|
||||
int rnd = randLight();
|
||||
float pct = float(specialf1 / 360.f);
|
||||
|
||||
m_currentRadius = float(args[LIGHT_INTENSITY + (rnd >= pct * 255)]);
|
||||
int rnd = randLight(360);
|
||||
m_currentRadius = float((rnd < int(specialf1))? GetIntensity() : GetSecondaryIntensity());
|
||||
break;
|
||||
}
|
||||
|
||||
case RandomFlickerLight:
|
||||
{
|
||||
int flickerRange = args[LIGHT_SECONDARY_INTENSITY] - args[LIGHT_INTENSITY];
|
||||
int flickerRange = GetSecondaryIntensity() - GetIntensity();
|
||||
float amt = randLight() / 255.f;
|
||||
|
||||
if (m_tickCount > specialf1)
|
||||
{
|
||||
m_tickCount = 0;
|
||||
}
|
||||
if (m_tickCount++ == 0 || m_currentRadius > args[LIGHT_SECONDARY_INTENSITY])
|
||||
if (m_tickCount++ == 0 || m_currentRadius > GetSecondaryIntensity())
|
||||
{
|
||||
m_currentRadius = float(args[LIGHT_INTENSITY] + (amt * flickerRange));
|
||||
m_currentRadius = float(GetIntensity() + (amt * flickerRange));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -302,14 +336,14 @@ void ADynamicLight::Tick()
|
|||
|
||||
case RandomColorFlickerLight:
|
||||
{
|
||||
int flickerRange = args[LIGHT_SECONDARY_INTENSITY] - args[LIGHT_INTENSITY];
|
||||
int flickerRange = GetSecondaryIntensity() - GetIntensity();
|
||||
float amt = randLight() / 255.f;
|
||||
|
||||
m_tickCount++;
|
||||
|
||||
if (m_tickCount > specialf1)
|
||||
{
|
||||
m_currentRadius = args[LIGHT_INTENSITY] + (amt * flickerRange);
|
||||
m_currentRadius = GetIntensity() + (amt * flickerRange);
|
||||
m_tickCount = 0;
|
||||
}
|
||||
break;
|
||||
|
@ -319,7 +353,7 @@ void ADynamicLight::Tick()
|
|||
case SectorLight:
|
||||
{
|
||||
float intensity;
|
||||
float scale = args[LIGHT_SCALE] / 8.f;
|
||||
float scale = GetIntensity() / 8.f;
|
||||
|
||||
if (scale == 0.f) scale = 1.f;
|
||||
|
||||
|
@ -331,7 +365,7 @@ void ADynamicLight::Tick()
|
|||
}
|
||||
|
||||
case PointLight:
|
||||
m_currentRadius = float(args[LIGHT_INTENSITY]);
|
||||
m_currentRadius = float(GetIntensity());
|
||||
break;
|
||||
}
|
||||
if (m_currentRadius <= 0) m_currentRadius = 1;
|
||||
|
@ -346,45 +380,37 @@ void ADynamicLight::Tick()
|
|||
//
|
||||
//
|
||||
//==========================================================================
|
||||
void ADynamicLight::UpdateLocation()
|
||||
void FDynamicLight::UpdateLocation()
|
||||
{
|
||||
double oldx= X();
|
||||
double oldy= Y();
|
||||
double oldradius= radius;
|
||||
float intensity;
|
||||
float oldradius = radius;
|
||||
|
||||
if (IsActive())
|
||||
{
|
||||
if (target)
|
||||
{
|
||||
DAngle angle = target->Angles.Yaw;
|
||||
double s = angle.Sin();
|
||||
double c = angle.Cos();
|
||||
AActor *target = this->target; // perform the read barrier only once.
|
||||
|
||||
DVector3 pos = target->Vec3Offset(m_off.X * c + m_off.Y * s, m_off.X * s - m_off.Y * c, m_off.Z + target->GetBobOffset());
|
||||
SetXYZ(pos); // attached lights do not need to go into the regular blockmap
|
||||
Prev = target->Pos();
|
||||
subsector = R_PointInSubsector(Prev);
|
||||
Sector = subsector->sector;
|
||||
// Offset is calculated in relation to the owning actor.
|
||||
DAngle angle = target->Angles.Yaw;
|
||||
double s = angle.Sin();
|
||||
double c = angle.Cos();
|
||||
|
||||
// Some z-coordinate fudging to prevent the light from getting too close to the floor or ceiling planes. With proper attenuation this would render them invisible.
|
||||
// A distance of 5 is needed so that the light's effect doesn't become too small.
|
||||
if (Z() < target->floorz + 5.) SetZ(target->floorz + 5.);
|
||||
else if (Z() > target->ceilingz - 5.) SetZ(target->ceilingz - 5.);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Z() < floorz + 5.) SetZ(floorz + 5.);
|
||||
else if (Z() > ceilingz - 5.) SetZ(ceilingz - 5.);
|
||||
}
|
||||
Pos = target->Vec3Offset(m_off.X * c + m_off.Y * s, m_off.X * s - m_off.Y * c, m_off.Z + target->GetBobOffset());
|
||||
Sector = target->subsector->sector; // Get the render sector. target->Sector is the sector according to play logic.
|
||||
|
||||
// Some z-coordinate fudging to prevent the light from getting too close to the floor or ceiling planes. With proper attenuation this would render them invisible.
|
||||
// A distance of 5 is needed so that the light's effect doesn't become too small.
|
||||
if (Z() < target->floorz + 5.) Pos.Z = target->floorz + 5.;
|
||||
else if (Z() > target->ceilingz - 5.) Pos.Z = target->ceilingz - 5.;
|
||||
|
||||
// The radius being used here is always the maximum possible with the
|
||||
// current settings. This avoids constant relinking of flickering lights
|
||||
|
||||
float intensity;
|
||||
|
||||
if (lighttype == FlickerLight || lighttype == RandomFlickerLight || lighttype == PulseLight)
|
||||
{
|
||||
intensity = float(MAX(args[LIGHT_INTENSITY], args[LIGHT_SECONDARY_INTENSITY]));
|
||||
intensity = float(MAX(GetIntensity(), GetSecondaryIntensity()));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -401,60 +427,6 @@ void ADynamicLight::UpdateLocation()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void ADynamicLight::SetOrigin(double x, double y, double z, bool moving)
|
||||
{
|
||||
Super::SetOrigin(x, y, z, moving);
|
||||
LinkLight();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void ADynamicLight::SetOffset(const DVector3 &pos)
|
||||
{
|
||||
m_off = pos;
|
||||
UpdateLocation();
|
||||
}
|
||||
|
||||
static void SetOffset(ADynamicLight *self, const DVector3 &pos)
|
||||
{
|
||||
self->SetOffset(pos);
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(ADynamicLight, SetOffset, SetOffset)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(ADynamicLight)
|
||||
PARAM_FLOAT(x)
|
||||
PARAM_FLOAT(y)
|
||||
PARAM_FLOAT(z)
|
||||
self->SetOffset(DVector3(x, y, z));
|
||||
return 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// The target pointer in dynamic lights should never be substituted unless
|
||||
// notOld is nullptr (which indicates that the object was destroyed by force.)
|
||||
//
|
||||
//==========================================================================
|
||||
size_t ADynamicLight::PointerSubstitution (DObject *old, DObject *notOld)
|
||||
{
|
||||
AActor *saved_target = target;
|
||||
size_t ret = Super::PointerSubstitution(old, notOld);
|
||||
if (notOld != nullptr) target = saved_target;
|
||||
return ret;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// These have been copied from the secnode code and modified for the light links
|
||||
|
@ -466,7 +438,7 @@ size_t ADynamicLight::PointerSubstitution (DObject *old, DObject *notOld)
|
|||
//
|
||||
//=============================================================================
|
||||
|
||||
FLightNode * AddLightNode(FLightNode ** thread, void * linkto, ADynamicLight * light, FLightNode *& nextnode)
|
||||
FLightNode * AddLightNode(FLightNode ** thread, void * linkto, FDynamicLight * light, FLightNode *& nextnode)
|
||||
{
|
||||
FLightNode * node;
|
||||
|
||||
|
@ -541,7 +513,7 @@ static FLightNode * DeleteLightNode(FLightNode * node)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
double ADynamicLight::DistToSeg(const DVector3 &pos, vertex_t *start, vertex_t *end)
|
||||
double FDynamicLight::DistToSeg(const DVector3 &pos, vertex_t *start, vertex_t *end)
|
||||
{
|
||||
double u, px, py;
|
||||
|
||||
|
@ -576,7 +548,7 @@ struct LightLinkEntry
|
|||
};
|
||||
static TArray<LightLinkEntry> collected_ss;
|
||||
|
||||
void ADynamicLight::CollectWithinRadius(const DVector3 &opos, FSection *section, float radius)
|
||||
void FDynamicLight::CollectWithinRadius(const DVector3 &opos, FSection *section, float radius)
|
||||
{
|
||||
if (!section) return;
|
||||
collected_ss.Clear();
|
||||
|
@ -621,7 +593,7 @@ void ADynamicLight::CollectWithinRadius(const DVector3 &opos, FSection *section,
|
|||
if (othersect->validcount != ::validcount)
|
||||
{
|
||||
othersect->validcount = ::validcount;
|
||||
collected_ss.Push({ othersect, PosRelative(other) });
|
||||
collected_ss.Push({ othersect, PosRelative(other->frontsector->PortalGroup) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -672,7 +644,7 @@ void ADynamicLight::CollectWithinRadius(const DVector3 &opos, FSection *section,
|
|||
if (othersect->validcount != dl_validcount)
|
||||
{
|
||||
othersect->validcount = dl_validcount;
|
||||
collected_ss.Push({ othersect, PosRelative(othersub->sector) });
|
||||
collected_ss.Push({ othersect, PosRelative(othersub->sector->PortalGroup) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -687,12 +659,12 @@ void ADynamicLight::CollectWithinRadius(const DVector3 &opos, FSection *section,
|
|||
if (othersect->validcount != dl_validcount)
|
||||
{
|
||||
othersect->validcount = dl_validcount;
|
||||
collected_ss.Push({ othersect, PosRelative(othersub->sector) });
|
||||
collected_ss.Push({ othersect, PosRelative(othersub->sector->PortalGroup) });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
shadowmapped = hitonesidedback && !(lightflags & LF_NOSHADOWMAP);
|
||||
shadowmapped = hitonesidedback && !DontShadowmap();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -701,7 +673,7 @@ void ADynamicLight::CollectWithinRadius(const DVector3 &opos, FSection *section,
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void ADynamicLight::LinkLight()
|
||||
void FDynamicLight::LinkLight()
|
||||
{
|
||||
// mark the old light nodes
|
||||
FLightNode * node;
|
||||
|
@ -722,11 +694,11 @@ void ADynamicLight::LinkLight()
|
|||
if (radius>0)
|
||||
{
|
||||
// passing in radius*radius allows us to do a distance check without any calls to sqrt
|
||||
FSection *sect = R_PointInSubsector(Pos())->section;
|
||||
FSection *sect = R_PointInSubsector(Pos)->section;
|
||||
|
||||
dl_validcount++;
|
||||
::validcount++;
|
||||
CollectWithinRadius(Pos(), sect, float(radius*radius));
|
||||
CollectWithinRadius(Pos, sect, float(radius*radius));
|
||||
|
||||
}
|
||||
|
||||
|
@ -762,32 +734,13 @@ void ADynamicLight::LinkLight()
|
|||
// Deletes the link lists
|
||||
//
|
||||
//==========================================================================
|
||||
void ADynamicLight::UnlinkLight ()
|
||||
void FDynamicLight::UnlinkLight ()
|
||||
{
|
||||
if (owned && target != nullptr)
|
||||
{
|
||||
// Delete reference in owning actor
|
||||
for(int c=target->AttachedLights.Size()-1; c>=0; c--)
|
||||
{
|
||||
if (target->AttachedLights[c] == this)
|
||||
{
|
||||
target->AttachedLights.Delete(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (touching_sides) touching_sides = DeleteLightNode(touching_sides);
|
||||
while (touching_sector) touching_sector = DeleteLightNode(touching_sector);
|
||||
shadowmapped = false;
|
||||
}
|
||||
|
||||
void ADynamicLight::OnDestroy()
|
||||
{
|
||||
UnlinkLight();
|
||||
Super::OnDestroy();
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
|
@ -796,23 +749,19 @@ void ADynamicLight::OnDestroy()
|
|||
|
||||
void AActor::AttachLight(unsigned int count, const FLightDefaults *lightdef)
|
||||
{
|
||||
ADynamicLight *light;
|
||||
FDynamicLight *light;
|
||||
|
||||
if (count < AttachedLights.Size())
|
||||
{
|
||||
light = barrier_cast<ADynamicLight*>(AttachedLights[count]);
|
||||
light = AttachedLights[count];
|
||||
assert(light != nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
light = Spawn<ADynamicLight>(Pos(), NO_REPLACE);
|
||||
light->target = this;
|
||||
light->owned = true;
|
||||
light->ObjectFlags |= OF_Transient;
|
||||
//light->lightflags |= LF_ATTENUATE;
|
||||
light = GetLight();
|
||||
light->SetActor(this, true);
|
||||
AttachedLights.Push(light);
|
||||
}
|
||||
light->flags2&=~MF2_DORMANT;
|
||||
lightdef->ApplyProperties(light);
|
||||
}
|
||||
|
||||
|
@ -831,11 +780,8 @@ void AActor::SetDynamicLights()
|
|||
if (state == nullptr) return;
|
||||
if (LightAssociations.Size() > 0)
|
||||
{
|
||||
ADynamicLight *lights, *tmpLight;
|
||||
unsigned int i;
|
||||
|
||||
lights = tmpLight = nullptr;
|
||||
|
||||
for (i = 0; i < LightAssociations.Size(); i++)
|
||||
{
|
||||
if (LightAssociations[i]->Sprite() == sprite &&
|
||||
|
@ -858,24 +804,24 @@ void AActor::SetDynamicLights()
|
|||
|
||||
for(;count<AttachedLights.Size();count++)
|
||||
{
|
||||
AttachedLights[count]->flags2 |= MF2_DORMANT;
|
||||
memset(AttachedLights[count]->args, 0, 3*sizeof(args[0]));
|
||||
AttachedLights[count]->Deactivate();
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Needed for garbage collection
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
size_t AActor::PropagateMark()
|
||||
void AActor::DeleteAttachedLights()
|
||||
{
|
||||
for (unsigned i = 0; i<AttachedLights.Size(); i++)
|
||||
for (auto l : AttachedLights)
|
||||
{
|
||||
GC::Mark(AttachedLights[i]);
|
||||
l->UnlinkLight();
|
||||
l->ReleaseLight();
|
||||
}
|
||||
return Super::PropagateMark();
|
||||
AttachedLights.Clear();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -888,21 +834,10 @@ void AActor::DeleteAllAttachedLights()
|
|||
{
|
||||
TThinkerIterator<AActor> it;
|
||||
AActor * a;
|
||||
ADynamicLight * l;
|
||||
|
||||
while ((a=it.Next()))
|
||||
{
|
||||
a->AttachedLights.Clear();
|
||||
}
|
||||
|
||||
TThinkerIterator<ADynamicLight> it2;
|
||||
|
||||
l=it2.Next();
|
||||
while (l)
|
||||
{
|
||||
ADynamicLight * ll = it2.Next();
|
||||
if (l->owned) l->Destroy();
|
||||
l=ll;
|
||||
a->DeleteAttachedLights();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -919,7 +854,18 @@ void AActor::RecreateAllAttachedLights()
|
|||
|
||||
while ((a=it.Next()))
|
||||
{
|
||||
a->SetDynamicLights();
|
||||
if (!a->IsKindOf(NAME_DynamicLight))
|
||||
{
|
||||
a->SetDynamicLights();
|
||||
}
|
||||
else if (a->AttachedLights.Size() == 0)
|
||||
{
|
||||
::AttachLight(a);
|
||||
if (!(a->flags2 & MF2_DORMANT))
|
||||
{
|
||||
::ActivateLight(a);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -934,17 +880,16 @@ CCMD(listlights)
|
|||
int walls, sectors;
|
||||
int allwalls=0, allsectors=0, allsubsecs = 0;
|
||||
int i=0, shadowcount = 0;
|
||||
ADynamicLight * dl;
|
||||
TThinkerIterator<ADynamicLight> it;
|
||||
FDynamicLight * dl;
|
||||
|
||||
while ((dl=it.Next()))
|
||||
for (dl = level.lights; dl; dl = dl->next)
|
||||
{
|
||||
walls=0;
|
||||
sectors=0;
|
||||
Printf("%s at (%f, %f, %f), color = 0x%02x%02x%02x, radius = %f %s %s",
|
||||
dl->target? dl->target->GetClass()->TypeName.GetChars() : dl->GetClass()->TypeName.GetChars(),
|
||||
dl->X(), dl->Y(), dl->Z(), dl->args[LIGHT_RED],
|
||||
dl->args[LIGHT_GREEN], dl->args[LIGHT_BLUE], dl->radius, (dl->lightflags & LF_ATTENUATE)? "attenuated" : "", dl->shadowmapped? "shadowmapped" : "");
|
||||
dl->target->GetClass()->TypeName.GetChars(),
|
||||
dl->X(), dl->Y(), dl->Z(), dl->GetRed(), dl->GetGreen(), dl->GetBlue(),
|
||||
dl->radius, dl->IsAttenuated()? "attenuated" : "", dl->shadowmapped? "shadowmapped" : "");
|
||||
i++;
|
||||
shadowcount += dl->shadowmapped;
|
||||
|
||||
|
@ -981,4 +926,3 @@ CCMD(listlights)
|
|||
Printf("%i dynamic lights, %d shadowmapped, %d walls, %d sectors\n\n\n", i, shadowcount, allwalls, allsectors);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -2,15 +2,14 @@
|
|||
#include "c_cvars.h"
|
||||
#include "actor.h"
|
||||
#include "cycler.h"
|
||||
#include "g_levellocals.h"
|
||||
|
||||
EXTERN_CVAR(Bool, r_dynlights)
|
||||
EXTERN_CVAR(Bool, gl_lights)
|
||||
EXTERN_CVAR(Bool, gl_attachedlights)
|
||||
|
||||
struct side_t;
|
||||
struct seg_t;
|
||||
|
||||
class ADynamicLight;
|
||||
class FSerializer;
|
||||
struct FSectionLine;
|
||||
|
||||
|
@ -34,7 +33,6 @@ enum
|
|||
LIGHT_BLUE = 2,
|
||||
LIGHT_INTENSITY = 3,
|
||||
LIGHT_SECONDARY_INTENSITY = 4,
|
||||
LIGHT_SCALE = 3,
|
||||
};
|
||||
|
||||
enum LightFlag
|
||||
|
@ -48,6 +46,9 @@ enum LightFlag
|
|||
LF_SPOT = 64
|
||||
};
|
||||
|
||||
typedef TFlags<LightFlag> LightFlags;
|
||||
DEFINE_TFLAGS_OPERATORS(LightFlags)
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Light definitions
|
||||
|
@ -58,22 +59,23 @@ class FLightDefaults
|
|||
public:
|
||||
FLightDefaults(FName name, ELightType type);
|
||||
|
||||
void ApplyProperties(ADynamicLight * light) const;
|
||||
void ApplyProperties(FDynamicLight * light) const;
|
||||
FName GetName() const { return m_Name; }
|
||||
void SetParameter(double p) { m_Param = p; }
|
||||
void SetArg(int arg, int val) { m_Args[arg] = val; }
|
||||
int GetArg(int arg) { return m_Args[arg]; }
|
||||
uint8_t GetAttenuate() const { return m_attenuate; }
|
||||
void SetOffset(float* ft) { m_Pos.X = ft[0]; m_Pos.Z = ft[1]; m_Pos.Y = ft[2]; }
|
||||
void SetSubtractive(bool subtract) { m_subtractive = subtract; }
|
||||
void SetAdditive(bool add) { m_additive = add; }
|
||||
void SetDontLightSelf(bool add) { m_dontlightself = add; }
|
||||
void SetAttenuate(bool on) { m_attenuate = on; }
|
||||
void SetHalo(bool halo) { m_halo = halo; }
|
||||
void SetDontLightActors(bool on) { m_dontlightactors = on; }
|
||||
void SetSpot(bool spot) { m_spot = spot; }
|
||||
void SetSubtractive(bool subtract) { if (subtract) m_lightFlags |= LF_SUBTRACTIVE; else m_lightFlags &= ~LF_SUBTRACTIVE; }
|
||||
void SetAdditive(bool add) { if (add) m_lightFlags |= LF_ADDITIVE; else m_lightFlags &= ~LF_ADDITIVE; }
|
||||
void SetDontLightSelf(bool add) { if (add) m_lightFlags |= LF_DONTLIGHTSELF; else m_lightFlags &= ~LF_DONTLIGHTSELF; }
|
||||
void SetAttenuate(bool on) { m_attenuate = on; if (on) m_lightFlags |= LF_ATTENUATE; else m_lightFlags &= ~LF_ATTENUATE; }
|
||||
void SetDontLightActors(bool on) { if (on) m_lightFlags |= LF_DONTLIGHTACTORS; else m_lightFlags &= ~LF_DONTLIGHTACTORS; }
|
||||
void SetNoShadowmap(bool on) { if (on) m_lightFlags |= LF_NOSHADOWMAP; else m_lightFlags &= ~LF_NOSHADOWMAP; }
|
||||
void SetSpot(bool spot) { if (spot) m_lightFlags |= LF_SPOT; else m_lightFlags &= ~LF_SPOT; }
|
||||
void SetSpotInnerAngle(double angle) { m_spotInnerAngle = angle; }
|
||||
void SetSpotOuterAngle(double angle) { m_spotOuterAngle = angle; }
|
||||
static void SetAttenuationForLevel();
|
||||
|
||||
void OrderIntensities()
|
||||
{
|
||||
|
@ -91,15 +93,13 @@ protected:
|
|||
DVector3 m_Pos = { 0,0,0 };
|
||||
ELightType m_type;
|
||||
int8_t m_attenuate = -1;
|
||||
bool m_subtractive = false;
|
||||
bool m_additive = false;
|
||||
bool m_halo = false;
|
||||
bool m_dontlightself = false;
|
||||
bool m_dontlightactors = false;
|
||||
LightFlags m_lightFlags = 0;
|
||||
bool m_swapped = false;
|
||||
bool m_spot = false;
|
||||
double m_spotInnerAngle = 10.0;
|
||||
double m_spotOuterAngle = 25.0;
|
||||
bool m_explicitPitch = false;
|
||||
DAngle m_spotInnerAngle = 10.0;
|
||||
DAngle m_spotOuterAngle = 25.0;
|
||||
DAngle m_pitch = 0.0;
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
|
@ -148,18 +148,13 @@ protected:
|
|||
};
|
||||
|
||||
|
||||
|
||||
typedef TFlags<LightFlag> LightFlags;
|
||||
DEFINE_TFLAGS_OPERATORS(LightFlags)
|
||||
|
||||
|
||||
struct FLightNode
|
||||
{
|
||||
FLightNode ** prevTarget;
|
||||
FLightNode * nextTarget;
|
||||
FLightNode ** prevLight;
|
||||
FLightNode * nextLight;
|
||||
ADynamicLight * lightsource;
|
||||
FDynamicLight * lightsource;
|
||||
union
|
||||
{
|
||||
side_t * targLine;
|
||||
|
@ -168,72 +163,89 @@ struct FLightNode
|
|||
};
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Base class
|
||||
//
|
||||
// [CO] I merged everything together in this one class so that I don't have
|
||||
// to create and re-create an excessive amount of objects
|
||||
//
|
||||
|
||||
class ADynamicLight : public AActor
|
||||
struct FDynamicLight
|
||||
{
|
||||
friend class FLightDefaults;
|
||||
DECLARE_CLASS(ADynamicLight, AActor)
|
||||
public:
|
||||
virtual void Tick();
|
||||
void Serialize(FSerializer &arc);
|
||||
void PostSerialize();
|
||||
uint8_t GetRed() const { return args[LIGHT_RED]; }
|
||||
uint8_t GetGreen() const { return args[LIGHT_GREEN]; }
|
||||
uint8_t GetBlue() const { return args[LIGHT_BLUE]; }
|
||||
|
||||
inline DVector3 PosRelative(int portalgroup) const
|
||||
{
|
||||
return Pos + level.Displacements.getOffset(Sector->PortalGroup, portalgroup);
|
||||
}
|
||||
|
||||
bool ShouldLightActor(AActor *check)
|
||||
{
|
||||
return visibletoplayer && IsActive() && (!((*pLightFlags) & LF_DONTLIGHTSELF) || target != check) && !((*pLightFlags) & LF_DONTLIGHTACTORS);
|
||||
}
|
||||
|
||||
void SetOffset(const DVector3 &pos)
|
||||
{
|
||||
m_off = pos;
|
||||
}
|
||||
|
||||
|
||||
bool IsActive() const { return m_active; }
|
||||
float GetRadius() const { return (IsActive() ? m_currentRadius * 2.f : 0.f); }
|
||||
int GetRed() const { return pArgs[LIGHT_RED]; }
|
||||
int GetGreen() const { return pArgs[LIGHT_GREEN]; }
|
||||
int GetBlue() const { return pArgs[LIGHT_BLUE]; }
|
||||
int GetIntensity() const { return pArgs[LIGHT_INTENSITY]; }
|
||||
int GetSecondaryIntensity() const { return pArgs[LIGHT_SECONDARY_INTENSITY]; }
|
||||
|
||||
bool IsSubtractive() const { return !!((*pLightFlags) & LF_SUBTRACTIVE); }
|
||||
bool IsAdditive() const { return !!((*pLightFlags) & LF_ADDITIVE); }
|
||||
bool IsSpot() const { return !!((*pLightFlags) & LF_SPOT); }
|
||||
bool IsAttenuated() const { return !!((*pLightFlags) & LF_ATTENUATE); }
|
||||
bool DontShadowmap() const { return !!((*pLightFlags) & LF_NOSHADOWMAP); }
|
||||
bool DontLightSelf() const { return !!((*pLightFlags) & (LF_DONTLIGHTSELF|LF_DONTLIGHTACTORS)); } // dontlightactors implies dontlightself.
|
||||
bool DontLightActors() const { return !!((*pLightFlags) & LF_DONTLIGHTACTORS); }
|
||||
void Deactivate() { m_active = false; }
|
||||
void Activate();
|
||||
|
||||
void SetActor(AActor *ac, bool isowned) { target = ac; owned = isowned; }
|
||||
double X() const { return Pos.X; }
|
||||
double Y() const { return Pos.Y; }
|
||||
double Z() const { return Pos.Z; }
|
||||
|
||||
void Tick();
|
||||
void UpdateLocation();
|
||||
void LinkLight();
|
||||
void UnlinkLight();
|
||||
size_t PointerSubstitution(DObject *old, DObject *notOld);
|
||||
|
||||
void BeginPlay();
|
||||
void SetOrigin(double x, double y, double z, bool moving = false);
|
||||
void PostBeginPlay();
|
||||
void OnDestroy() override;
|
||||
void Activate(AActor *activator);
|
||||
void Deactivate(AActor *activator);
|
||||
void SetOffset(const DVector3 &pos);
|
||||
void UpdateLocation();
|
||||
bool IsOwned() const { return owned; }
|
||||
bool IsActive() const { return !(flags2&MF2_DORMANT); }
|
||||
bool IsSubtractive() { return !!(lightflags & LF_SUBTRACTIVE); }
|
||||
bool IsAdditive() { return !!(lightflags & LF_ADDITIVE); }
|
||||
bool IsSpot() { return !!(lightflags & LF_SPOT); }
|
||||
FState *targetState;
|
||||
FLightNode * touching_sides;
|
||||
FLightNode * touching_sector;
|
||||
void ReleaseLight();
|
||||
|
||||
private:
|
||||
double DistToSeg(const DVector3 &pos, vertex_t *start, vertex_t *end);
|
||||
void CollectWithinRadius(const DVector3 &pos, FSection *section, float radius);
|
||||
|
||||
protected:
|
||||
DVector3 m_off;
|
||||
float m_currentRadius;
|
||||
unsigned int m_lastUpdate;
|
||||
FCycler m_cycler;
|
||||
subsector_t * subsector;
|
||||
|
||||
public:
|
||||
FCycler m_cycler;
|
||||
DVector3 Pos;
|
||||
DVector3 m_off;
|
||||
|
||||
// This date can either come from the owning actor or from a light definition
|
||||
// To avoid having to copy these around every tic, these are pointers to the source data.
|
||||
const DAngle *pSpotInnerAngle;
|
||||
const DAngle *pSpotOuterAngle;
|
||||
const DAngle *pPitch; // This is to handle pitch overrides through GLDEFS, it can either point to the target's pitch or the light definition.
|
||||
const int *pArgs;
|
||||
const LightFlags *pLightFlags;
|
||||
|
||||
double specialf1;
|
||||
FDynamicLight *next, *prev;
|
||||
sector_t *Sector;
|
||||
TObjPtr<AActor *> target;
|
||||
FLightNode * touching_sides;
|
||||
FLightNode * touching_sector;
|
||||
float radius; // The maximum size the light can be with its current settings.
|
||||
float m_currentRadius; // The current light size.
|
||||
int m_tickCount;
|
||||
int m_lastUpdate;
|
||||
int mShadowmapIndex;
|
||||
bool m_active;
|
||||
bool visibletoplayer;
|
||||
bool shadowmapped;
|
||||
uint8_t lighttype;
|
||||
bool owned;
|
||||
bool halo;
|
||||
uint8_t color2[3];
|
||||
bool visibletoplayer;
|
||||
bool swapped;
|
||||
bool shadowmapped;
|
||||
int bufferindex;
|
||||
LightFlags lightflags;
|
||||
DAngle SpotInnerAngle;
|
||||
DAngle SpotOuterAngle;
|
||||
|
||||
int mShadowmapIndex;
|
||||
bool explicitpitch;
|
||||
|
||||
};
|
||||
|
|
|
@ -43,14 +43,10 @@ IMPLEMENT_POINTERS_START(DFlashFader)
|
|||
IMPLEMENT_POINTER(ForWho)
|
||||
IMPLEMENT_POINTERS_END
|
||||
|
||||
DFlashFader::DFlashFader ()
|
||||
{
|
||||
}
|
||||
|
||||
DFlashFader::DFlashFader (float r1, float g1, float b1, float a1,
|
||||
float r2, float g2, float b2, float a2,
|
||||
float time, AActor *who, bool terminate)
|
||||
: TotalTics ((int)(time*TICRATE)), StartTic (level.time), ForWho (who)
|
||||
: TotalTics ((int)(time*TICRATE)), RemainingTics(TotalTics), ForWho (who)
|
||||
{
|
||||
Blends[0][0]=r1; Blends[0][1]=g1; Blends[0][2]=b1; Blends[0][3]=a1;
|
||||
Blends[1][0]=r2; Blends[1][1]=g2; Blends[1][2]=b2; Blends[1][3]=a2;
|
||||
|
@ -68,7 +64,7 @@ void DFlashFader::Serialize(FSerializer &arc)
|
|||
{
|
||||
Super::Serialize (arc);
|
||||
arc("totaltics", TotalTics)
|
||||
("starttic", StartTic)
|
||||
("remainingtics", RemainingTics)
|
||||
("forwho", ForWho)
|
||||
.Array("blends", Blends[0], 8);
|
||||
}
|
||||
|
@ -80,13 +76,13 @@ void DFlashFader::Tick ()
|
|||
Destroy ();
|
||||
return;
|
||||
}
|
||||
if (level.time >= StartTic+TotalTics)
|
||||
if (--RemainingTics <= 0)
|
||||
{
|
||||
SetBlend (1.f);
|
||||
Destroy ();
|
||||
return;
|
||||
}
|
||||
SetBlend ((float)(level.time - StartTic) / (float)TotalTics);
|
||||
SetBlend (1.f - (float)RemainingTics / (float)TotalTics);
|
||||
}
|
||||
|
||||
void DFlashFader::SetBlend (float time)
|
||||
|
@ -105,6 +101,6 @@ void DFlashFader::SetBlend (float time)
|
|||
|
||||
void DFlashFader::Cancel ()
|
||||
{
|
||||
TotalTics = level.time - StartTic;
|
||||
RemainingTics = 0;
|
||||
Blends[1][3] = 0.f;
|
||||
}
|
||||
|
|
|
@ -157,7 +157,7 @@ void DLightningThinker::LightningFlash ()
|
|||
// [ZZ] just in case
|
||||
E_WorldLightning();
|
||||
// start LIGHTNING scripts
|
||||
FBehavior::StaticStartTypedScripts (SCRIPT_Lightning, NULL, false); // [RH] Run lightning scripts
|
||||
level.Behaviors.StartTypedScripts (SCRIPT_Lightning, NULL, false); // [RH] Run lightning scripts
|
||||
|
||||
// Calculate the next lighting flash
|
||||
if (!NextLightningFlash)
|
||||
|
|
|
@ -19,23 +19,9 @@
|
|||
//
|
||||
|
||||
#include "info.h"
|
||||
#include "a_pickups.h"
|
||||
#include "p_local.h"
|
||||
#include "gi.h"
|
||||
#include "a_sharedglobal.h"
|
||||
#include "sbar.h"
|
||||
#include "a_morph.h"
|
||||
#include "doomstat.h"
|
||||
#include "serializer.h"
|
||||
#include "p_enemy.h"
|
||||
#include "d_player.h"
|
||||
#include "r_data/sprites.h"
|
||||
#include "g_levellocals.h"
|
||||
#include "actor.h"
|
||||
#include "vm.h"
|
||||
|
||||
static FRandom pr_morphmonst ("MorphMonster");
|
||||
|
||||
|
||||
bool P_MorphActor(AActor *activator, AActor *victim, PClassActor *ptype, PClassActor *mtype, int duration, int style, PClassActor *enter_flash, PClassActor *exit_flash)
|
||||
{
|
||||
IFVIRTUALPTR(victim, AActor, Morph)
|
||||
|
|
|
@ -9,6 +9,7 @@ struct vertex_t;
|
|||
struct side_t;
|
||||
struct F3DFloor;
|
||||
class DBaseDecal;
|
||||
struct SpreadInfo;
|
||||
|
||||
class DBaseDecal *ShootDecal(const FDecalTemplate *tpl, AActor *basisactor, sector_t *sec, double x, double y, double z, DAngle angle, double tracedist, bool permanent);
|
||||
void SprayDecal(AActor *shooter, const char *name,double distance = 172.);
|
||||
|
@ -52,8 +53,8 @@ protected:
|
|||
void CalcFracPos(side_t *wall, double x, double y);
|
||||
void Remove ();
|
||||
|
||||
static void SpreadLeft (double r, vertex_t *v1, side_t *feelwall, F3DFloor *ffloor);
|
||||
static void SpreadRight (double r, side_t *feelwall, double wallsize, F3DFloor *ffloor);
|
||||
static void SpreadLeft (double r, vertex_t *v1, side_t *feelwall, F3DFloor *ffloor, SpreadInfo *spread);
|
||||
static void SpreadRight (double r, side_t *feelwall, double wallsize, F3DFloor *ffloor, SpreadInfo *spread);
|
||||
};
|
||||
|
||||
class DImpactDecal : public DBaseDecal
|
||||
|
@ -67,11 +68,10 @@ public:
|
|||
static DImpactDecal *StaticCreate(const FDecalTemplate *tpl, const DVector3 &pos, side_t *wall, F3DFloor * ffloor, PalEntry color = 0);
|
||||
|
||||
void BeginPlay ();
|
||||
void OnDestroy() override;
|
||||
|
||||
protected:
|
||||
DBaseDecal *CloneSelf(const FDecalTemplate *tpl, double x, double y, double z, side_t *wall, F3DFloor * ffloor) const;
|
||||
static void CheckMax ();
|
||||
void CheckMax ();
|
||||
|
||||
private:
|
||||
DImpactDecal();
|
||||
|
@ -95,11 +95,11 @@ public:
|
|||
protected:
|
||||
float Blends[2][4];
|
||||
int TotalTics;
|
||||
int StartTic;
|
||||
int RemainingTics;
|
||||
TObjPtr<AActor*> ForWho;
|
||||
bool Terminate;
|
||||
void SetBlend (float time);
|
||||
DFlashFader ();
|
||||
DFlashFader() = default;
|
||||
};
|
||||
|
||||
enum
|
||||
|
|
|
@ -42,7 +42,6 @@
|
|||
static FRandom pr_spot ("SpecialSpot");
|
||||
|
||||
IMPLEMENT_CLASS(DSpotState, false, false)
|
||||
TObjPtr<DSpotState*> DSpotState::SpotState;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
|
@ -198,16 +197,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FSpotList &list, FSpot
|
|||
//----------------------------------------------------------------------------
|
||||
|
||||
DSpotState::DSpotState ()
|
||||
: DThinker (STAT_INFO)
|
||||
{
|
||||
if (SpotState)
|
||||
{
|
||||
I_Error ("Only one SpotState is allowed to exist at a time.\nCheck your code.");
|
||||
}
|
||||
else
|
||||
{
|
||||
SpotState = this;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -219,8 +209,6 @@ DSpotState::DSpotState ()
|
|||
void DSpotState::OnDestroy ()
|
||||
{
|
||||
SpotLists.Reset();
|
||||
|
||||
SpotState = NULL;
|
||||
Super::OnDestroy();
|
||||
}
|
||||
|
||||
|
@ -240,18 +228,6 @@ void DSpotState::Tick ()
|
|||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
DSpotState *DSpotState::GetSpotState(bool create)
|
||||
{
|
||||
if (SpotState == NULL && create) SpotState = Create<DSpotState>();
|
||||
return SpotState;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
FSpotList *DSpotState::FindSpotList(PClassActor *type)
|
||||
{
|
||||
if (type == nullptr) return nullptr;
|
||||
|
|
|
@ -7,10 +7,9 @@
|
|||
struct FSpotList;
|
||||
|
||||
|
||||
class DSpotState : public DThinker
|
||||
class DSpotState : public DObject
|
||||
{
|
||||
DECLARE_CLASS(DSpotState, DThinker)
|
||||
static TObjPtr<DSpotState*> SpotState;
|
||||
DECLARE_CLASS(DSpotState, DObject)
|
||||
TArray<FSpotList> SpotLists;
|
||||
|
||||
public:
|
||||
|
|
|
@ -251,7 +251,6 @@ struct FMugShotState
|
|||
TArray<FMugShotFrame> Frames;
|
||||
|
||||
FMugShotState(FName name);
|
||||
~FMugShotState();
|
||||
void Tick();
|
||||
void Reset();
|
||||
FMugShotFrame &GetCurrentFrame() { return Frames[Position]; }
|
||||
|
@ -454,6 +453,7 @@ public:
|
|||
|
||||
|
||||
void RefreshBackground () const;
|
||||
void RefreshViewBorder ();
|
||||
|
||||
private:
|
||||
DObject *AltHud = nullptr;
|
||||
|
|
|
@ -126,16 +126,6 @@ FMugShotState::FMugShotState(FName name)
|
|||
Random = M_Random();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// MugShotState destructor
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
FMugShotState::~FMugShotState()
|
||||
{
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// FMugShotState :: Tick
|
||||
|
@ -471,7 +461,7 @@ FTexture *FMugShot::GetFace(player_t *player, const char *default_face, int accu
|
|||
{
|
||||
int angle = UpdateState(player, stateflags);
|
||||
int level = 0;
|
||||
int max = player->mo->MugShotMaxHealth;
|
||||
int max = player->mo->IntVar(NAME_MugShotMaxHealth);
|
||||
if (max < 0)
|
||||
{
|
||||
max = player->mo->GetMaxHealth();
|
||||
|
@ -487,7 +477,7 @@ FTexture *FMugShot::GetFace(player_t *player, const char *default_face, int accu
|
|||
if (CurrentState != NULL)
|
||||
{
|
||||
int skin = player->userinfo.GetSkin();
|
||||
const char *skin_face = (stateflags & FMugShot::CUSTOM) ? nullptr : (player->morphTics ? ((APlayerPawn*)GetDefaultByType(player->MorphedPlayerClass))->Face.GetChars() : Skins[skin].Face.GetChars());
|
||||
const char *skin_face = (stateflags & FMugShot::CUSTOM) ? nullptr : (player->morphTics ? (GetDefaultByType(player->MorphedPlayerClass))->NameVar(NAME_Face).GetChars() : Skins[skin].Face.GetChars());
|
||||
return CurrentState->GetCurrentFrameTexture(default_face, skin_face, level, angle);
|
||||
}
|
||||
return NULL;
|
||||
|
|
|
@ -241,7 +241,7 @@ class CommandDrawImage : public SBarInfoCommandFlowControl
|
|||
applyscale = false;
|
||||
}
|
||||
if(type == PLAYERICON)
|
||||
texture = TexMan.GetTexture(statusBar->CPlayer->mo->ScoreIcon, true);
|
||||
texture = TexMan.ByIndex(statusBar->CPlayer->mo->IntVar(NAME_ScoreIcon), true);
|
||||
else if(type == AMMO1)
|
||||
{
|
||||
auto ammo = statusBar->ammo1;
|
||||
|
@ -293,8 +293,8 @@ class CommandDrawImage : public SBarInfoCommandFlowControl
|
|||
}
|
||||
else if(type == INVENTORYICON)
|
||||
texture = TexMan.GetTexture(sprite, true);
|
||||
else if(type == SELECTEDINVENTORYICON && statusBar->CPlayer->mo->InvSel != NULL)
|
||||
texture = TexMan.GetTexture(statusBar->CPlayer->mo->InvSel->TextureIDVar(NAME_Icon), true);
|
||||
else if(type == SELECTEDINVENTORYICON && statusBar->CPlayer->mo->PointerVar<AActor>(NAME_InvSel) != NULL)
|
||||
texture = TexMan.GetTexture(statusBar->CPlayer->mo->PointerVar<AActor>(NAME_InvSel)->TextureIDVar(NAME_Icon), true);
|
||||
else if(image >= 0)
|
||||
texture = statusBar->Images[image];
|
||||
|
||||
|
@ -892,7 +892,7 @@ class CommandDrawString : public SBarInfoCommand
|
|||
SetStringToTag(statusBar->CPlayer->ReadyWeapon);
|
||||
break;
|
||||
case INVENTORYTAG:
|
||||
SetStringToTag(statusBar->CPlayer->mo->InvSel);
|
||||
SetStringToTag(statusBar->CPlayer->mo->PointerVar<AActor>(NAME_InvSel));
|
||||
break;
|
||||
case PLAYERNAME:
|
||||
// Can't think of a good way to detect changes to this, so
|
||||
|
@ -904,7 +904,7 @@ class CommandDrawString : public SBarInfoCommand
|
|||
if(ACS_GlobalVars[valueArgument] != cache)
|
||||
{
|
||||
cache = ACS_GlobalVars[valueArgument];
|
||||
str = FBehavior::StaticLookupString(ACS_GlobalVars[valueArgument]);
|
||||
str = level.Behaviors.LookupString(ACS_GlobalVars[valueArgument]);
|
||||
RealignString();
|
||||
}
|
||||
break;
|
||||
|
@ -912,7 +912,7 @@ class CommandDrawString : public SBarInfoCommand
|
|||
if(ACS_GlobalArrays[valueArgument][consoleplayer] != cache)
|
||||
{
|
||||
cache = ACS_GlobalArrays[valueArgument][consoleplayer];
|
||||
str = FBehavior::StaticLookupString(ACS_GlobalArrays[valueArgument][consoleplayer]);
|
||||
str = level.Behaviors.LookupString(ACS_GlobalArrays[valueArgument][consoleplayer]);
|
||||
RealignString();
|
||||
}
|
||||
break;
|
||||
|
@ -923,7 +923,7 @@ class CommandDrawString : public SBarInfoCommand
|
|||
break;
|
||||
}
|
||||
case LOGTEXT:
|
||||
str = statusBar->CPlayer->LogText;
|
||||
str = GStrings(statusBar->CPlayer->LogText);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -1465,8 +1465,8 @@ class CommandDrawNumber : public CommandDrawString
|
|||
break;
|
||||
}
|
||||
case SELECTEDINVENTORY:
|
||||
if(statusBar->CPlayer->mo->InvSel != NULL)
|
||||
num = statusBar->CPlayer->mo->InvSel->IntVar(NAME_Amount);
|
||||
if(statusBar->CPlayer->mo->PointerVar<AActor>(NAME_InvSel) != NULL)
|
||||
num = statusBar->CPlayer->mo->PointerVar<AActor>(NAME_InvSel)->IntVar(NAME_Amount);
|
||||
break;
|
||||
case ACCURACY:
|
||||
num = statusBar->CPlayer->mo->accuracy;
|
||||
|
@ -1691,7 +1691,7 @@ class CommandDrawSelectedInventory : public CommandDrawImage, private CommandDra
|
|||
if(alternateOnEmpty)
|
||||
SBarInfoCommandFlowControl::Draw(block, statusBar);
|
||||
|
||||
if(statusBar->CPlayer->mo->InvSel != NULL && !(level.flags & LEVEL_NOINVENTORYBAR))
|
||||
if(statusBar->CPlayer->mo->PointerVar<AActor>(NAME_InvSel) != NULL && !(level.flags & LEVEL_NOINVENTORYBAR))
|
||||
{
|
||||
if(artiflash && statusBar->wrapper->artiflashTick)
|
||||
{
|
||||
|
@ -1708,7 +1708,7 @@ class CommandDrawSelectedInventory : public CommandDrawImage, private CommandDra
|
|||
}
|
||||
CommandDrawImage::Draw(block, statusBar);
|
||||
}
|
||||
if(alwaysShowCounter || statusBar->CPlayer->mo->InvSel->IntVar(NAME_Amount) != 1)
|
||||
if(alwaysShowCounter || statusBar->CPlayer->mo->PointerVar<AActor>(NAME_InvSel)->IntVar(NAME_Amount) != 1)
|
||||
CommandDrawNumber::Draw(block, statusBar);
|
||||
}
|
||||
}
|
||||
|
@ -1791,7 +1791,7 @@ class CommandDrawSelectedInventory : public CommandDrawImage, private CommandDra
|
|||
{
|
||||
SBarInfoCommandFlowControl::Tick(block, statusBar, hudChanged);
|
||||
|
||||
SetTruth(statusBar->CPlayer->mo->InvSel == NULL || (level.flags & LEVEL_NOINVENTORYBAR), block, statusBar);
|
||||
SetTruth(statusBar->CPlayer->mo->PointerVar<AActor>(NAME_InvSel) == NULL || (level.flags & LEVEL_NOINVENTORYBAR), block, statusBar);
|
||||
|
||||
CommandDrawImage::Tick(block, statusBar, hudChanged);
|
||||
CommandDrawNumber::Tick(block, statusBar, hudChanged);
|
||||
|
@ -2119,11 +2119,12 @@ class CommandDrawInventoryBar : public SBarInfoCommand
|
|||
|
||||
AActor *item;
|
||||
unsigned int i = 0;
|
||||
auto &InvFirst = statusBar->CPlayer->mo->PointerVar<AActor>(NAME_InvFirst);
|
||||
// If the player has no artifacts, don't draw the bar
|
||||
statusBar->CPlayer->mo->InvFirst = statusBar->wrapper->ValidateInvFirst(size);
|
||||
if(statusBar->CPlayer->mo->InvFirst != NULL || alwaysShow)
|
||||
InvFirst = statusBar->wrapper->ValidateInvFirst(size);
|
||||
if (InvFirst != nullptr || alwaysShow)
|
||||
{
|
||||
for(item = statusBar->CPlayer->mo->InvFirst, i = 0; item != NULL && i < size; item = NextInv(item), ++i)
|
||||
for(item = InvFirst, i = 0; item != NULL && i < size; item = NextInv(item), ++i)
|
||||
{
|
||||
SBarInfoCoordinate rx = x + (!vertical ? i*spacing : 0);
|
||||
SBarInfoCoordinate ry = y + (vertical ? i*spacing : 0);
|
||||
|
@ -2132,7 +2133,7 @@ class CommandDrawInventoryBar : public SBarInfoCommand
|
|||
|
||||
if(style != STYLE_Strife) //Strife draws the cursor before the icons
|
||||
statusBar->DrawGraphic(TexMan.GetTexture(item->TextureIDVar(NAME_Icon), true), rx - (style == STYLE_HexenStrict ? 2 : 0), ry - (style == STYLE_HexenStrict ? 1 : 0), block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets(), false, item->IntVar(NAME_Amount) <= 0);
|
||||
if(item == statusBar->CPlayer->mo->InvSel)
|
||||
if(item == statusBar->CPlayer->mo->PointerVar<AActor>(NAME_InvSel))
|
||||
{
|
||||
if(style == STYLE_Heretic)
|
||||
statusBar->DrawGraphic(statusBar->Images[statusBar->invBarOffset + imgSELECTBOX], rx, ry+29, block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets());
|
||||
|
@ -2157,7 +2158,7 @@ class CommandDrawInventoryBar : public SBarInfoCommand
|
|||
statusBar->DrawGraphic(statusBar->Images[statusBar->invBarOffset + imgARTIBOX], x + (!vertical ? (i*spacing) : 0), y + (vertical ? (i*spacing) : 0), block->XOffset(), block->YOffset(), bgalpha, block->FullScreenOffsets());
|
||||
|
||||
// Is there something to the left?
|
||||
if (!noArrows && PrevInv(statusBar->CPlayer->mo->InvFirst))
|
||||
if (!noArrows && InvFirst && PrevInv(statusBar->CPlayer->mo->PointerVar<AActor>(NAME_InvFirst)))
|
||||
{
|
||||
int offset = (style != STYLE_Strife ? (style != STYLE_HexenStrict ? -12 : -10) : 14);
|
||||
int yOffset = style != STYLE_HexenStrict ? 0 : -1;
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
#include "vm.h"
|
||||
#include "p_acs.h"
|
||||
#include "sbarinfo.h"
|
||||
#include "gstrings.h"
|
||||
#include "events.h"
|
||||
|
||||
#include "../version.h"
|
||||
|
@ -436,7 +437,7 @@ void DBaseStatusBar::OnDestroy ()
|
|||
msg->Destroy();
|
||||
msg = next;
|
||||
}
|
||||
Messages[i] = NULL;
|
||||
Messages[i] = nullptr;
|
||||
}
|
||||
if (AltHud) AltHud->Destroy();
|
||||
Super::OnDestroy();
|
||||
|
@ -594,7 +595,7 @@ void DBaseStatusBar::Tick ()
|
|||
for (size_t i = 0; i < countof(Messages); ++i)
|
||||
{
|
||||
DHUDMessageBase *msg = Messages[i];
|
||||
DHUDMessageBase **prev = &Messages[i];
|
||||
TObjPtr<DHUDMessageBase *>*prev = &Messages[i];
|
||||
|
||||
while (msg)
|
||||
{
|
||||
|
@ -657,7 +658,7 @@ void DBaseStatusBar::CallTick()
|
|||
void DBaseStatusBar::AttachMessage (DHUDMessageBase *msg, uint32_t id, int layer)
|
||||
{
|
||||
DHUDMessageBase *old = NULL;
|
||||
DHUDMessageBase **prev;
|
||||
TObjPtr<DHUDMessageBase *>*prev;
|
||||
|
||||
old = (id == 0 || id == 0xFFFFFFFF) ? NULL : DetachMessage (id);
|
||||
if (old != NULL)
|
||||
|
@ -698,7 +699,7 @@ DHUDMessageBase *DBaseStatusBar::DetachMessage (DHUDMessageBase *msg)
|
|||
for (size_t i = 0; i < countof(Messages); ++i)
|
||||
{
|
||||
DHUDMessageBase *probe = Messages[i];
|
||||
DHUDMessageBase **prev = &Messages[i];
|
||||
TObjPtr<DHUDMessageBase *>*prev = &Messages[i];
|
||||
|
||||
while (probe && probe != msg)
|
||||
{
|
||||
|
@ -708,7 +709,7 @@ DHUDMessageBase *DBaseStatusBar::DetachMessage (DHUDMessageBase *msg)
|
|||
if (probe != NULL)
|
||||
{
|
||||
*prev = probe->Next;
|
||||
probe->Next = NULL;
|
||||
probe->Next = nullptr;
|
||||
return probe;
|
||||
}
|
||||
}
|
||||
|
@ -720,7 +721,7 @@ DHUDMessageBase *DBaseStatusBar::DetachMessage (uint32_t id)
|
|||
for (size_t i = 0; i < countof(Messages); ++i)
|
||||
{
|
||||
DHUDMessageBase *probe = Messages[i];
|
||||
DHUDMessageBase **prev = &Messages[i];
|
||||
TObjPtr<DHUDMessageBase *>*prev = &Messages[i];
|
||||
|
||||
while (probe && probe->SBarID != id)
|
||||
{
|
||||
|
@ -730,7 +731,7 @@ DHUDMessageBase *DBaseStatusBar::DetachMessage (uint32_t id)
|
|||
if (probe != NULL)
|
||||
{
|
||||
*prev = probe->Next;
|
||||
probe->Next = NULL;
|
||||
probe->Next = nullptr;
|
||||
return probe;
|
||||
}
|
||||
}
|
||||
|
@ -749,7 +750,7 @@ void DBaseStatusBar::DetachAllMessages ()
|
|||
{
|
||||
DHUDMessageBase *probe = Messages[i];
|
||||
|
||||
Messages[i] = NULL;
|
||||
Messages[i] = nullptr;
|
||||
while (probe != NULL)
|
||||
{
|
||||
DHUDMessageBase *next = probe->Next;
|
||||
|
@ -774,6 +775,49 @@ void DBaseStatusBar::ShowPlayerName ()
|
|||
1.5f, 0.92f, 0, 0, color, 2.f, 0.35f), MAKE_ID('P','N','A','M'));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
static FTextureID GetBorderTexture(FLevelLocals *Level)
|
||||
{
|
||||
if (Level != nullptr && Level->info != nullptr && Level->info->BorderTexture.Len() != 0)
|
||||
{
|
||||
auto picnum = TexMan.CheckForTexture (Level->info->BorderTexture, ETextureType::Flat);
|
||||
if (picnum.isValid()) return picnum;
|
||||
}
|
||||
return TexMan.CheckForTexture (gameinfo.BorderFlat, ETextureType::Flat);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// R_RefreshViewBorder
|
||||
//
|
||||
// Draws the border around the player view, if needed.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void DBaseStatusBar::RefreshViewBorder ()
|
||||
{
|
||||
if (setblocks < 10)
|
||||
{
|
||||
int Width = screen->GetWidth();
|
||||
if (viewwidth == Width)
|
||||
{
|
||||
return;
|
||||
}
|
||||
auto tex = GetBorderTexture(&level);
|
||||
screen->DrawBorder (tex, 0, 0, Width, viewwindowy);
|
||||
screen->DrawBorder (tex, 0, viewwindowy, viewwindowx, viewheight + viewwindowy);
|
||||
screen->DrawBorder (tex, viewwindowx + viewwidth, viewwindowy, Width, viewheight + viewwindowy);
|
||||
screen->DrawBorder (tex, 0, viewwindowy + viewheight, Width, StatusBar->GetTopOfStatusbar());
|
||||
|
||||
screen->DrawFrame (viewwindowx, viewwindowy, viewwidth, viewheight);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// RefreshBackground
|
||||
|
@ -787,13 +831,17 @@ void DBaseStatusBar::RefreshBackground () const
|
|||
float ratio = ActiveRatio (SCREENWIDTH, SCREENHEIGHT);
|
||||
x = ST_X;
|
||||
y = SBarTop;
|
||||
|
||||
if (x == 0 && y == SCREENHEIGHT) return;
|
||||
|
||||
auto tex = GetBorderTexture(&level);
|
||||
|
||||
if(!CompleteBorder)
|
||||
{
|
||||
if(y < SCREENHEIGHT)
|
||||
{
|
||||
screen->DrawBorder (x+1, y, SCREENWIDTH, y+1);
|
||||
screen->DrawBorder (x+1, SCREENHEIGHT-1, SCREENWIDTH, SCREENHEIGHT);
|
||||
screen->DrawBorder (tex, x+1, y, SCREENWIDTH, y+1);
|
||||
screen->DrawBorder (tex, x+1, SCREENHEIGHT-1, SCREENWIDTH, SCREENHEIGHT);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -812,8 +860,8 @@ void DBaseStatusBar::RefreshBackground () const
|
|||
x2 = SCREENWIDTH;
|
||||
}
|
||||
|
||||
screen->DrawBorder (0, y, x+1, SCREENHEIGHT);
|
||||
screen->DrawBorder (x2-1, y, SCREENWIDTH, SCREENHEIGHT);
|
||||
screen->DrawBorder (tex, 0, y, x+1, SCREENHEIGHT);
|
||||
screen->DrawBorder (tex, x2-1, y, SCREENWIDTH, SCREENHEIGHT);
|
||||
|
||||
if (setblocks >= 10)
|
||||
{
|
||||
|
@ -1017,7 +1065,7 @@ void DBaseStatusBar::DrawLog ()
|
|||
hudheight = SCREENHEIGHT / scale;
|
||||
|
||||
int linelen = hudwidth<640? Scale(hudwidth,9,10)-40 : 560;
|
||||
auto lines = V_BreakLines (SmallFont, linelen, CPlayer->LogText);
|
||||
auto lines = V_BreakLines (SmallFont, linelen, GStrings(CPlayer->LogText));
|
||||
int height = 20;
|
||||
|
||||
for (unsigned i = 0; i < lines.Size(); i++) height += SmallFont->GetHeight () + 1;
|
||||
|
|
177
src/gi.cpp
177
src/gi.cpp
|
@ -40,9 +40,13 @@
|
|||
#include "v_video.h"
|
||||
#include "g_level.h"
|
||||
#include "vm.h"
|
||||
#include "c_cvars.h"
|
||||
|
||||
gameinfo_t gameinfo;
|
||||
|
||||
EXTERN_CVAR(Float, turbo)
|
||||
|
||||
|
||||
DEFINE_GLOBAL(gameinfo)
|
||||
DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, backpacktype)
|
||||
DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, Armor2Percent)
|
||||
|
@ -67,6 +71,8 @@ DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, defKickback)
|
|||
DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, healthpic)
|
||||
DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, berserkpic)
|
||||
DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, defaultdropstyle)
|
||||
DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, normforwardmove)
|
||||
DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, normsidemove)
|
||||
|
||||
const char *GameNames[17] =
|
||||
{
|
||||
|
@ -186,6 +192,16 @@ const char* GameInfoBorders[] =
|
|||
gameinfo.key = sc.Float; \
|
||||
}
|
||||
|
||||
#define GAMEINFOKEY_TWODOUBLES(key, variable) \
|
||||
else if(nextKey.CompareNoCase(variable) == 0) \
|
||||
{ \
|
||||
sc.MustGetValue(true); \
|
||||
gameinfo.key[0] = sc.Float; \
|
||||
sc.MustGetToken(','); \
|
||||
sc.MustGetValue(true); \
|
||||
gameinfo.key[1] = sc.Float; \
|
||||
}
|
||||
|
||||
#define GAMEINFOKEY_COLOR(key, variable) \
|
||||
else if(nextKey.CompareNoCase(variable) == 0) \
|
||||
{ \
|
||||
|
@ -250,7 +266,7 @@ void FMapInfoParser::ParseGameInfo()
|
|||
sc.MustGetToken('{');
|
||||
while(sc.GetToken())
|
||||
{
|
||||
if (sc.TokenType == '}') return;
|
||||
if (sc.TokenType == '}') break;
|
||||
|
||||
sc.TokenMustBe(TK_Identifier);
|
||||
FString nextKey = sc.String;
|
||||
|
@ -337,84 +353,86 @@ void FMapInfoParser::ParseGameInfo()
|
|||
}
|
||||
// Insert valid keys here.
|
||||
GAMEINFOKEY_STRING(mCheatKey, "cheatKey")
|
||||
GAMEINFOKEY_STRING(mEasyKey, "easyKey")
|
||||
GAMEINFOKEY_STRING(TitlePage, "titlePage")
|
||||
GAMEINFOKEY_STRINGARRAY(creditPages, "addcreditPage", 8, false)
|
||||
GAMEINFOKEY_STRINGARRAY(creditPages, "CreditPage", 8, true)
|
||||
GAMEINFOKEY_STRINGARRAY(PlayerClasses, "addplayerclasses", 0, false)
|
||||
GAMEINFOKEY_STRINGARRAY(PlayerClasses, "playerclasses", 0, true)
|
||||
GAMEINFOKEY_MUSIC(titleMusic, titleOrder, "titleMusic")
|
||||
GAMEINFOKEY_FLOAT(titleTime, "titleTime")
|
||||
GAMEINFOKEY_FLOAT(advisoryTime, "advisoryTime")
|
||||
GAMEINFOKEY_FLOAT(pageTime, "pageTime")
|
||||
GAMEINFOKEY_STRING(chatSound, "chatSound")
|
||||
GAMEINFOKEY_MUSIC(finaleMusic, finaleOrder, "finaleMusic")
|
||||
GAMEINFOKEY_STRING(FinaleFlat, "finaleFlat")
|
||||
GAMEINFOKEY_STRINGARRAY(finalePages, "finalePage", 8, true)
|
||||
GAMEINFOKEY_STRINGARRAY(infoPages, "addinfoPage", 8, false)
|
||||
GAMEINFOKEY_STRINGARRAY(infoPages, "infoPage", 8, true)
|
||||
GAMEINFOKEY_STRINGARRAY(PrecachedClasses, "precacheclasses", 0, false)
|
||||
GAMEINFOKEY_STRINGARRAY(PrecachedTextures, "precachetextures", 0, false)
|
||||
GAMEINFOKEY_SOUNDARRAY(PrecachedSounds, "precachesounds", 0, false)
|
||||
GAMEINFOKEY_STRINGARRAY(EventHandlers, "addeventhandlers", 0, false)
|
||||
GAMEINFOKEY_STRINGARRAY(EventHandlers, "eventhandlers", 0, true)
|
||||
GAMEINFOKEY_STRING(PauseSign, "pausesign")
|
||||
GAMEINFOKEY_STRING(quitSound, "quitSound")
|
||||
GAMEINFOKEY_STRING(BorderFlat, "borderFlat")
|
||||
GAMEINFOKEY_DOUBLE(telefogheight, "telefogheight")
|
||||
GAMEINFOKEY_DOUBLE(gibfactor, "gibfactor")
|
||||
GAMEINFOKEY_INT(defKickback, "defKickback")
|
||||
GAMEINFOKEY_STRING(SkyFlatName, "SkyFlatName")
|
||||
GAMEINFOKEY_STRING(translator, "translator")
|
||||
GAMEINFOKEY_COLOR(pickupcolor, "pickupcolor")
|
||||
GAMEINFOKEY_COLOR(defaultbloodcolor, "defaultbloodcolor")
|
||||
GAMEINFOKEY_COLOR(defaultbloodparticlecolor, "defaultbloodparticlecolor")
|
||||
GAMEINFOKEY_STRING(backpacktype, "backpacktype")
|
||||
GAMEINFOKEY_STRING_STAMPED(statusbar, "statusbar", statusbarfile)
|
||||
GAMEINFOKEY_STRING_STAMPED(statusbarclass, "statusbarclass", statusbarclassfile)
|
||||
GAMEINFOKEY_MUSIC(intermissionMusic, intermissionOrder, "intermissionMusic")
|
||||
GAMEINFOKEY_STRING(CursorPic, "CursorPic")
|
||||
GAMEINFOKEY_STRING(MessageBoxClass, "MessageBoxClass")
|
||||
GAMEINFOKEY_BOOL(noloopfinalemusic, "noloopfinalemusic")
|
||||
GAMEINFOKEY_BOOL(drawreadthis, "drawreadthis")
|
||||
GAMEINFOKEY_BOOL(swapmenu, "swapmenu")
|
||||
GAMEINFOKEY_BOOL(dontcrunchcorpses, "dontcrunchcorpses")
|
||||
GAMEINFOKEY_BOOL(correctprintbold, "correctprintbold")
|
||||
GAMEINFOKEY_BOOL(intermissioncounter, "intermissioncounter")
|
||||
GAMEINFOKEY_BOOL(nightmarefast, "nightmarefast")
|
||||
GAMEINFOKEY_COLOR(dimcolor, "dimcolor")
|
||||
GAMEINFOKEY_FLOAT(dimamount, "dimamount")
|
||||
GAMEINFOKEY_FLOAT(bluramount, "bluramount")
|
||||
GAMEINFOKEY_STRING(mSliderColor, "menuslidercolor")
|
||||
GAMEINFOKEY_INT(definventorymaxamount, "definventorymaxamount")
|
||||
GAMEINFOKEY_INT(defaultrespawntime, "defaultrespawntime")
|
||||
GAMEINFOKEY_INT(defaultdropstyle, "defaultdropstyle")
|
||||
GAMEINFOKEY_STRING(Endoom, "endoom")
|
||||
GAMEINFOKEY_STRINGARRAY(quitmessages, "addquitmessages", 0, false)
|
||||
GAMEINFOKEY_STRINGARRAY(quitmessages, "quitmessages", 0, true)
|
||||
GAMEINFOKEY_STRING(mTitleColor, "menufontcolor_title")
|
||||
GAMEINFOKEY_STRING(mFontColor, "menufontcolor_label")
|
||||
GAMEINFOKEY_STRING(mFontColorValue, "menufontcolor_value")
|
||||
GAMEINFOKEY_STRING(mFontColorMore, "menufontcolor_action")
|
||||
GAMEINFOKEY_STRING(mFontColorHeader, "menufontcolor_header")
|
||||
GAMEINFOKEY_STRING(mFontColorHighlight, "menufontcolor_highlight")
|
||||
GAMEINFOKEY_STRING(mFontColorSelection, "menufontcolor_selection")
|
||||
GAMEINFOKEY_STRING(mBackButton, "menubackbutton")
|
||||
GAMEINFOKEY_INT(TextScreenX, "textscreenx")
|
||||
GAMEINFOKEY_INT(TextScreenY, "textscreeny")
|
||||
GAMEINFOKEY_STRING(DefaultEndSequence, "defaultendsequence")
|
||||
GAMEINFOKEY_STRING(DefaultConversationMenuClass, "defaultconversationmenuclass")
|
||||
GAMEINFOKEY_FONT(mStatscreenMapNameFont, "statscreen_mapnamefont")
|
||||
GAMEINFOKEY_FONT(mStatscreenFinishedFont, "statscreen_finishedfont")
|
||||
GAMEINFOKEY_FONT(mStatscreenEnteringFont, "statscreen_enteringfont")
|
||||
GAMEINFOKEY_PATCH(mStatscreenFinishedFont, "statscreen_finishedpatch")
|
||||
GAMEINFOKEY_PATCH(mStatscreenEnteringFont, "statscreen_enteringpatch")
|
||||
GAMEINFOKEY_BOOL(norandomplayerclass, "norandomplayerclass")
|
||||
GAMEINFOKEY_BOOL(forcekillscripts, "forcekillscripts") // [JM] Force kill scripts on thing death. (MF7_NOKILLSCRIPTS overrides.)
|
||||
GAMEINFOKEY_STRING(Dialogue, "dialogue")
|
||||
GAMEINFOKEY_STRING(statusscreen_single, "statscreen_single")
|
||||
GAMEINFOKEY_STRING(statusscreen_coop, "statscreen_coop")
|
||||
GAMEINFOKEY_STRING(statusscreen_dm, "statscreen_dm")
|
||||
GAMEINFOKEY_STRING(mEasyKey, "easyKey")
|
||||
GAMEINFOKEY_STRING(TitlePage, "titlePage")
|
||||
GAMEINFOKEY_STRINGARRAY(creditPages, "addcreditPage", 8, false)
|
||||
GAMEINFOKEY_STRINGARRAY(creditPages, "CreditPage", 8, true)
|
||||
GAMEINFOKEY_STRINGARRAY(PlayerClasses, "addplayerclasses", 0, false)
|
||||
GAMEINFOKEY_STRINGARRAY(PlayerClasses, "playerclasses", 0, true)
|
||||
GAMEINFOKEY_MUSIC(titleMusic, titleOrder, "titleMusic")
|
||||
GAMEINFOKEY_FLOAT(titleTime, "titleTime")
|
||||
GAMEINFOKEY_FLOAT(advisoryTime, "advisoryTime")
|
||||
GAMEINFOKEY_FLOAT(pageTime, "pageTime")
|
||||
GAMEINFOKEY_STRING(chatSound, "chatSound")
|
||||
GAMEINFOKEY_MUSIC(finaleMusic, finaleOrder, "finaleMusic")
|
||||
GAMEINFOKEY_STRING(FinaleFlat, "finaleFlat")
|
||||
GAMEINFOKEY_STRINGARRAY(finalePages, "finalePage", 8, true)
|
||||
GAMEINFOKEY_STRINGARRAY(infoPages, "addinfoPage", 8, false)
|
||||
GAMEINFOKEY_STRINGARRAY(infoPages, "infoPage", 8, true)
|
||||
GAMEINFOKEY_STRINGARRAY(PrecachedClasses, "precacheclasses", 0, false)
|
||||
GAMEINFOKEY_STRINGARRAY(PrecachedTextures, "precachetextures", 0, false)
|
||||
GAMEINFOKEY_SOUNDARRAY(PrecachedSounds, "precachesounds", 0, false)
|
||||
GAMEINFOKEY_STRINGARRAY(EventHandlers, "addeventhandlers", 0, false)
|
||||
GAMEINFOKEY_STRINGARRAY(EventHandlers, "eventhandlers", 0, true)
|
||||
GAMEINFOKEY_STRING(PauseSign, "pausesign")
|
||||
GAMEINFOKEY_STRING(quitSound, "quitSound")
|
||||
GAMEINFOKEY_STRING(BorderFlat, "borderFlat")
|
||||
GAMEINFOKEY_DOUBLE(telefogheight, "telefogheight")
|
||||
GAMEINFOKEY_DOUBLE(gibfactor, "gibfactor")
|
||||
GAMEINFOKEY_INT(defKickback, "defKickback")
|
||||
GAMEINFOKEY_STRING(SkyFlatName, "SkyFlatName")
|
||||
GAMEINFOKEY_STRING(translator, "translator")
|
||||
GAMEINFOKEY_COLOR(pickupcolor, "pickupcolor")
|
||||
GAMEINFOKEY_COLOR(defaultbloodcolor, "defaultbloodcolor")
|
||||
GAMEINFOKEY_COLOR(defaultbloodparticlecolor, "defaultbloodparticlecolor")
|
||||
GAMEINFOKEY_STRING(backpacktype, "backpacktype")
|
||||
GAMEINFOKEY_STRING_STAMPED(statusbar, "statusbar", statusbarfile)
|
||||
GAMEINFOKEY_STRING_STAMPED(statusbarclass, "statusbarclass", statusbarclassfile)
|
||||
GAMEINFOKEY_MUSIC(intermissionMusic, intermissionOrder, "intermissionMusic")
|
||||
GAMEINFOKEY_STRING(CursorPic, "CursorPic")
|
||||
GAMEINFOKEY_STRING(MessageBoxClass, "MessageBoxClass")
|
||||
GAMEINFOKEY_BOOL(noloopfinalemusic, "noloopfinalemusic")
|
||||
GAMEINFOKEY_BOOL(drawreadthis, "drawreadthis")
|
||||
GAMEINFOKEY_BOOL(swapmenu, "swapmenu")
|
||||
GAMEINFOKEY_BOOL(dontcrunchcorpses, "dontcrunchcorpses")
|
||||
GAMEINFOKEY_BOOL(correctprintbold, "correctprintbold")
|
||||
GAMEINFOKEY_BOOL(intermissioncounter, "intermissioncounter")
|
||||
GAMEINFOKEY_BOOL(nightmarefast, "nightmarefast")
|
||||
GAMEINFOKEY_COLOR(dimcolor, "dimcolor")
|
||||
GAMEINFOKEY_FLOAT(dimamount, "dimamount")
|
||||
GAMEINFOKEY_FLOAT(bluramount, "bluramount")
|
||||
GAMEINFOKEY_STRING(mSliderColor, "menuslidercolor")
|
||||
GAMEINFOKEY_INT(definventorymaxamount, "definventorymaxamount")
|
||||
GAMEINFOKEY_INT(defaultrespawntime, "defaultrespawntime")
|
||||
GAMEINFOKEY_INT(defaultdropstyle, "defaultdropstyle")
|
||||
GAMEINFOKEY_STRING(Endoom, "endoom")
|
||||
GAMEINFOKEY_STRINGARRAY(quitmessages, "addquitmessages", 0, false)
|
||||
GAMEINFOKEY_STRINGARRAY(quitmessages, "quitmessages", 0, true)
|
||||
GAMEINFOKEY_STRING(mTitleColor, "menufontcolor_title")
|
||||
GAMEINFOKEY_STRING(mFontColor, "menufontcolor_label")
|
||||
GAMEINFOKEY_STRING(mFontColorValue, "menufontcolor_value")
|
||||
GAMEINFOKEY_STRING(mFontColorMore, "menufontcolor_action")
|
||||
GAMEINFOKEY_STRING(mFontColorHeader, "menufontcolor_header")
|
||||
GAMEINFOKEY_STRING(mFontColorHighlight, "menufontcolor_highlight")
|
||||
GAMEINFOKEY_STRING(mFontColorSelection, "menufontcolor_selection")
|
||||
GAMEINFOKEY_STRING(mBackButton, "menubackbutton")
|
||||
GAMEINFOKEY_INT(TextScreenX, "textscreenx")
|
||||
GAMEINFOKEY_INT(TextScreenY, "textscreeny")
|
||||
GAMEINFOKEY_STRING(DefaultEndSequence, "defaultendsequence")
|
||||
GAMEINFOKEY_STRING(DefaultConversationMenuClass, "defaultconversationmenuclass")
|
||||
GAMEINFOKEY_FONT(mStatscreenMapNameFont, "statscreen_mapnamefont")
|
||||
GAMEINFOKEY_FONT(mStatscreenFinishedFont, "statscreen_finishedfont")
|
||||
GAMEINFOKEY_FONT(mStatscreenEnteringFont, "statscreen_enteringfont")
|
||||
GAMEINFOKEY_PATCH(mStatscreenFinishedFont, "statscreen_finishedpatch")
|
||||
GAMEINFOKEY_PATCH(mStatscreenEnteringFont, "statscreen_enteringpatch")
|
||||
GAMEINFOKEY_BOOL(norandomplayerclass, "norandomplayerclass")
|
||||
GAMEINFOKEY_BOOL(forcekillscripts, "forcekillscripts") // [JM] Force kill scripts on thing death. (MF7_NOKILLSCRIPTS overrides.)
|
||||
GAMEINFOKEY_STRING(Dialogue, "dialogue")
|
||||
GAMEINFOKEY_STRING(statusscreen_single, "statscreen_single")
|
||||
GAMEINFOKEY_STRING(statusscreen_coop, "statscreen_coop")
|
||||
GAMEINFOKEY_STRING(statusscreen_dm, "statscreen_dm")
|
||||
GAMEINFOKEY_TWODOUBLES(normforwardmove, "normforwardmove")
|
||||
GAMEINFOKEY_TWODOUBLES(normsidemove, "normsidemove")
|
||||
|
||||
else
|
||||
{
|
||||
|
@ -425,6 +443,7 @@ void FMapInfoParser::ParseGameInfo()
|
|||
SkipToNext();
|
||||
}
|
||||
}
|
||||
turbo.Callback();
|
||||
}
|
||||
|
||||
const char *gameinfo_t::GetFinalePage(unsigned int num) const
|
||||
|
|
2
src/gi.h
2
src/gi.h
|
@ -193,6 +193,8 @@ struct gameinfo_t
|
|||
FName statusscreen_dm;
|
||||
int healthpic; // These get filled in from ALTHUDCF
|
||||
int berserkpic;
|
||||
double normforwardmove[2];
|
||||
double normsidemove[2];
|
||||
|
||||
const char *GetFinalePage(unsigned int num) const;
|
||||
};
|
||||
|
|
|
@ -254,7 +254,9 @@ sector_t *FGLRenderer::RenderView(player_t* player)
|
|||
bool saved_niv = NoInterpolateView;
|
||||
NoInterpolateView = false;
|
||||
// prepare all camera textures that have been used in the last frame
|
||||
level.canvasTextureInfo.UpdateAll([&](AActor *camera, FCanvasTexture *camtex, double fov)
|
||||
auto Level = &level;
|
||||
gl_RenderState.CheckTimer(Level->ShaderStartTime);
|
||||
Level->canvasTextureInfo.UpdateAll([&](AActor *camera, FCanvasTexture *camtex, double fov)
|
||||
{
|
||||
RenderTextureView(camtex, camera, fov);
|
||||
});
|
||||
|
@ -273,7 +275,6 @@ sector_t *FGLRenderer::RenderView(player_t* player)
|
|||
fovratio = ratio;
|
||||
}
|
||||
|
||||
UpdateShadowMap();
|
||||
retsec = RenderViewpoint(r_viewpoint, player->camera, NULL, r_viewpoint.FieldOfView.Degrees, ratio, fovratio, true, true);
|
||||
}
|
||||
All.Unclock();
|
||||
|
@ -362,7 +363,7 @@ void FGLRenderer::WriteSavePic (player_t *player, FileWriter *file, int width, i
|
|||
FRenderViewpoint savevp;
|
||||
sector_t *viewsector = RenderViewpoint(savevp, players[consoleplayer].camera, &bounds, r_viewpoint.FieldOfView.Degrees, 1.6f, 1.6f, true, false);
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
gl_RenderState.SetSoftLightLevel(-1);
|
||||
gl_RenderState.SetNoSoftLightLevel();
|
||||
CopyToBackbuffer(&bounds, false);
|
||||
|
||||
// strictly speaking not needed as the glReadPixels should block until the scene is rendered, but this is to safeguard against shitty drivers
|
||||
|
|
|
@ -48,7 +48,6 @@ namespace OpenGLRenderer
|
|||
FGLRenderState gl_RenderState;
|
||||
|
||||
static VSMatrix identityMatrix(1);
|
||||
TArray<VSMatrix> gl_MatrixStack;
|
||||
|
||||
static void matrixToGL(const VSMatrix &mat, int loc)
|
||||
{
|
||||
|
@ -94,12 +93,6 @@ void FGLRenderState::Reset()
|
|||
|
||||
bool FGLRenderState::ApplyShader()
|
||||
{
|
||||
static uint64_t firstFrame = 0;
|
||||
// if firstFrame is not yet initialized, initialize it to current time
|
||||
// if we're going to overflow a float (after ~4.6 hours, or 24 bits), re-init to regain precision
|
||||
if ((firstFrame == 0) || (screen->FrameTime - firstFrame >= 1<<24) || level.ShaderStartTime >= firstFrame)
|
||||
firstFrame = screen->FrameTime;
|
||||
|
||||
static const float nulvec[] = { 0.f, 0.f, 0.f, 0.f };
|
||||
if (mSpecialEffect > EFF_NONE)
|
||||
{
|
||||
|
@ -596,4 +589,12 @@ bool FGLRenderState::SetDepthClamp(bool on)
|
|||
return res;
|
||||
}
|
||||
|
||||
void FGLRenderState::CheckTimer(uint64_t ShaderStartTime)
|
||||
{
|
||||
// if firstFrame is not yet initialized, initialize it to current time
|
||||
// if we're going to overflow a float (after ~4.6 hours, or 24 bits), re-init to regain precision
|
||||
if ((firstFrame == 0) || (screen->FrameTime - firstFrame >= 1 << 24) || ShaderStartTime >= firstFrame)
|
||||
firstFrame = screen->FrameTime;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -39,7 +39,6 @@ namespace OpenGLRenderer
|
|||
|
||||
class FShader;
|
||||
struct GLSectorPlane;
|
||||
extern TArray<VSMatrix> gl_MatrixStack;
|
||||
|
||||
enum EPassType
|
||||
{
|
||||
|
@ -51,6 +50,8 @@ enum EPassType
|
|||
|
||||
class FGLRenderState : public FRenderState
|
||||
{
|
||||
uint64_t firstFrame = 0;
|
||||
|
||||
uint8_t mLastDepthClamp : 1;
|
||||
|
||||
float mGlossiness, mSpecularLevel;
|
||||
|
@ -103,6 +104,7 @@ public:
|
|||
void Apply();
|
||||
void ApplyBuffers();
|
||||
void ApplyBlendMode();
|
||||
void CheckTimer(uint64_t ShaderStartTime);
|
||||
|
||||
void ResetVertexBuffer()
|
||||
{
|
||||
|
|
|
@ -152,6 +152,9 @@ sector_t * FGLRenderer::RenderViewpoint (FRenderViewpoint &mainvp, AActor * came
|
|||
{
|
||||
R_SetupFrame (mainvp, r_viewwindow, camera);
|
||||
|
||||
if (mainview && toscreen)
|
||||
UpdateShadowMap();
|
||||
|
||||
// Render (potentially) multiple views for stereo 3d
|
||||
// Fixme. The view offsetting should be done with a static table and not require setup of the entire render state for the mode.
|
||||
auto vrmode = VRMode::GetVRMode(mainview && toscreen);
|
||||
|
|
|
@ -65,9 +65,8 @@ void GLBuffer::Bind()
|
|||
}
|
||||
|
||||
|
||||
void GLBuffer::SetData(size_t size, void *data, bool staticdata)
|
||||
void GLBuffer::SetData(size_t size, const void *data, bool staticdata)
|
||||
{
|
||||
assert(nomap); // once it's mappable, it cannot be recreated anymore.
|
||||
Bind();
|
||||
if (data != nullptr)
|
||||
{
|
||||
|
@ -92,6 +91,12 @@ void GLBuffer::SetData(size_t size, void *data, bool staticdata)
|
|||
InvalidateBufferState();
|
||||
}
|
||||
|
||||
void GLBuffer::SetSubData(size_t offset, size_t size, const void *data)
|
||||
{
|
||||
Bind();
|
||||
glBufferSubData(mUseType, offset, size, data);
|
||||
}
|
||||
|
||||
void GLBuffer::Map()
|
||||
{
|
||||
assert(nomap == false); // do not allow mapping of static buffers. Vulkan cannot do that so it should be blocked in OpenGL, too.
|
||||
|
|
|
@ -22,7 +22,8 @@ protected:
|
|||
|
||||
GLBuffer(int usetype);
|
||||
~GLBuffer();
|
||||
void SetData(size_t size, void *data, bool staticdata) override;
|
||||
void SetData(size_t size, const void *data, bool staticdata) override;
|
||||
void SetSubData(size_t offset, size_t size, const void *data) override;
|
||||
void Map() override;
|
||||
void Unmap() override;
|
||||
void Resize(size_t newsize) override;
|
||||
|
|
|
@ -58,12 +58,7 @@ void gl_LoadExtensions();
|
|||
void gl_PrintStartupLog();
|
||||
void Draw2D(F2DDrawer *drawer, FRenderState &state);
|
||||
|
||||
|
||||
CUSTOM_CVAR(Int, vid_hwgamma, 2, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
|
||||
{
|
||||
if (self < 0 || self > 2) self = 2;
|
||||
if (screen != nullptr) screen->SetGamma();
|
||||
}
|
||||
extern bool vid_hdr_active;
|
||||
|
||||
namespace OpenGLRenderer
|
||||
{
|
||||
|
@ -281,35 +276,6 @@ void OpenGLFrameBuffer::SetVSync(bool vsync)
|
|||
glBindFramebuffer(GL_READ_FRAMEBUFFER, oldReadFramebufferBinding);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// DoSetGamma
|
||||
//
|
||||
// (Unfortunately Windows has some safety precautions that block gamma ramps
|
||||
// that are considered too extreme. As a result this doesn't work flawlessly)
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void OpenGLFrameBuffer::SetGamma()
|
||||
{
|
||||
bool useHWGamma = m_supportsGamma && ((vid_hwgamma == 0) || (vid_hwgamma == 2 && IsFullscreen()));
|
||||
if (useHWGamma)
|
||||
{
|
||||
uint16_t gammaTable[768];
|
||||
|
||||
// This formula is taken from Doomsday
|
||||
BuildGammaTable(gammaTable);
|
||||
SetGammaTable(gammaTable);
|
||||
|
||||
HWGammaActive = true;
|
||||
}
|
||||
else if (HWGammaActive)
|
||||
{
|
||||
ResetGammaTable();
|
||||
HWGammaActive = false;
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
//
|
||||
|
@ -465,7 +431,9 @@ TArray<uint8_t> OpenGLFrameBuffer::GetScreenshotBuffer(int &pitch, ESSType &colo
|
|||
color_type = SS_RGB;
|
||||
|
||||
// Screenshot should not use gamma correction if it was already applied to rendered image
|
||||
gamma = 1 == vid_hwgamma || (2 == vid_hwgamma && !fullscreen) ? 1.0f : Gamma;
|
||||
gamma = 1;
|
||||
if (vid_hdr_active && fullscreen)
|
||||
gamma *= 2.2f;
|
||||
return ScreenshotBuffer;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,9 +24,6 @@ public:
|
|||
void InitializeState() override;
|
||||
void Update() override;
|
||||
|
||||
// Color correction
|
||||
void SetGamma();
|
||||
|
||||
void CleanForRestart() override;
|
||||
void UpdatePalette() override;
|
||||
uint32_t GetCaps() override;
|
||||
|
|
|
@ -97,7 +97,10 @@ unsigned int FHardwareTexture::CreateTexture(unsigned char * buffer, int w, int
|
|||
}
|
||||
*/
|
||||
bool firstCall = glTexID == 0;
|
||||
if (firstCall) glGenTextures(1,&glTexID);
|
||||
if (firstCall)
|
||||
{
|
||||
glGenTextures(1, &glTexID);
|
||||
}
|
||||
|
||||
int textureBinding = UINT_MAX;
|
||||
if (texunit == -1) glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding);
|
||||
|
@ -211,7 +214,8 @@ uint8_t *FHardwareTexture::MapBuffer()
|
|||
//===========================================================================
|
||||
FHardwareTexture::~FHardwareTexture()
|
||||
{
|
||||
glDeleteBuffers(1, &glBufferID);
|
||||
if (glTexID != 0) glDeleteTextures(1, &glTexID);
|
||||
if (glBufferID != 0) glDeleteBuffers(1, &glBufferID);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -207,9 +207,10 @@ void HU_GetPlayerWidths(int &maxnamewidth, int &maxscorewidth, int &maxiconheigh
|
|||
{
|
||||
maxnamewidth = width;
|
||||
}
|
||||
if (players[i].mo->ScoreIcon.isValid())
|
||||
auto icon = FSetTextureID(players[i].mo->IntVar(NAME_ScoreIcon));
|
||||
if (icon.isValid())
|
||||
{
|
||||
FTexture *pic = TexMan.GetTexture(players[i].mo->ScoreIcon);
|
||||
FTexture *pic = TexMan.GetTexture(icon);
|
||||
width = pic->GetDisplayWidth() - pic->GetDisplayLeftOffset() + 2;
|
||||
if (width > maxscorewidth)
|
||||
{
|
||||
|
@ -420,9 +421,10 @@ static void HU_DrawPlayer (player_t *player, bool highlight, int col1, int col2,
|
|||
screen->DrawText (SmallFont, color, col2, y + ypadding, player->playerstate == PST_DEAD && !deathmatch ? "DEAD" : str,
|
||||
DTA_CleanNoMove, true, TAG_DONE);
|
||||
|
||||
if (player->mo->ScoreIcon.isValid())
|
||||
auto icon = FSetTextureID(player->mo->IntVar(NAME_ScoreIcon));
|
||||
if (icon.isValid())
|
||||
{
|
||||
FTexture *pic = TexMan.GetTexture(player->mo->ScoreIcon);
|
||||
FTexture *pic = TexMan.GetTexture(icon);
|
||||
screen->DrawTexture (pic, col3, y,
|
||||
DTA_CleanNoMove, true,
|
||||
TAG_DONE);
|
||||
|
|
|
@ -47,7 +47,8 @@ public:
|
|||
IBuffer &operator=(const IBuffer &) = delete;
|
||||
virtual ~IBuffer() = default;
|
||||
|
||||
virtual void SetData(size_t size, void *data, bool staticdata = true) = 0;
|
||||
virtual void SetData(size_t size, const void *data, bool staticdata = true) = 0;
|
||||
virtual void SetSubData(size_t offset, size_t size, const void *data) = 0;
|
||||
virtual void *Lock(unsigned int size) = 0;
|
||||
virtual void Unlock() = 0;
|
||||
virtual void Resize(size_t newsize) = 0;
|
||||
|
|
|
@ -27,42 +27,49 @@
|
|||
namespace hwrenderer
|
||||
{
|
||||
|
||||
LevelAABBTree::LevelAABBTree()
|
||||
LevelAABBTree::LevelAABBTree(FLevelLocals *lev)
|
||||
{
|
||||
Level = lev;
|
||||
// Calculate the center of all lines
|
||||
TArray<FVector2> centroids;
|
||||
for (unsigned int i = 0; i < level.lines.Size(); i++)
|
||||
for (unsigned int i = 0; i < Level->lines.Size(); i++)
|
||||
{
|
||||
FVector2 v1 = { (float)level.lines[i].v1->fX(), (float)level.lines[i].v1->fY() };
|
||||
FVector2 v2 = { (float)level.lines[i].v2->fX(), (float)level.lines[i].v2->fY() };
|
||||
FVector2 v1 = { (float)Level->lines[i].v1->fX(), (float)Level->lines[i].v1->fY() };
|
||||
FVector2 v2 = { (float)Level->lines[i].v2->fX(), (float)Level->lines[i].v2->fY() };
|
||||
centroids.Push((v1 + v2) * 0.5f);
|
||||
}
|
||||
|
||||
// Create a list of level lines we want to add:
|
||||
TArray<int> line_elements;
|
||||
for (unsigned int i = 0; i < level.lines.Size(); i++)
|
||||
// Create the static subtree
|
||||
if (!GenerateTree(¢roids[0], false))
|
||||
return;
|
||||
|
||||
int staticroot = nodes.Size() - 1;
|
||||
|
||||
dynamicStartNode = nodes.Size();
|
||||
dynamicStartLine = treelines.Size();
|
||||
|
||||
// Create the dynamic subtree
|
||||
if (GenerateTree(¢roids[0], true))
|
||||
{
|
||||
if (!level.lines[i].backsector)
|
||||
{
|
||||
if (level.lines[i].sidedef[0] && (level.lines[i].sidedef[0]->Flags & WALLF_POLYOBJ))
|
||||
polylines.Push(i);
|
||||
line_elements.Push(i);
|
||||
}
|
||||
int dynamicroot = nodes.Size() - 1;
|
||||
|
||||
// Create a shared root node
|
||||
FVector2 aabb_min, aabb_max;
|
||||
const auto &left = nodes[staticroot];
|
||||
const auto &right = nodes[dynamicroot];
|
||||
aabb_min.X = MIN(left.aabb_left, right.aabb_left);
|
||||
aabb_min.Y = MIN(left.aabb_top, right.aabb_top);
|
||||
aabb_max.X = MAX(left.aabb_right, right.aabb_right);
|
||||
aabb_max.Y = MAX(left.aabb_bottom, right.aabb_bottom);
|
||||
nodes.Push({ aabb_min, aabb_max, staticroot, dynamicroot });
|
||||
}
|
||||
|
||||
// GenerateTreeNode needs a buffer where it can store line indices temporarily when sorting lines into the left and right child AABB buckets
|
||||
TArray<int> work_buffer;
|
||||
work_buffer.Resize(line_elements.Size() * 2);
|
||||
|
||||
// Generate the AABB tree
|
||||
GenerateTreeNode(&line_elements[0], (int)line_elements.Size(), ¢roids[0], &work_buffer[0]);
|
||||
|
||||
// Add the lines referenced by the leaf nodes
|
||||
lines.Resize(level.lines.Size());
|
||||
for (unsigned int i = 0; i < level.lines.Size(); i++)
|
||||
treelines.Resize(mapLines.Size());
|
||||
for (unsigned int i = 0; i < mapLines.Size(); i++)
|
||||
{
|
||||
const auto &line = level.lines[i];
|
||||
auto &treeline = lines[i];
|
||||
const auto &line = Level->lines[mapLines[i]];
|
||||
auto &treeline = treelines[i];
|
||||
|
||||
treeline.x = (float)line.v1->fX();
|
||||
treeline.y = (float)line.v1->fY();
|
||||
|
@ -71,13 +78,47 @@ LevelAABBTree::LevelAABBTree()
|
|||
}
|
||||
}
|
||||
|
||||
bool LevelAABBTree::GenerateTree(const FVector2 *centroids, bool dynamicsubtree)
|
||||
{
|
||||
// Create a list of level lines we want to add:
|
||||
TArray<int> line_elements;
|
||||
auto &maplines = Level->lines;
|
||||
for (unsigned int i = 0; i < maplines.Size(); i++)
|
||||
{
|
||||
if (!maplines[i].backsector)
|
||||
{
|
||||
bool isPolyLine = maplines[i].sidedef[0] && (maplines[i].sidedef[0]->Flags & WALLF_POLYOBJ);
|
||||
if (isPolyLine && dynamicsubtree)
|
||||
{
|
||||
line_elements.Push(mapLines.Size());
|
||||
mapLines.Push(i);
|
||||
}
|
||||
else if (!isPolyLine && !dynamicsubtree)
|
||||
{
|
||||
line_elements.Push(mapLines.Size());
|
||||
mapLines.Push(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (line_elements.Size() == 0)
|
||||
return false;
|
||||
|
||||
// GenerateTreeNode needs a buffer where it can store line indices temporarily when sorting lines into the left and right child AABB buckets
|
||||
TArray<int> work_buffer;
|
||||
work_buffer.Resize(line_elements.Size() * 2);
|
||||
|
||||
// Generate the AABB tree
|
||||
GenerateTreeNode(&line_elements[0], (int)line_elements.Size(), centroids, &work_buffer[0]);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LevelAABBTree::Update()
|
||||
{
|
||||
bool modified = false;
|
||||
for (unsigned int ii = 0; ii < polylines.Size(); ii++)
|
||||
for (unsigned int i = dynamicStartLine; i < mapLines.Size(); i++)
|
||||
{
|
||||
int i = polylines[ii];
|
||||
const auto &line = level.lines[i];
|
||||
const auto &line = Level->lines[mapLines[i]];
|
||||
|
||||
AABBTreeLine treeline;
|
||||
treeline.x = (float)line.v1->fX();
|
||||
|
@ -85,15 +126,15 @@ bool LevelAABBTree::Update()
|
|||
treeline.dx = (float)line.v2->fX() - treeline.x;
|
||||
treeline.dy = (float)line.v2->fY() - treeline.y;
|
||||
|
||||
if (memcmp(&lines[i], &treeline, sizeof(AABBTreeLine)))
|
||||
if (memcmp(&treelines[i], &treeline, sizeof(AABBTreeLine)))
|
||||
{
|
||||
TArray<int> path = FindNodePath(i, nodes.Size() - 1);
|
||||
if (path.Size())
|
||||
{
|
||||
float x1 = (float)level.lines[i].v1->fX();
|
||||
float y1 = (float)level.lines[i].v1->fY();
|
||||
float x2 = (float)level.lines[i].v2->fX();
|
||||
float y2 = (float)level.lines[i].v2->fY();
|
||||
float x1 = (float)line.v1->fX();
|
||||
float y1 = (float)line.v1->fY();
|
||||
float x2 = (float)line.v2->fX();
|
||||
float y2 = (float)line.v2->fY();
|
||||
|
||||
int nodeIndex = path[0];
|
||||
nodes[nodeIndex].aabb_left = MIN(x1, x2);
|
||||
|
@ -112,7 +153,7 @@ bool LevelAABBTree::Update()
|
|||
cur.aabb_bottom = MAX(left.aabb_bottom, right.aabb_bottom);
|
||||
}
|
||||
|
||||
lines[i] = treeline;
|
||||
treelines[i] = treeline;
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
|
@ -124,8 +165,8 @@ TArray<int> LevelAABBTree::FindNodePath(unsigned int line, unsigned int node)
|
|||
{
|
||||
const AABBTreeNode &n = nodes[node];
|
||||
|
||||
if (n.aabb_left > lines[line].x || n.aabb_right < lines[line].x ||
|
||||
n.aabb_top > lines[line].y || n.aabb_bottom < lines[line].y)
|
||||
if (n.aabb_left > treelines[line].x || n.aabb_right < treelines[line].x ||
|
||||
n.aabb_top > treelines[line].y || n.aabb_bottom < treelines[line].y)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
@ -140,7 +181,7 @@ TArray<int> LevelAABBTree::FindNodePath(unsigned int line, unsigned int node)
|
|||
if (path.Size())
|
||||
path.Push(node);
|
||||
}
|
||||
else if (n.line_index == line)
|
||||
else if (n.line_index == (int)line)
|
||||
{
|
||||
path.Push(node);
|
||||
}
|
||||
|
@ -160,7 +201,7 @@ double LevelAABBTree::RayTest(const DVector3 &ray_start, const DVector3 &ray_end
|
|||
double hit_fraction = 1.0;
|
||||
|
||||
// Walk the tree nodes
|
||||
int stack[16];
|
||||
int stack[32];
|
||||
int stack_pos = 1;
|
||||
stack[0] = nodes.Size() - 1; // root node is the last node in the list
|
||||
while (stack_pos > 0)
|
||||
|
@ -178,7 +219,7 @@ double LevelAABBTree::RayTest(const DVector3 &ray_start, const DVector3 &ray_end
|
|||
hit_fraction = MIN(IntersectRayLine(ray_start, ray_end, nodes[node_index].line_index, raydelta, rayd, raydist2), hit_fraction);
|
||||
stack_pos--;
|
||||
}
|
||||
else if (stack_pos == 16)
|
||||
else if (stack_pos == 32)
|
||||
{
|
||||
stack_pos--; // stack overflow - tree is too deep!
|
||||
}
|
||||
|
@ -234,7 +275,7 @@ double LevelAABBTree::IntersectRayLine(const DVector2 &ray_start, const DVector2
|
|||
// This algorithm is homemade - I would not be surprised if there's a much faster method out there.
|
||||
|
||||
const double epsilon = 0.0000001;
|
||||
const AABBTreeLine &line = lines[line_index];
|
||||
const AABBTreeLine &line = treelines[line_index];
|
||||
|
||||
DVector2 raynormal = DVector2(raydelta.Y, -raydelta.X);
|
||||
|
||||
|
@ -264,15 +305,16 @@ int LevelAABBTree::GenerateTreeNode(int *lines, int num_lines, const FVector2 *c
|
|||
// Find bounding box and median of the lines
|
||||
FVector2 median = FVector2(0.0f, 0.0f);
|
||||
FVector2 aabb_min, aabb_max;
|
||||
aabb_min.X = (float)level.lines[lines[0]].v1->fX();
|
||||
aabb_min.Y = (float)level.lines[lines[0]].v1->fY();
|
||||
auto &maplines = Level->lines;
|
||||
aabb_min.X = (float)maplines[mapLines[lines[0]]].v1->fX();
|
||||
aabb_min.Y = (float)maplines[mapLines[lines[0]]].v1->fY();
|
||||
aabb_max = aabb_min;
|
||||
for (int i = 0; i < num_lines; i++)
|
||||
{
|
||||
float x1 = (float)level.lines[lines[i]].v1->fX();
|
||||
float y1 = (float)level.lines[lines[i]].v1->fY();
|
||||
float x2 = (float)level.lines[lines[i]].v2->fX();
|
||||
float y2 = (float)level.lines[lines[i]].v2->fY();
|
||||
float x1 = (float)maplines[mapLines[lines[i]]].v1->fX();
|
||||
float y1 = (float)maplines[mapLines[lines[i]]].v1->fY();
|
||||
float x2 = (float)maplines[mapLines[lines[i]]].v2->fX();
|
||||
float y2 = (float)maplines[mapLines[lines[i]]].v2->fY();
|
||||
|
||||
aabb_min.X = MIN(aabb_min.X, x1);
|
||||
aabb_min.X = MIN(aabb_min.X, x2);
|
||||
|
@ -283,7 +325,7 @@ int LevelAABBTree::GenerateTreeNode(int *lines, int num_lines, const FVector2 *c
|
|||
aabb_max.Y = MAX(aabb_max.Y, y1);
|
||||
aabb_max.Y = MAX(aabb_max.Y, y2);
|
||||
|
||||
median += centroids[lines[i]];
|
||||
median += centroids[mapLines[lines[i]]];
|
||||
}
|
||||
median /= (float)num_lines;
|
||||
|
||||
|
@ -319,7 +361,7 @@ int LevelAABBTree::GenerateTreeNode(int *lines, int num_lines, const FVector2 *c
|
|||
{
|
||||
int line_index = lines[i];
|
||||
|
||||
float side = FVector3(centroids[lines[i]], 1.0f) | plane;
|
||||
float side = FVector3(centroids[mapLines[lines[i]]], 1.0f) | plane;
|
||||
if (side >= 0.0f)
|
||||
{
|
||||
work_buffer[left_count] = line_index;
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
#include "tarray.h"
|
||||
#include "vectors.h"
|
||||
|
||||
struct FLevelLocals;
|
||||
|
||||
namespace hwrenderer
|
||||
{
|
||||
|
||||
|
@ -35,25 +37,33 @@ struct AABBTreeLine
|
|||
float dx, dy;
|
||||
};
|
||||
|
||||
// Axis aligned bounding box tree used for ray testing lines.
|
||||
// Axis aligned bounding box tree used for ray testing treelines.
|
||||
class LevelAABBTree
|
||||
{
|
||||
public:
|
||||
// Constructs a tree for the current level
|
||||
LevelAABBTree();
|
||||
|
||||
// Nodes in the AABB tree. Last node is the root node.
|
||||
TArray<AABBTreeNode> nodes;
|
||||
|
||||
// Line segments for the leaf nodes in the tree.
|
||||
TArray<AABBTreeLine> lines;
|
||||
LevelAABBTree(FLevelLocals *lev);
|
||||
|
||||
// Shoot a ray from ray_start to ray_end and return the closest hit as a fractional value between 0 and 1. Returns 1 if no line was hit.
|
||||
double RayTest(const DVector3 &ray_start, const DVector3 &ray_end);
|
||||
|
||||
bool Update();
|
||||
|
||||
const void *Nodes() const { return nodes.Data(); }
|
||||
const void *Lines() const { return treelines.Data(); }
|
||||
size_t NodesSize() const { return nodes.Size() * sizeof(AABBTreeNode); }
|
||||
size_t LinesSize() const { return treelines.Size() * sizeof(AABBTreeLine); }
|
||||
|
||||
const void *DynamicNodes() const { return nodes.Data() + dynamicStartNode; }
|
||||
const void *DynamicLines() const { return treelines.Data() + dynamicStartLine; }
|
||||
size_t DynamicNodesSize() const { return (nodes.Size() - dynamicStartNode) * sizeof(AABBTreeNode); }
|
||||
size_t DynamicLinesSize() const { return (treelines.Size() - dynamicStartLine) * sizeof(AABBTreeLine); }
|
||||
size_t DynamicNodesOffset() const { return dynamicStartNode * sizeof(AABBTreeNode); }
|
||||
size_t DynamicLinesOffset() const { return dynamicStartLine * sizeof(AABBTreeLine); }
|
||||
|
||||
private:
|
||||
bool GenerateTree(const FVector2 *centroids, bool dynamicsubtree);
|
||||
|
||||
// Test if a ray overlaps an AABB node or not
|
||||
bool OverlapRayAABB(const DVector2 &ray_start2d, const DVector2 &ray_end2d, const AABBTreeNode &node);
|
||||
|
||||
|
@ -61,11 +71,21 @@ private:
|
|||
double IntersectRayLine(const DVector2 &ray_start, const DVector2 &ray_end, int line_index, const DVector2 &raydelta, double rayd, double raydist2);
|
||||
|
||||
// Generate a tree node and its children recursively
|
||||
int GenerateTreeNode(int *lines, int num_lines, const FVector2 *centroids, int *work_buffer);
|
||||
int GenerateTreeNode(int *treelines, int num_lines, const FVector2 *centroids, int *work_buffer);
|
||||
|
||||
TArray<int> FindNodePath(unsigned int line, unsigned int node);
|
||||
|
||||
TArray<int> polylines;
|
||||
// Nodes in the AABB tree. Last node is the root node.
|
||||
TArray<AABBTreeNode> nodes;
|
||||
|
||||
// Line segments for the leaf nodes in the tree.
|
||||
TArray<AABBTreeLine> treelines;
|
||||
|
||||
int dynamicStartNode = 0;
|
||||
int dynamicStartLine = 0;
|
||||
|
||||
TArray<int> mapLines;
|
||||
FLevelLocals *Level;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -42,14 +42,13 @@ thread_local FDynLightData lightdata;
|
|||
CVAR (Bool, gl_light_sprites, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
|
||||
CVAR (Bool, gl_light_particles, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
|
||||
|
||||
CVAR(Int, gl_attenuate, -1, 0); // This is mainly a debug option.
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Sets up the parameters to render one dynamic light onto one plane
|
||||
//
|
||||
//==========================================================================
|
||||
bool FDynLightData::GetLight(int group, Plane & p, ADynamicLight * light, bool checkside)
|
||||
bool FDynLightData::GetLight(int group, Plane & p, FDynamicLight * light, bool checkside)
|
||||
{
|
||||
DVector3 pos = light->PosRelative(group);
|
||||
float radius = (light->GetRadius());
|
||||
|
@ -72,7 +71,7 @@ bool FDynLightData::GetLight(int group, Plane & p, ADynamicLight * light, bool c
|
|||
// Add one dynamic light to the light data list
|
||||
//
|
||||
//==========================================================================
|
||||
void FDynLightData::AddLightToList(int group, ADynamicLight * light, bool forceAttenuate)
|
||||
void FDynLightData::AddLightToList(int group, FDynamicLight * light, bool forceAttenuate)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
|
@ -106,13 +105,9 @@ void FDynLightData::AddLightToList(int group, ADynamicLight * light, bool forceA
|
|||
}
|
||||
|
||||
float shadowIndex = light->mShadowmapIndex + 1.0f;
|
||||
bool attenuate;
|
||||
|
||||
// Store attenuate flag in the sign bit of the float.
|
||||
if (gl_attenuate == -1) attenuate = !!(light->lightflags & LF_ATTENUATE) || forceAttenuate;
|
||||
else attenuate = !!gl_attenuate;
|
||||
|
||||
if (attenuate) shadowIndex = -shadowIndex;
|
||||
if (light->IsAttenuated() || forceAttenuate) shadowIndex = -shadowIndex;
|
||||
|
||||
float lightType = 0.0f;
|
||||
float spotInnerAngle = 0.0f;
|
||||
|
@ -123,14 +118,15 @@ void FDynLightData::AddLightToList(int group, ADynamicLight * light, bool forceA
|
|||
if (light->IsSpot())
|
||||
{
|
||||
lightType = 1.0f;
|
||||
spotInnerAngle = (float)light->SpotInnerAngle.Cos();
|
||||
spotOuterAngle = (float)light->SpotOuterAngle.Cos();
|
||||
spotInnerAngle = (float)light->pSpotInnerAngle->Cos();
|
||||
spotOuterAngle = (float)light->pSpotOuterAngle->Cos();
|
||||
|
||||
DAngle negPitch = -light->Angles.Pitch;
|
||||
DAngle negPitch = -*light->pPitch;
|
||||
DAngle Angle = light->target->Angles.Yaw;
|
||||
double xzLen = negPitch.Cos();
|
||||
spotDirX = float(-light->Angles.Yaw.Cos() * xzLen);
|
||||
spotDirX = float(-Angle.Cos() * xzLen);
|
||||
spotDirY = float(-negPitch.Sin());
|
||||
spotDirZ = float(-light->Angles.Yaw.Sin() * xzLen);
|
||||
spotDirZ = float(-Angle.Sin() * xzLen);
|
||||
}
|
||||
|
||||
float *data = &arrays[i][arrays[i].Reserve(16)];
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue