Merge branch 'next' of https://git.magicalgirl.moe/STJr/SRB2.git into resend-gamestate

# Conflicts:
#	src/d_clisrv.c
#	src/d_clisrv.h
#	src/d_net.c
#	src/p_saveg.c
#	src/p_saveg.h
This commit is contained in:
Louis-Antoine 2020-08-13 13:53:10 +02:00
commit 9dd5c11322
256 changed files with 28584 additions and 31624 deletions

View file

@ -51,8 +51,8 @@ jobs:
- /var/cache/apt/archives
- checkout
- run:
name: Compile without network support and BLUA
command: make -C src LINUX=1 ERRORMODE=1 -k NONET=1 NO_LUA=1
name: Compile without network support
command: make -C src LINUX=1 ERRORMODE=1 -k NONET=1
- run:
name: wipe build
command: make -C src LINUX=1 cleandep

View file

@ -26,6 +26,7 @@ matrix:
- libgl1-mesa-dev
- libgme-dev
- libopenmpt-dev
- libcurl4-openssl-dev
- p7zip-full
- gcc-4.4
compiler: gcc-4.4
@ -43,6 +44,7 @@ matrix:
- libgl1-mesa-dev
- libgme-dev
- libopenmpt-dev
- libcurl4-openssl-dev
- p7zip-full
- gcc-4.6
compiler: gcc-4.6
@ -60,6 +62,7 @@ matrix:
- libgl1-mesa-dev
- libgme-dev
- libopenmpt-dev
- libcurl4-openssl-dev
- p7zip-full
- gcc-4.7
compiler: gcc-4.7
@ -83,6 +86,7 @@ matrix:
- libgl1-mesa-dev
- libgme-dev
- libopenmpt-dev
- libcurl4-openssl-dev
- p7zip-full
- gcc-4.8
compiler: gcc-4.8
@ -101,6 +105,7 @@ matrix:
- libgl1-mesa-dev
- libgme-dev
- libopenmpt-dev
- libcurl4-openssl-dev
- p7zip-full
- gcc-7
compiler: gcc-7
@ -119,6 +124,7 @@ matrix:
- libgl1-mesa-dev
- libgme-dev
- libopenmpt-dev
- libcurl4-openssl-dev
- p7zip-full
- gcc-8
compiler: gcc-8
@ -141,6 +147,7 @@ matrix:
- libgl1-mesa-dev
- libgme-dev
- libopenmpt-dev
- libcurl4-openssl-dev
- p7zip-full
- clang-3.5
compiler: clang-3.5
@ -159,6 +166,7 @@ matrix:
- libgl1-mesa-dev
- libgme-dev
- libopenmpt-dev
- libcurl4-openssl-dev
- p7zip-full
- clang-3.6
compiler: clang-3.6
@ -177,6 +185,7 @@ matrix:
- libgl1-mesa-dev
- libgme-dev
- libopenmpt-dev
- libcurl4-openssl-dev
- p7zip-full
- clang-3.7
compiler: clang-3.7
@ -195,6 +204,7 @@ matrix:
- libgl1-mesa-dev
- libgme-dev
- libopenmpt-dev
- libcurl4-openssl-dev
- p7zip-full
- clang-3.8
compiler: clang-3.8
@ -213,6 +223,7 @@ matrix:
- libgl1-mesa-dev
- libgme-dev
- libopenmpt-dev
- libcurl4-openssl-dev
- p7zip-full
- clang-3.9
compiler: clang-3.9
@ -323,6 +334,7 @@ matrix:
- libpng-dev
- libgl1-mesa-dev
- libgme-dev
- libcurl4-openssl-dev
- p7zip-full
- gcc-4.8
compiler: gcc-4.8
@ -468,6 +480,7 @@ matrix:
- libgl1-mesa-dev
- libgme-dev
- libopenmpt-dev
- libcurl4-openssl-dev
- p7zip-full
- gcc-4.8
compiler: gcc-4.8
@ -495,6 +508,7 @@ matrix:
- libgl1-mesa-dev
- libgme-dev
- libopenmpt-dev
- libcurl4-openssl-dev
- p7zip-full
- gcc-4.8
compiler: gcc-4.8
@ -522,6 +536,7 @@ matrix:
- libgl1-mesa-dev
- libgme-dev
- libopenmpt-dev
- libcurl4-openssl-dev
- p7zip-full
- gcc-4.8
compiler: gcc-4.8
@ -549,6 +564,7 @@ matrix:
- libgl1-mesa-dev
- libgme-dev
- libopenmpt-dev
- libcurl4-openssl-dev
- p7zip-full
- gcc-4.8
compiler: gcc-4.8
@ -576,6 +592,7 @@ matrix:
- libgl1-mesa-dev
- libgme-dev
- libopenmpt-dev
- libcurl4-openssl-dev
- p7zip-full
- gcc-4.8
compiler: gcc-4.8
@ -619,6 +636,7 @@ addons:
- libgme-dev
- zlib1g-dev
- libopenmpt-dev
- libcurl4-openssl-dev
- p7zip-full
homebrew:
taps:
@ -629,6 +647,7 @@ addons:
- p7zip
- libopenmpt
- cmake
- curl
update: true

View file

@ -1,14 +1,34 @@
cmake_minimum_required(VERSION 3.0)
# Enable CCache early
set(SRB2_USE_CCACHE OFF CACHE BOOL "Use CCache")
if (${SRB2_USE_CCACHE})
find_program(CCACHE_PROGRAM ccache)
if(CCACHE_PROGRAM)
message(STATUS "Found CCache: ${CCACHE_PROGRAM}")
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_PROGRAM}")
else()
message(WARNING "You have specified to use CCACHE but it was not found. Object files will not be cached.")
endif()
endif()
file(STRINGS src/version.h SRB2_VERSION)
string(REGEX MATCH "[0-9]+\\.[0-9.]+" SRB2_VERSION ${SRB2_VERSION})
# DO NOT CHANGE THIS SRB2 STRING! Some variable names depend on this string.
# Version change is fine.
project(SRB2
VERSION 2.2.2
VERSION ${SRB2_VERSION}
LANGUAGES C)
if(${PROJECT_SOURCE_DIR} MATCHES ${PROJECT_BINARY_DIR})
message(FATAL_ERROR "In-source builds will bring you a world of pain. Please make a separate directory to invoke CMake from.")
endif()
if ((${SRB2_USE_CCACHE}) AND (${CMAKE_C_COMPILER} MATCHES "clang"))
message(WARNING "Using clang and CCache: You may want to set environment variable CCACHE_CPP2=yes to prevent include errors during compile.")
endif()
# Set up CMAKE path
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
@ -113,16 +133,19 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/config.h.in ${CMAKE_CURRENT_BINAR
##### PACKAGE CONFIGURATION #####
if(${CMAKE_SYSTEM} MATCHES "Windows")
set(CPACK_GENERATOR "ZIP")
endif()
if(${CMAKE_SYSTEM} MATCHES "Linux")
set(CPACK_GENERATOR "TGZ")
endif()
if(${CMAKE_SYSTEM} MATCHES "Darwin")
set(CPACK_GENERATOR "DragNDrop")
set(SRB2_CPACK_GENERATOR "" CACHE STRING "Generator to use for making a package. E.g., ZIP, TGZ, DragNDrop (OSX only). Leave blank for default generator.")
if("${SRB2_CPACK_GENERATOR}" STREQUAL "")
if(${CMAKE_SYSTEM} MATCHES "Windows")
set(SRB2_CPACK_GENERATOR "ZIP")
elseif(${CMAKE_SYSTEM} MATCHES "Linux")
set(SRB2_CPACK_GENERATOR "TGZ")
elseif(${CMAKE_SYSTEM} MATCHES "Darwin")
set(SRB2_CPACK_GENERATOR "TGZ")
endif()
endif()
set(CPACK_GENERATOR ${SRB2_CPACK_GENERATOR})
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Sonic Robo Blast 2" CACHE STRING "Program name for display purposes")
set(CPACK_PACKAGE_VENDOR "Sonic Team Jr." CACHE STRING "Vendor name for display purposes")
#set(CPACK_PACKAGE_DESCRIPTION_FILE )
@ -131,4 +154,5 @@ set(CPACK_PACKAGE_VERSION_MAJOR ${SRB2_VERSION_MAJOR})
set(CPACK_PACKAGE_VERSION_MINOR ${SRB2_VERSION_MINOR})
set(CPACK_PACKAGE_VERSION_PATCH ${SRB2_VERSION_PATCH})
set(CPACK_PACKAGE_INSTALL_DIRECTORY "CMake ${CMAKE_VERSION_MAJOR}.${CMAKE_VERSION_MINOR}")
SET(CPACK_OUTPUT_FILE_PREFIX package)
include(CPack)

View file

@ -109,13 +109,10 @@ FILE_PATTERNS = *.c \
*.mm \
*.dox
RECURSIVE = YES
EXCLUDE = ./src/djgppdos/internal.h \
./src/djgppdos/setup.c \
./src/sdl/IMG_xpm.c \
EXCLUDE = ./src/sdl/IMG_xpm.c \
./src/sdl/SRB2DC/scramble.c
EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS = */src/hardware/*/* \
*/src/djgppdos/bcd.? \
*/src/sdl/SDL_main/* \
*/src/*/*_private.h \
*/src/sdl/*/*help.? \

View file

@ -1,4 +1,4 @@
version: 2.2.2.{branch}-{build}
version: 2.2.6.{branch}-{build}
os: MinGW
environment:
@ -110,8 +110,8 @@ after_build:
- set BUILDSARCHIVE=%REPO%-%CONFIGURATION%.7z
- cmd: 7z a %BUILD_ARCHIVE% %BUILD_PATH% -xr!.gitignore
- appveyor PushArtifact %BUILD_ARCHIVE%
- cmd: copy %BUILD_ARCHIVE% %BUILDSARCHIVE%
- appveyor PushArtifact %BUILDSARCHIVE%
#- cmd: copy %BUILD_ARCHIVE% %BUILDSARCHIVE%
#- appveyor PushArtifact %BUILDSARCHIVE%
##############################
# DEPLOYER SCRIPT
##############################

View file

@ -12,6 +12,9 @@ ENDFUNCTION(PREPEND)
set(SRB2_ASSET_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/installer"
CACHE STRING "Path to directory that contains all asset files for the installer.")
set(SRB2_ASSET_INSTALL ON
CACHE BOOL "Insert asset files into the install directory or package.")
####################
# POST-V2.2 NOTE: Do not forget to add patch.pk3 to the end of this list!
####################
@ -43,20 +46,27 @@ endforeach()
if(${CMAKE_SYSTEM} MATCHES Darwin)
get_target_property(outname SRB2SDL2 OUTPUT_NAME)
install(DIRECTORY "${SRB2_ASSET_DIRECTORY}/"
DESTINATION "${outname}.app/Contents/Resources"
)
if(${SRB2_ASSET_INSTALL})
install(DIRECTORY "${SRB2_ASSET_DIRECTORY}/"
DESTINATION "${outname}.app/Contents/Resources"
)
endif()
# Always install the doc files, even in non-asset packages.
install(FILES ${SRB2_ASSET_DOCS}
DESTINATION .
OPTIONAL
)
else()
install(DIRECTORY "${SRB2_ASSET_DIRECTORY}/"
DESTINATION .
)
# Docs are assumed to be located in SRB2_ASSET_DIRECTORY, so don't install again
#install(FILES ${SRB2_ASSET_DOCS}
# DESTINATION .
# OPTIONAL
#)
if(${SRB2_ASSET_INSTALL})
install(DIRECTORY "${SRB2_ASSET_DIRECTORY}/"
DESTINATION .
)
# Docs are assumed to be located in SRB2_ASSET_DIRECTORY, so don't install them in their own call.
else()
# Always install the doc files, even in non-asset packages.
install(FILES ${SRB2_ASSET_DOCS}
DESTINATION .
OPTIONAL
)
endif()
endif()

View file

@ -1,2 +0,0 @@
# DON'T REMOVE
# This keeps the folder from disappearing

View file

@ -1,2 +0,0 @@
# DON'T REMOVE
# This keeps the folder from disappearing

3
cmake/launch-c.in Normal file
View file

@ -0,0 +1,3 @@
#!/bin/sh
export CCACHE_CPP2=true
exec "${RULE_LAUNCH_COMPILE}" "${CMAKE_C_COMPILER}" "$@"

3
cmake/launch-cxx.in Normal file
View file

@ -0,0 +1,3 @@
#!/bin/sh
export CCACHE_CPP2=true
exec "${RULE_LAUNCH_COMPILE}" "${CMAKE_C_COMPILER}" "$@"

View file

@ -11,6 +11,7 @@ Build-Depends: debhelper (>= 7.0.50~),
zlib1g-dev,
libgme-dev,
libopenmpt-dev,
libcurl4-openssl-dev,
libglu1-dev | libglu-dev,
libosmesa6-dev | libgl-dev,
nasm [i386]

File diff suppressed because it is too large Load diff

View file

@ -15,7 +15,7 @@
* Oogaland
* Rob
* Shadow Hog
* Spherallic
* sphere
* SRB2-Playah
* SSNTails
* SteelT
@ -435,7 +435,7 @@ sectortypes
112 = "Trigger Line Ex. (NiGHTS Mare)";
128 = "Check for Linedef Executor on FOFs";
144 = "Egg Capsule";
160 = "Special Stage Time/Rings Parameters";
160 = "Special Stage Time/Spheres Parameters";
176 = "Custom Global Gravity";
512 = "Wind/Current";
1024 = "Conveyor Belt";
@ -490,7 +490,7 @@ gen_sectortypes
112 = "Trigger Line Ex. (NiGHTS Mare)";
128 = "Check for Linedef Executor on FOFs";
144 = "Egg Capsule";
160 = "Special Stage Time/Rings Parameters";
160 = "Special Stage Time/Spheres Parameters";
176 = "Custom Global Gravity";
}
@ -738,12 +738,6 @@ linedeftypes
flags2text = "[1] Use control sector tag";
flags64text = "[6] No sound effect";
}
65
{
title = "Bridge Thinker <disabled>";
prefix = "(65)";
}
}
polyobject
@ -756,20 +750,17 @@ linedeftypes
prefix = "(20)";
}
21
{
title = "Explicitly Include Line <disabled>";
prefix = "(21)";
}
22
{
title = "Parameters";
prefix = "(22)";
flags8text = "[3] Set translucency by X offset";
flags32text = "[5] Render outer sides only";
flags64text = "[6] Trigger linedef executor";
flags128text = "[7] Intangible";
flags256text = "[8] Stopped by pushables";
flags512text = "[9] Render flats";
flags8192text = "[13] Cut cyan flat pixels";
}
30
@ -788,7 +779,6 @@ linedeftypes
{
title = "Angular Displacement by Front Sector";
prefix = "(32)";
flags8text = "[3] Set delay by backside sector";
flags64text = "[6] Don't turn players";
flags512text = "[9] Turn all objects";
}
@ -925,6 +915,7 @@ linedeftypes
flags32text = "[5] Only block player";
flags64text = "[6] Render insides";
flags128text = "[7] Only block non-players";
flags8192text = "[13] Cut cyan flat pixels";
3dfloor = true;
3dfloorflags = "195F";
flags643dfloorflagsadd = "7C80";
@ -984,6 +975,7 @@ linedeftypes
flags32text = "[5] Only block player";
flags64text = "[6] Don't cast shadow";
flags128text = "[7] Render insides/block non-plr";
flags8192text = "[13] Cut cyan flat pixels";
3dfloor = true;
3dfloorflags = "200191F";
flags1283dfloorflagsadd = "7C80";
@ -997,6 +989,7 @@ linedeftypes
flags32text = "[5] Only block player";
flags64text = "[6] Don't cast shadow";
flags128text = "[7] Render insides/block non-plr";
flags8192text = "[13] Cut cyan flat pixels";
3dfloor = true;
3dfloorflags = "2001917";
flags1283dfloorflagsadd = "7C80";
@ -1024,6 +1017,7 @@ linedeftypes
flags32text = "[5] Only block player";
flags64text = "[6] Don't cast shadow";
flags128text = "[7] Render insides/block non-plr";
flags8192text = "[13] Cut cyan flat pixels";
3dfloor = true;
3dfloorflags = "400191F";
flags1283dfloorflagsadd = "7C80";
@ -1037,6 +1031,7 @@ linedeftypes
flags32text = "[5] Only block player";
flags64text = "[6] Don't cast shadow";
flags128text = "[7] Render insides/block non-plr";
flags8192text = "[13] Cut cyan flat pixels";
3dfloor = true;
3dfloorflags = "4001917";
flags1283dfloorflagsadd = "7C80";
@ -1082,6 +1077,7 @@ linedeftypes
flags64text = "[6] Use two light levels";
flags512text = "[9] Use target light level";
flags1024text = "[10] Ripple effect";
flags8192text = "[13] Cut cyan flat pixels";
3dfloor = true;
3dfloorflags = "9F39";
flags643dfloorflagsadd = "20000";
@ -1110,6 +1106,7 @@ linedeftypes
flags64text = "[6] Use two light levels";
flags512text = "[9] Use target light level";
flags1024text = "[10] Ripple effect";
flags8192text = "[13] Cut cyan flat pixels";
3dfloor = true;
3dfloorflags = "1F31";
flags643dfloorflagsadd = "20000";
@ -1125,6 +1122,7 @@ linedeftypes
flags64text = "[6] Use two light levels";
flags512text = "[9] Use target light level";
flags1024text = "[10] Ripple effect";
flags8192text = "[13] Cut cyan flat pixels";
3dfloor = true;
3dfloorflags = "209F39";
flags643dfloorflagsadd = "20000";
@ -1136,10 +1134,10 @@ linedeftypes
{
title = "Goo Water, Translucent, No Sides";
prefix = "(125)";
flags8text = "[3] Slope skew sides";
flags64text = "[6] Use two light levels";
flags512text = "[9] Use target light level";
flags1024text = "[10] Ripple effect";
flags8192text = "[13] Cut cyan flat pixels";
3dfloor = true;
3dfloorflags = "201F31";
flags643dfloorflagsadd = "20000";
@ -1162,6 +1160,7 @@ linedeftypes
prefix = "(221)";
flags8text = "[3] Slope skew sides";
flags64text = "[6] Cast shadow";
flags8192text = "[13] Cut cyan flat pixels";
3dfloor = true;
3dfloorflags = "1B59";
flags643dfloorflagsremove = "40";
@ -1227,6 +1226,18 @@ linedeftypes
3dfloorflags = "19F";
}
153
{
title = "Dynamically Sinking Platform";
prefix = "(153)";
flags8text = "[3] Slope skew sides";
flags32text = "[5] Only block player";
flags64text = "[6] Spindash to move";
flags128text = "[7] Only block non-players";
3dfloor = true;
3dfloorflags = "19F";
}
160
{
title = "Floating, Bobbing";
@ -1273,6 +1284,7 @@ linedeftypes
flags32text = "[5] Only block player";
flags64text = "[6] Spindash to move";
flags128text = "[7] Only block non-players";
flags8192text = "[13] Cut cyan flat pixels";
3dfloor = true;
3dfloorflags = "195F";
}
@ -1282,7 +1294,6 @@ linedeftypes
title = "Rising Platform, Solid, Invisible";
prefix = "(193)";
flags2text = "[1] Sink when stepped on";
flags8text = "[3] Slope skew sides";
flags32text = "[5] Only block player";
flags64text = "[6] Spindash to move";
flags128text = "[7] Only block non-players";
@ -1313,6 +1324,7 @@ linedeftypes
flags32text = "[5] Only block player";
flags64text = "[6] Spindash, no shadow";
flags128text = "[7] Only block non-players";
flags8192text = "[13] Cut cyan flat pixels";
3dfloor = true;
3dfloorflags = "2009D1F";
flags643dfloorflagsadd = "40";
@ -1379,6 +1391,7 @@ linedeftypes
flags32text = "[5] Only block player";
flags64text = "[6] Don't cast shadow";
flags128text = "[7] Only block non-players";
flags8192text = "[13] Cut cyan flat pixels";
3dfloor = true;
3dfloorflags = "210959F";
flags643dfloorflagsadd = "40";
@ -1392,6 +1405,7 @@ linedeftypes
flags32text = "[5] Only block player";
flags64text = "[6] Don't cast shadow";
flags128text = "[7] Only block non-players";
flags8192text = "[13] Cut cyan flat pixels";
3dfloor = true;
3dfloorflags = "218959F";
flags643dfloorflagsadd = "40";
@ -1488,16 +1502,22 @@ linedeftypes
{
title = "Mario Block";
prefix = "(250)";
flags8text = "[3] Slope skew sides";
flags32text = "[5] Invisible block";
flags64text = "[6] Brick block";
3dfloor = true;
3dfloorflags = "40019F";
flags323dfloorflagsremove = "19E";
flags643dfloorflagsadd = "200000";
}
251
{
title = "Thwomp Block";
prefix = "(251)";
flags8text = "[3] Slope skew sides";
flags32text = "[5] Only block player";
flags128text = "[7] Only block non-players";
flags512text = "[9] Custom crushing sound";
flags1024text = "[10] Custom speed";
3dfloor = true;
@ -1513,8 +1533,8 @@ linedeftypes
flags512text = "[9] Shattered by pushables";
flags1024text = "[10] Trigger linedef executor";
3dfloor = true;
3dfloorflags = "8800019";
flags643dfloorflagsadd = "200006";
3dfloorflags = "880001D";
flags643dfloorflagsadd = "200002";
}
253
@ -1524,8 +1544,9 @@ linedeftypes
flags8text = "[3] Slope skew sides";
flags512text = "[9] Shattered by pushables";
flags1024text = "[10] Trigger linedef executor";
flags8192text = "[13] Cut cyan flat pixels";
3dfloor = true;
3dfloorflags = "8801019";
3dfloorflags = "880101D";
}
254
@ -1533,6 +1554,7 @@ linedeftypes
title = "Bustable Block";
prefix = "(254)";
flags8text = "[3] Slope skew sides";
flags32text = "[5] Only block player";
flags64text = "[6] Strong characters only";
flags128text = "[7] Only block non-players";
flags512text = "[9] Shattered by pushables";
@ -1564,6 +1586,7 @@ linedeftypes
flags128text = "[7] Only block non-players";
flags512text = "[9] Shattered by pushables";
flags1024text = "[10] Trigger linedef executor";
flags8192text = "[13] Cut cyan flat pixels";
3dfloor = true;
3dfloorflags = "1080101F";
}
@ -1585,6 +1608,7 @@ linedeftypes
prefix = "(258)";
flags8text = "[3] Slope skew sides";
flags32text = "[5] Don't damage bosses";
flags8192text = "[13] Cut cyan flat pixels";
3dfloor = true;
3dfloorflags = "959";
}
@ -1593,10 +1617,12 @@ linedeftypes
{
title = "Custom FOF";
prefix = "(259)";
flags8text = "[3] Slope skew sides";
flags32text = "[5] Only block player";
flags128text = "[7] Only block non-players";
flags512text = "[9] Shattered by pushables";
flags1024text = "[10] Trigger linedef executor";
flags8192text = "[13] Cut cyan flat pixels";
3dfloor = true;
3dfloorcustom = true;
}
@ -1896,6 +1922,27 @@ linedeftypes
prefix = "(333)";
}
334
{
title = "Object Dye - Continuous";
flags64text = "[6] Disable for this color";
prefix = "(334)";
}
335
{
title = "Object Dye - Each Time";
flags64text = "[6] Disable for this color";
prefix = "(335)";
}
336
{
title = "Object Dye - Once";
flags64text = "[6] Disable for this color";
prefix = "(336)";
}
399
{
title = "Level Load";
@ -2161,6 +2208,14 @@ linedeftypes
flags8text = "[3] Set delay by backside sector";
}
449
{
title = "Enable Bosses with Parameter";
prefix = "(449)";
flags8text = "[3] Set delay by backside sector";
flags64text = "[6] Disable bosses";
}
457
{
title = "Track Object's Angle";
@ -2180,12 +2235,15 @@ linedeftypes
{
title = "Award Rings";
prefix = "(460)";
flags8text = "[3] Set delay by backside sector";
}
461
{
title = "Spawn Object";
prefix = "(461)";
flags8text = "[3] Set delay by backside sector";
flags32text = "[5] Use line angle for object";
flags64text = "[6] Spawn inside a range";
}
@ -2193,6 +2251,20 @@ linedeftypes
{
title = "Stop Timer/Exit Stage in Record Attack";
prefix = "(462)";
flags8text = "[3] Set delay by backside sector";
}
463
{
title = "Dye Object";
prefix = "(463)";
}
464
{
title = "Trigger Egg Capsule";
prefix = "(464)";
flags64text = "[6] Don't end level";
}
}
@ -2206,7 +2278,7 @@ linedeftypes
prefix = "(413)";
flags2text = "[1] Keep after death";
flags8text = "[3] Set delay by backside sector";
flags32text = "[5] Seek to current song position";
flags32text = "[5] Seek from current position";
flags64text = "[6] For everyone";
flags128text = "[7] Fade to custom volume";
flags512text = "[9] Don't loop";
@ -2220,7 +2292,7 @@ linedeftypes
flags2text = "[1] From calling sector";
flags8text = "[3] Set delay by backside sector";
flags64text = "[6] From nowhere for triggerer";
flags512text = "[9] For everyone";
flags512text = "[9] From nowhere for everyone";
flags1024text = "[10] From tagged sectors";
}
@ -2298,7 +2370,6 @@ linedeftypes
flags8text = "[3] Set delay by backside sector";
}
445
{
title = "Make FOF Disappear/Reappear";
@ -2325,8 +2396,8 @@ linedeftypes
flags32text = "[5] Subtract Red value";
flags64text = "[6] Subtract Green value";
flags128text = "[7] Subtract Blue value";
flags256text = "[8] Calc relative values";
flags32768text = "[15] Use back side colormap";
flags256text = "[8] Set relative to current";
flags32768text = "[15] Use backside colormap";
}
448
@ -2359,7 +2430,7 @@ linedeftypes
prefix = "(452)";
flags8text = "[3] Set delay by backside sector";
flags64text = "[6] Do not handle FF_TRANS";
flags256text = "[8] Set relative to current val";
flags256text = "[8] Set relative to current";
}
453
@ -2371,7 +2442,7 @@ linedeftypes
flags32text = "[5] No collision during fade";
flags64text = "[6] Do not handle FF_TRANS";
flags128text = "[7] Do not handle lighting";
flags256text = "[8] Set relative to current val";
flags256text = "[8] Set relative to current";
flags512text = "[9] Speed = Tic Duration";
flags1024text = "[10] Override existing fade";
flags16384text = "[14] Do not handle collision";
@ -2395,11 +2466,11 @@ linedeftypes
flags32text = "[5] Subtract Red value";
flags64text = "[6] Subtract Green value";
flags128text = "[7] Subtract Blue value";
flags256text = "[8] Calc relative values";
flags256text = "[8] Set relative to current";
flags512text = "[9] Speed = Tic Duration";
flags1024text = "[10] Override existing fade";
flags16384text = "[14] Fade from invisible black";
flags32768text = "[15] Use back side colormap";
flags32768text = "[15] Use backside colormap";
}
456
@ -2416,9 +2487,7 @@ linedeftypes
flags2text = "[1] Close text prompt";
flags8text = "[3] Set delay by backside sector";
flags32text = "[5] Run executor tag on close";
flags64text = "[6] For everyone";
flags128text = "[7] Do not block controls";
flags256text = "[8] Do not freeze time";
flags128text = "[7] Don't disable controls";
flags32768text = "[15] Find prompt by name";
}
}
@ -2524,7 +2593,7 @@ linedeftypes
prefix = "(491)";
flags8text = "[3] Set delay by backside sector";
flags16text = "[4] Set raw alpha by Front X";
flags256text = "[8] Calc relative values";
flags256text = "[8] Set relative to current";
}
492
@ -2534,7 +2603,7 @@ linedeftypes
flags8text = "[3] Set delay by backside sector";
flags16text = "[4] Set raw alpha by Front X";
flags32text = "[5] No collision during fade";
flags256text = "[8] Calc relative values";
flags256text = "[8] Set relative to current";
flags512text = "[9] Speed = Tic Duration";
flags1024text = "[10] Override existing fade";
flags16384text = "[14] Do not handle collision";
@ -2547,45 +2616,63 @@ linedeftypes
500
{
title = "Scroll Wall Front Side Left";
title = "Scroll Front Wall Left";
prefix = "(500)";
}
501
{
title = "Scroll Wall Front Side Right";
title = "Scroll Front Wall Right";
prefix = "(501)";
}
502
{
title = "Scroll Wall According to Linedef";
title = "Scroll Tagged Wall";
prefix = "(502)";
flags128text = "[7] Use texture offsets";
flags256text = "[8] Scroll back side";
}
503
{
title = "Scroll Wall According to Linedef (Accelerative)";
title = "Scroll Tagged Wall (Accelerative)";
prefix = "(503)";
flags128text = "[7] Use texture offsets";
flags256text = "[8] Scroll back side";
}
504
{
title = "Scroll Wall According to Linedef (Displacement)";
title = "Scroll Tagged Wall (Displacement)";
prefix = "(504)";
flags128text = "[7] Use texture offsets";
flags256text = "[8] Scroll back side";
}
505
{
title = "Scroll Texture by Front Side Offsets";
title = "Scroll Front Wall by Front Side Offsets";
prefix = "(505)";
}
506
{
title = "Scroll Texture by Back Side Offsets";
title = "Scroll Front Wall by Back Side Offsets";
prefix = "(506)";
}
507
{
title = "Scroll Back Wall by Front Side Offsets";
prefix = "(507)";
}
508
{
title = "Scroll Back Wall by Back Side Offsets";
prefix = "(508)";
}
}
planescroll
@ -2632,76 +2719,84 @@ linedeftypes
{
title = "Carry Objects on Floor";
prefix = "(520)";
flags64text = "[6] Exclusive";
}
521
{
title = "Carry Objects on Floor (Accelerative)";
prefix = "(521)";
flags64text = "[6] Even across edges";
flags64text = "[6] Exclusive";
}
522
{
title = "Carry Objects on Floor (Displacement)";
prefix = "(522)";
flags64text = "[6] Exclusive";
}
523
{
title = "Carry Objects on Ceiling";
prefix = "(523)";
flags64text = "[6] Even across edges";
flags64text = "[6] Exclusive";
}
524
{
title = "Carry Objects on Ceiling (Accelerative)";
prefix = "(524)";
flags64text = "[6] Exclusive";
}
525
{
title = "Carry Objects on Ceiling (Displacement)";
prefix = "(525)";
flags64text = "[6] Exclusive";
}
530
{
title = "Scroll Floor Texture and Carry Objects";
prefix = "(530)";
flags64text = "[6] Even across edges";
flags64text = "[6] Exclusive";
}
531
{
title = "Scroll Floor Texture and Carry Objects (Accelerative)";
prefix = "(531)";
flags64text = "[6] Exclusive";
}
532
{
title = "Scroll Floor Texture and Carry Objects (Displacement)";
prefix = "(532)";
flags64text = "[6] Exclusive";
}
533
{
title = "Scroll Ceiling Texture and Carry Objects";
prefix = "(533)";
flags64text = "[6] Even across edges";
flags64text = "[6] Exclusive";
}
534
{
title = "Scroll Ceiling Texture and Carry Objects (Accelerative)";
prefix = "(534)";
flags64text = "[6] Exclusive";
}
535
{
title = "Scroll Ceiling Texture and Carry Objects (Displacement)";
prefix = "(535)";
flags64text = "[6] Exclusive";
}
}
@ -2714,7 +2809,7 @@ linedeftypes
title = "Wind";
prefix = "(541)";
flags512text = "[9] Player slides";
flags64text = "[6] Even across edges";
flags64text = "[6] Exclusive";
}
542
@ -2722,7 +2817,7 @@ linedeftypes
title = "Upwards Wind";
prefix = "(542)";
flags512text = "[9] Player slides";
flags64text = "[6] Even across edges";
flags64text = "[6] Exclusive";
}
543
@ -2730,7 +2825,7 @@ linedeftypes
title = "Downwards Wind";
prefix = "(543)";
flags512text = "[9] Player slides";
flags64text = "[6] Even across edges";
flags64text = "[6] Exclusive";
}
544
@ -2738,7 +2833,7 @@ linedeftypes
title = "Current";
prefix = "(544)";
flags512text = "[9] Player slides";
flags64text = "[6] Even across edges";
flags64text = "[6] Exclusive";
}
545
@ -2746,7 +2841,7 @@ linedeftypes
title = "Upwards Current";
prefix = "(545)";
flags512text = "[9] Player slides";
flags64text = "[6] Even across edges";
flags64text = "[6] Exclusive";
}
546
@ -2754,13 +2849,14 @@ linedeftypes
title = "Downwards Current";
prefix = "(546)";
flags512text = "[9] Player slides";
flags64text = "[6] Even across edges";
flags64text = "[6] Exclusive";
}
547
{
title = "Push/Pull";
prefix = "(547)";
flags64text = "[6] Exclusive";
}
}
@ -3407,8 +3503,8 @@ thingtypes
sprite = "ESHIA1";
width = 16;
height = 48;
flags1text = "[1] 90 degrees counter-clockwise";
flags4text = "[4] 90 degrees clockwise";
flags1text = "[1] 90 degrees clockwise";
flags4text = "[4] 90 degrees counter-clockwise";
flags8text = "[8] Double speed";
}
115
@ -3674,6 +3770,7 @@ thingtypes
width = 8;
height = 16;
sprite = "internal:capsule";
angletext = "Tag";
}
292
{
@ -3870,6 +3967,8 @@ thingtypes
{
title = "Emerald Hunt Location";
sprite = "SHRDA0";
flags8height = 24;
flags8text = "[8] Float";
}
321
{
@ -3897,9 +3996,10 @@ thingtypes
title = "Monitors";
width = 18;
height = 40;
flags1text = "[1] Run Linedef Executor on pop";
flags1text = "[1] Run linedef executor on pop";
flags4text = "[4] Random (Strong)";
flags8text = "[8] Random (Weak)";
angletext = "Tag";
400
{
@ -4029,7 +4129,8 @@ thingtypes
title = "Monitors (Respawning)";
width = 20;
height = 44;
flags1text = "[1] Run Linedef Executor on pop";
flags1text = "[1] Run linedef executor on pop";
angletext = "Tag";
431
{
@ -4125,7 +4226,9 @@ thingtypes
sprite = "STPTA0M0";
width = 64;
height = 128;
flags4text = "[4] Respawn at center";
angletext = "Angle/Order";
parametertext = "Order";
}
520
{
@ -4152,6 +4255,7 @@ thingtypes
sprite = "WSPKALAR";
width = 16;
height = 14;
arrow = 1;
flags1text = "[1] Start retracted";
flags4text = "[4] Retractable";
flags8text = "[8] Intangible";
@ -4558,6 +4662,7 @@ thingtypes
sprite = "TOADA0";
width = 32;
height = 16;
angletext = "Tag";
}
757
{
@ -5832,7 +5937,7 @@ thingtypes
sprite = "CAPSA0";
width = 72;
height = 144;
angletext = "Rings";
angletext = "Spheres";
parametertext = "Mare";
}
}
@ -6273,7 +6378,7 @@ thingtypes
sprite = "PUMKA0";
width = 16;
height = 40;
flags1text = "Don't flicker";
flags1text = "[1] Don't flicker";
}
2007
{
@ -6281,7 +6386,7 @@ thingtypes
sprite = "PUMKB0";
width = 16;
height = 40;
flags1text = "Don't flicker";
flags1text = "[1] Don't flicker";
}
2008
{
@ -6289,7 +6394,7 @@ thingtypes
sprite = "PUMKC0";
width = 16;
height = 40;
flags1text = "Don't flicker";
flags1text = "[1] Don't flicker";
}
2009
{

View file

@ -1,7 +1,7 @@
// Default lump name for new map
defaultlumpname = "MAP01";
//GZDB specific. Don't try to load lumps that don't exist.
basegame = 0;
basegame = "Doom";
//Sky textures for vanilla maps
defaultskytextures

View file

@ -1,24 +1,40 @@
common
{
// Some common settings
// Simulate Doom brightness levels (turn this off for linear lighting)
doomlightlevels = true;
// Enables support for long (> 8 chars) texture names
// WARNING: this should only be enabled for UDMF game configurations!
// WARNING: enabling this will make maps incompatible with Doom Builder 2 and can lead to problems in Slade 3!
longtexturenames = false;
// These directory names are ignored when loading PK3/PK7/Directory resources
ignoreddirectories = ".svn .git";
// Files with these extensions are ignored when loading PK3/PK7/Directory resources
ignoredextensions = "wad pk3 pk7 bak backup1 backup2 backup3 zip rar 7z";
// Default testing parameters
testparameters = "-file \"%AP\" \"%F\" -warp %L";
testshortpaths = true;
// Action special help (mxd)
// Action special help
actionspecialhelp = "https://wiki.srb2.org/wiki/Linedef_type_%K";
// Default nodebuilder configurations
defaultsavecompiler = "zennode_normal";
defaulttestcompiler = "zennode_fast";
// Generalized actions
generalizedlinedefs = false;
generalizedsectors = true;
// Maximum safe map size check (0 means skip check)
safeboundary = 1;
// Map boundaries. Map objects can only be placed within these boundaries
leftboundary = -32768;
rightboundary = 32767;
topboundary = 32767;
bottomboundary = -32768;
// Texture loading options
mixtexturesflats = true;
defaulttexturescale = 1.0f;
defaultflatscale = 1.0f;
@ -54,8 +70,12 @@ common
mapformat_doom
{
// The format interface handles the map data format - DoomMapSetIO for SRB2DB2, SRB2MapSetIO for Zone Builder
formatinterface = "SRB2MapSetIO";
// The format interface handles the map data format
formatinterface = "DoomMapSetIO";
// Default nodebuilder configurations
defaultsavecompiler = "zennode_normal";
defaulttestcompiler = "zennode_fast";
/*
GAME DETECT PATTERN
@ -104,7 +124,7 @@ mapformat_doom
// Special linedefs
include("SRB222_misc.cfg", "speciallinedefs");
// Default flags for first new thing (As far as 2.2 goes, they're empty just like in 2.1)
// Default flags for first new thing
defaultthingflags
{
}
@ -115,13 +135,13 @@ mapformat_doom
include("SRB222_misc.cfg", "sectorbrightness");
}
// SECTOR TYPES-----------------------------------------------------------------
// SECTOR TYPES
sectortypes
{
include("SRB222_sectors.cfg", "sectortypes");
}
// GENERALISED SECTOR TYPES-----------------------------------------------------------------
// GENERALISED SECTOR TYPES
gen_sectortypes
{
include("SRB222_sectors.cfg", "gen_sectortypes");
@ -178,16 +198,12 @@ mapformat_udmf
// The format interface handles the map data format
formatinterface = "UniversalMapSetIO";
// Enables support for long (> 8 chars) texture names
// WARNING: this should only be enabled for UDMF game configurations!
// WARNING: enabling this will make maps incompatible with Doom Builder 2 and can lead to problems in Slade 3!
longtexturenames = false;
// Default nodebuilder configurations
defaultsavecompiler = "zdbsp_udmf_normal";
defaulttestcompiler = "zdbsp_udmf_fast";
engine = "srb2"; // override that so that DB2 uses the correct namespace
// Determines the textmap namespace
engine = "srb2";
maplumpnames
{
@ -198,7 +214,7 @@ mapformat_udmf
universalfields
{
// include("SRB222_misc.cfg", "universalfields");
include("SRB222_misc.cfg", "universalfields");
}
// When this is set to true, sectors with the same tag will light up when a line is highlighted
@ -207,18 +223,15 @@ mapformat_udmf
// Special linedefs
include("SRB222_misc.cfg", "speciallinedefs_udmf");
// Default flags for first new thing (As far as 2.2 goes, they're empty just like in 2.1)
// Default flags for first new thing
defaultthingflags
{
}
// Generalized actions
generalizedlinedefs = false;
// SECTOR FLAGS
sectorflags
{
// include("SRB222_misc.cfg", "sectorflags");
include("SRB222_misc.cfg", "sectorflags");
}
// DEFAULT SECTOR BRIGHTNESS LEVELS
@ -233,11 +246,11 @@ mapformat_udmf
include("SRB222_sectors.cfg", "sectortypes");
}
// SECTOR RENSERSTYLES
/* sectorrenderstyles
// GENERALISED SECTOR TYPES
gen_sectortypes
{
include("SRB222_misc.cfg", "sectorrenderstyles");
}*/
include("SRB222_sectors.cfg", "gen_sectortypes");
}
// LINEDEF FLAGS
linedefflags
@ -245,27 +258,15 @@ mapformat_udmf
include("SRB222_misc.cfg", "linedefflags_udmf");
}
// LINEDEF ACTIVATIONS
linedefactivations
{
include("SRB222_misc.cfg", "linedefactivations_udmf");
}
linedefflagstranslation
{
include("SRB222_misc.cfg", "linedefflagstranslation");
}
// LINEDEF RENSERSTYLES
linedefrenderstyles
// LINEDEF RENDERSTYLES
/*linedefrenderstyles
{
include("SRB222_misc.cfg", "linedefrenderstyles");
}
//SIDEDEF FLAGS
/* sidedefflags
{
include("UDMF_misc.cfg", "sidedefflags");
}*/
// THING FLAGS
@ -282,23 +283,10 @@ mapformat_udmf
include("SRB222_misc.cfg", "thingflagstranslation");
}
// THING RENSERSTYLES
/* thingrenderstyles
{
include("SRB222_misc.cfg", "thingrenderstyles");
}*/
// How to compare thing flags (for the stuck things error checker)
/* thingflagscompare
thingflagscompare
{
include("UDMF_misc.cfg", "thingflagscompare");
}*/
//mxd. Thing flags UDMF translation table
// This is needed for copy/paste and prefabs to work properly
// When the UDMF field name is prefixed with ! it is inverted
thingflagstranslation
{
}
// LINEDEF TYPES

File diff suppressed because it is too large Load diff

View file

@ -19,13 +19,6 @@ linedefflags
}
// LINEDEF ACTIVATIONS
// Make sure these are in order from lowest value to highest value
linedefactivations
{
}
// Linedef flags UDMF translation table
// This is needed for copy/paste and prefabs to work properly
// When the UDMF field name is prefixed with ! it is inverted
@ -63,44 +56,24 @@ linedefflags_udmf
midpeg = "Peg Midtexture";
midsolid = "Solid Midtexture";
wrapmidtex = "Repeat Midtexture";
// netonly = "Netgame-Only special";
// nonet = "No netgame special";
// effect6 = "Effect 6";
netonly = "Netgame Only";
nonet = "No Netgame";
effect6 = "Effect 6";
bouncy = "Bouncy Wall";
// transfer = "Transfer Line";
transfer = "Transfer Line";
}
linedefactivations_udmf
{
notriggerorder = "Out of Order";
netonly = "Netgame-Only";
nonet = "No netgame";
}
sidedefflags
{
clipmidtex = "Clip middle texture";
wrapmidtex = "Wrap middle texture";
smoothlighting = "Smooth lighting";
nofakecontrast = "Even lighting";
nodecals = "No decals";
lightfog = "Use sidedef brightness on fogged walls";
}
//RENDER STYLES
thingrenderstyles
{
}
linedefrenderstyles
/*linedefrenderstyles
{
translucent = "Translucent";
fog = "Fog";
}
}*/
sectorrenderstyles
sectorflags
{
colormapfog = "Fog Planes in Colormap";
colormapfadesprites = "Fade Fullbright in Colormap";
colormapprotected = "Protected Colormap";
}
thingflags
@ -221,27 +194,25 @@ universalfields
{
sector
{
friction
lightalpha
{
name = "Friction";
type = 1;
default = 1;
type = 0;
default = 25;
}
specialeffectplanes
fadealpha
{
type = 11;
enum = "floorceiling";
default = 0;
type = 0;
default = 25;
}
colormapbegin
fadestart
{
type = 0;
default = 0;
}
colormapend
fadeend
{
type = 0;
default = 33;
@ -252,63 +223,39 @@ universalfields
type = 3;
default = false;
}
teambase
{
type = 11;
enum = "ctfteam";
default = 0;
}
triggersector
{
type = 3;
default = false;
}
triggerobject
{
type = 11;
enum = "triggerobjects";
default = 0;
}
triggersurface
{
type = 11;
enum = "triggersurfaces";
default = 0;
}
ringdrain
{
type = 1;
default = 0;
}
}
linedef
{
executordelay
{
type = 0;
default = 0;
}
midtexrepetitions
{
type = 0;
default = 0;
}
arg5
{
type = 0;
default = 0;
}
arg1str
stringarg0
{
type = 2;
default = "";
}
stringarg1
{
type = 2;
default = "";
}
executordelay
{
type = 0;
default = 0;
}
}
sidedef
{
repeatcnt
{
type = 0;
default = 0;
}
}
thing
@ -483,27 +430,6 @@ enums
1 = "Up";
}
addset
{
0 = "Add";
1 = "Set";
}
floorceiling
{
0 = "Floor";
1 = "Ceiling";
2 = "Floor and ceiling";
}
triggertype
{
0 = "Continuous";
1 = "Each Time (Enter)";
2 = "Each Time (Enter and leave)";
3 = "Once";
}
frontback
{
0 = "None";
@ -511,29 +437,6 @@ enums
2 = "Back";
}
ctfteam
{
0 = "None";
1 = "Red";
2 = "Blue";
}
triggerobjects
{
0 = "Any player";
1 = "All players";
2 = "Pushable object";
3 = "Any object with thinker";
}
triggersurfaces
{
0 = "Floor touch";
1 = "Ceiling touch";
2 = "Floor or ceiling touch";
3 = "Anywhere in sector";
}
tangibility
{
1 = "Intangible from top";
@ -601,10 +504,6 @@ thingsfilters
}
}
thingsfilters_udmf
{
}
// Special linedefs
speciallinedefs
{

View file

@ -25,7 +25,7 @@ sectortypes
112 = "Trigger Line Ex. (NiGHTS Mare)";
128 = "Check for Linedef Executor on FOFs";
144 = "Egg Capsule";
160 = "Special Stage Time/Rings Parameters";
160 = "Special Stage Time/Spheres Parameters";
176 = "Custom Global Gravity";
512 = "Wind/Current";
1024 = "Conveyor Belt";
@ -78,7 +78,7 @@ gen_sectortypes
112 = "Trigger Line Ex. (NiGHTS Mare)";
128 = "Check for Linedef Executor on FOFs";
144 = "Egg Capsule";
160 = "Special Stage Time/Rings Parameters";
160 = "Special Stage Time/Spheres Parameters";
176 = "Custom Global Gravity";
}

View file

@ -1,5 +1,5 @@
/************************************************************************\
Zone Builder Game Configuration for Sonic Robo Blast 2 Version 2.2
/************************************************************************\
Ultimate Doom Builder Game Configuration for Sonic Robo Blast 2 Version 2.2
\************************************************************************/
// This is required to prevent accidental use of a different configuration

View file

@ -1,5 +1,5 @@
/************************************************************************\
Zone Builder Game Configuration for Sonic Robo Blast 2 Version 2.2
/************************************************************************\
Ultimate Doom Builder Game Configuration for Sonic Robo Blast 2 Version 2.2
\************************************************************************/
// This is required to prevent accidental use of a different configuration
@ -14,7 +14,7 @@ engine = "zdoom";
// Settings common to all games and all map formats
include("Includes\\SRB222_common.cfg", "common");
// Settings common to Doom map format
// Settings common to text map format
include("Includes\\SRB222_common.cfg", "mapformat_udmf");
include("Includes\\Game_SRB222.cfg");

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
#ifndef __CURL_CURLVER_H
#define __CURL_CURLVER_H
#ifndef CURLINC_CURLVER_H
#define CURLINC_CURLVER_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
* are also available at https://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@ -26,17 +26,17 @@
a script at release-time. This was made its own header file in 7.11.2 */
/* This is the global package copyright */
#define LIBCURL_COPYRIGHT "1996 - 2011 Daniel Stenberg, <daniel@haxx.se>."
#define LIBCURL_COPYRIGHT "1996 - 2020 Daniel Stenberg, <daniel@haxx.se>."
/* This is the version number of the libcurl package from which this header
file origins: */
#define LIBCURL_VERSION "7.21.6"
#define LIBCURL_VERSION "7.69.0"
/* The numeric version number is also available "in parts" by using these
defines: */
#define LIBCURL_VERSION_MAJOR 7
#define LIBCURL_VERSION_MINOR 21
#define LIBCURL_VERSION_PATCH 6
#define LIBCURL_VERSION_MINOR 69
#define LIBCURL_VERSION_PATCH 0
/* This is the numeric version of the libcurl version number, meant for easier
parsing and comparions by programs. The LIBCURL_VERSION_NUM define will
@ -52,18 +52,26 @@
This 6-digit (24 bits) hexadecimal number does not show pre-release number,
and it is always a greater number in a more recent release. It makes
comparisons with greater than and less than work.
Note: This define is the full hex number and _does not_ use the
CURL_VERSION_BITS() macro since curl's own configure script greps for it
and needs it to contain the full number.
*/
#define LIBCURL_VERSION_NUM 0x071506
#define LIBCURL_VERSION_NUM 0x074500
/*
* This is the date and time when the full source package was created. The
* timestamp is not stored in git, as the timestamp is properly set in the
* tarballs by the maketgz script.
*
* The format of the date should follow this template:
* The format of the date follows this template:
*
* "Mon Feb 12 11:35:33 UTC 2007"
* "2007-11-23"
*/
#define LIBCURL_TIMESTAMP "Fri Apr 22 17:18:50 UTC 2011"
#define LIBCURL_TIMESTAMP "2020-03-04"
#endif /* __CURL_CURLVER_H */
#define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|(z))
#define CURL_AT_LEAST_VERSION(x,y,z) \
(LIBCURL_VERSION_NUM >= CURL_VERSION_BITS(x, y, z))
#endif /* CURLINC_CURLVER_H */

View file

@ -1,5 +1,5 @@
#ifndef __CURL_EASY_H
#define __CURL_EASY_H
#ifndef CURLINC_EASY_H
#define CURLINC_EASY_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
* are also available at https://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@ -58,7 +58,7 @@ CURL_EXTERN CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...);
* curl_easy_duphandle() for each new thread to avoid a series of identical
* curl_easy_setopt() invokes in every thread.
*/
CURL_EXTERN CURL* curl_easy_duphandle(CURL *curl);
CURL_EXTERN CURL *curl_easy_duphandle(CURL *curl);
/*
* NAME curl_easy_reset()
@ -95,6 +95,16 @@ CURL_EXTERN CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen,
CURL_EXTERN CURLcode curl_easy_send(CURL *curl, const void *buffer,
size_t buflen, size_t *n);
/*
* NAME curl_easy_upkeep()
*
* DESCRIPTION
*
* Performs connection upkeep for the given session handle.
*/
CURL_EXTERN CURLcode curl_easy_upkeep(CURL *curl);
#ifdef __cplusplus
}
#endif

View file

@ -1,5 +1,5 @@
#ifndef __CURL_MPRINTF_H
#define __CURL_MPRINTF_H
#ifndef CURLINC_MPRINTF_H
#define CURLINC_MPRINTF_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
* are also available at https://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@ -24,8 +24,7 @@
#include <stdarg.h>
#include <stdio.h> /* needed for FILE */
#include "curl.h"
#include "curl.h" /* for CURL_EXTERN */
#ifdef __cplusplus
extern "C" {
@ -44,38 +43,8 @@ CURL_EXTERN int curl_mvsnprintf(char *buffer, size_t maxlength,
CURL_EXTERN char *curl_maprintf(const char *format, ...);
CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args);
#ifdef _MPRINTF_REPLACE
# undef printf
# undef fprintf
# undef sprintf
# undef vsprintf
# undef snprintf
# undef vprintf
# undef vfprintf
# undef vsnprintf
# undef aprintf
# undef vaprintf
# define printf curl_mprintf
# define fprintf curl_mfprintf
#ifdef CURLDEBUG
/* When built with CURLDEBUG we define away the sprintf() functions since we
don't want internal code to be using them */
# define sprintf sprintf_was_used
# define vsprintf vsprintf_was_used
#else
# define sprintf curl_msprintf
# define vsprintf curl_mvsprintf
#endif
# define snprintf curl_msnprintf
# define vprintf curl_mvprintf
# define vfprintf curl_mvfprintf
# define vsnprintf curl_mvsnprintf
# define aprintf curl_maprintf
# define vaprintf curl_mvaprintf
#endif
#ifdef __cplusplus
}
#endif
#endif /* __CURL_MPRINTF_H */
#endif /* CURLINC_MPRINTF_H */

View file

@ -1,5 +1,5 @@
#ifndef __CURL_MULTI_H
#define __CURL_MULTI_H
#ifndef CURLINC_MULTI_H
#define CURLINC_MULTI_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
* are also available at https://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@ -52,7 +52,11 @@
extern "C" {
#endif
#if defined(BUILDING_LIBCURL) || defined(CURL_STRICTER)
typedef struct Curl_multi CURLM;
#else
typedef void CURLM;
#endif
typedef enum {
CURLM_CALL_MULTI_PERFORM = -1, /* please call curl_multi_perform() or
@ -64,6 +68,12 @@ typedef enum {
CURLM_INTERNAL_ERROR, /* this is a libcurl bug */
CURLM_BAD_SOCKET, /* the passed in socket argument did not match */
CURLM_UNKNOWN_OPTION, /* curl_multi_setopt() with unsupported option */
CURLM_ADDED_ALREADY, /* an easy handle already added to a multi handle was
attempted to get added - again */
CURLM_RECURSIVE_API_CALL, /* an api function was called from inside a
callback */
CURLM_WAKEUP_FAILURE, /* wakeup is unavailable or failed */
CURLM_BAD_FUNCTION_ARGUMENT, /* function called with a bad parameter */
CURLM_LAST
} CURLMcode;
@ -72,6 +82,11 @@ typedef enum {
curl_multi_perform() and CURLM_CALL_MULTI_PERFORM */
#define CURLM_CALL_MULTI_SOCKET CURLM_CALL_MULTI_PERFORM
/* bitmask bits for CURLMOPT_PIPELINING */
#define CURLPIPE_NOTHING 0L
#define CURLPIPE_HTTP1 1L
#define CURLPIPE_MULTIPLEX 2L
typedef enum {
CURLMSG_NONE, /* first, not used */
CURLMSG_DONE, /* This easy handle has completed. 'result' contains
@ -89,6 +104,19 @@ struct CURLMsg {
};
typedef struct CURLMsg CURLMsg;
/* Based on poll(2) structure and values.
* We don't use pollfd and POLL* constants explicitly
* to cover platforms without poll(). */
#define CURL_WAIT_POLLIN 0x0001
#define CURL_WAIT_POLLPRI 0x0002
#define CURL_WAIT_POLLOUT 0x0004
struct curl_waitfd {
curl_socket_t fd;
short events;
short revents; /* not supported yet */
};
/*
* Name: curl_multi_init()
*
@ -133,6 +161,43 @@ CURL_EXTERN CURLMcode curl_multi_fdset(CURLM *multi_handle,
fd_set *exc_fd_set,
int *max_fd);
/*
* Name: curl_multi_wait()
*
* Desc: Poll on all fds within a CURLM set as well as any
* additional fds passed to the function.
*
* Returns: CURLMcode type, general multi error code.
*/
CURL_EXTERN CURLMcode curl_multi_wait(CURLM *multi_handle,
struct curl_waitfd extra_fds[],
unsigned int extra_nfds,
int timeout_ms,
int *ret);
/*
* Name: curl_multi_poll()
*
* Desc: Poll on all fds within a CURLM set as well as any
* additional fds passed to the function.
*
* Returns: CURLMcode type, general multi error code.
*/
CURL_EXTERN CURLMcode curl_multi_poll(CURLM *multi_handle,
struct curl_waitfd extra_fds[],
unsigned int extra_nfds,
int timeout_ms,
int *ret);
/*
* Name: curl_multi_wakeup()
*
* Desc: wakes up a sleeping curl_multi_poll call.
*
* Returns: CURLMcode type, general multi error code.
*/
CURL_EXTERN CURLMcode curl_multi_wakeup(CURLM *multi_handle);
/*
* Name: curl_multi_perform()
*
@ -146,8 +211,8 @@ CURL_EXTERN CURLMcode curl_multi_fdset(CURLM *multi_handle,
*
* Returns: CURLMcode type, general multi error code. *NOTE* that this only
* returns errors etc regarding the whole multi stack. There might
* still have occurred problems on invidual transfers even when this
* returns OK.
* still have occurred problems on individual transfers even when
* this returns OK.
*/
CURL_EXTERN CURLMcode curl_multi_perform(CURLM *multi_handle,
int *running_handles);
@ -180,7 +245,7 @@ CURL_EXTERN CURLMcode curl_multi_cleanup(CURLM *multi_handle);
* curl_multi_cleanup().
*
* The 'CURLMsg' struct is meant to be very simple and only contain
* very basic informations. If more involved information is wanted,
* very basic information. If more involved information is wanted,
* we will provide the particular "transfer handle" in that struct
* and that should/could/would be used in subsequent
* curl_easy_getinfo() calls (or similar). The point being that we
@ -279,37 +344,58 @@ CURL_EXTERN CURLMcode curl_multi_socket_all(CURLM *multi_handle,
CURL_EXTERN CURLMcode curl_multi_timeout(CURLM *multi_handle,
long *milliseconds);
#undef CINIT /* re-using the same name as in curl.h */
#ifdef CURL_ISOCPP
#define CINIT(name,type,num) CURLMOPT_ ## name = CURLOPTTYPE_ ## type + num
#else
/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */
#define LONG CURLOPTTYPE_LONG
#define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT
#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT
#define OFF_T CURLOPTTYPE_OFF_T
#define CINIT(name,type,number) CURLMOPT_/**/name = type + number
#endif
typedef enum {
/* This is the socket callback function pointer */
CINIT(SOCKETFUNCTION, FUNCTIONPOINT, 1),
CURLOPT(CURLMOPT_SOCKETFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 1),
/* This is the argument passed to the socket callback */
CINIT(SOCKETDATA, OBJECTPOINT, 2),
CURLOPT(CURLMOPT_SOCKETDATA, CURLOPTTYPE_OBJECTPOINT, 2),
/* set to 1 to enable pipelining for this multi handle */
CINIT(PIPELINING, LONG, 3),
CURLOPT(CURLMOPT_PIPELINING, CURLOPTTYPE_LONG, 3),
/* This is the timer callback function pointer */
CINIT(TIMERFUNCTION, FUNCTIONPOINT, 4),
CURLOPT(CURLMOPT_TIMERFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 4),
/* This is the argument passed to the timer callback */
CINIT(TIMERDATA, OBJECTPOINT, 5),
CURLOPT(CURLMOPT_TIMERDATA, CURLOPTTYPE_OBJECTPOINT, 5),
/* maximum number of entries in the connection cache */
CINIT(MAXCONNECTS, LONG, 6),
CURLOPT(CURLMOPT_MAXCONNECTS, CURLOPTTYPE_LONG, 6),
/* maximum number of (pipelining) connections to one host */
CURLOPT(CURLMOPT_MAX_HOST_CONNECTIONS, CURLOPTTYPE_LONG, 7),
/* maximum number of requests in a pipeline */
CURLOPT(CURLMOPT_MAX_PIPELINE_LENGTH, CURLOPTTYPE_LONG, 8),
/* a connection with a content-length longer than this
will not be considered for pipelining */
CURLOPT(CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE, CURLOPTTYPE_OFF_T, 9),
/* a connection with a chunk length longer than this
will not be considered for pipelining */
CURLOPT(CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE, CURLOPTTYPE_OFF_T, 10),
/* a list of site names(+port) that are blacklisted from
pipelining */
CURLOPT(CURLMOPT_PIPELINING_SITE_BL, CURLOPTTYPE_OBJECTPOINT, 11),
/* a list of server types that are blacklisted from
pipelining */
CURLOPT(CURLMOPT_PIPELINING_SERVER_BL, CURLOPTTYPE_OBJECTPOINT, 12),
/* maximum number of open connections in total */
CURLOPT(CURLMOPT_MAX_TOTAL_CONNECTIONS, CURLOPTTYPE_LONG, 13),
/* This is the server push callback function pointer */
CURLOPT(CURLMOPT_PUSHFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 14),
/* This is the argument passed to the server push callback */
CURLOPT(CURLMOPT_PUSHDATA, CURLOPTTYPE_OBJECTPOINT, 15),
/* maximum number of concurrent streams to support on a connection */
CURLOPT(CURLMOPT_MAX_CONCURRENT_STREAMS, CURLOPTTYPE_LONG, 16),
CURLMOPT_LASTENTRY /* the last unused */
} CURLMoption;
@ -338,6 +424,31 @@ CURL_EXTERN CURLMcode curl_multi_setopt(CURLM *multi_handle,
CURL_EXTERN CURLMcode curl_multi_assign(CURLM *multi_handle,
curl_socket_t sockfd, void *sockp);
/*
* Name: curl_push_callback
*
* Desc: This callback gets called when a new stream is being pushed by the
* server. It approves or denies the new stream.
*
* Returns: CURL_PUSH_OK or CURL_PUSH_DENY.
*/
#define CURL_PUSH_OK 0
#define CURL_PUSH_DENY 1
struct curl_pushheaders; /* forward declaration only */
CURL_EXTERN char *curl_pushheader_bynum(struct curl_pushheaders *h,
size_t num);
CURL_EXTERN char *curl_pushheader_byname(struct curl_pushheaders *h,
const char *name);
typedef int (*curl_push_callback)(CURL *parent,
CURL *easy,
size_t num_headers,
struct curl_pushheaders *headers,
void *userp);
#ifdef __cplusplus
} /* end of extern "C" */
#endif

View file

@ -1,5 +1,5 @@
#ifndef __STDC_HEADERS_H
#define __STDC_HEADERS_H
#ifndef CURLINC_STDCHEADERS_H
#define CURLINC_STDCHEADERS_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
* are also available at https://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@ -24,10 +24,10 @@
#include <sys/types.h>
size_t fread (void *, size_t, size_t, FILE *);
size_t fwrite (const void *, size_t, size_t, FILE *);
size_t fread(void *, size_t, size_t, FILE *);
size_t fwrite(const void *, size_t, size_t, FILE *);
int strcasecmp(const char *, const char *);
int strncasecmp(const char *, const char *, size_t);
#endif /* __STDC_HEADERS_H */
#endif /* CURLINC_STDCHEADERS_H */

View file

@ -0,0 +1,504 @@
#ifndef CURLINC_SYSTEM_H
#define CURLINC_SYSTEM_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
/*
* Try to keep one section per platform, compiler and architecture, otherwise,
* if an existing section is reused for a different one and later on the
* original is adjusted, probably the piggybacking one can be adversely
* changed.
*
* In order to differentiate between platforms/compilers/architectures use
* only compiler built in predefined preprocessor symbols.
*
* curl_off_t
* ----------
*
* For any given platform/compiler curl_off_t must be typedef'ed to a 64-bit
* wide signed integral data type. The width of this data type must remain
* constant and independent of any possible large file support settings.
*
* As an exception to the above, curl_off_t shall be typedef'ed to a 32-bit
* wide signed integral data type if there is no 64-bit type.
*
* As a general rule, curl_off_t shall not be mapped to off_t. This rule shall
* only be violated if off_t is the only 64-bit data type available and the
* size of off_t is independent of large file support settings. Keep your
* build on the safe side avoiding an off_t gating. If you have a 64-bit
* off_t then take for sure that another 64-bit data type exists, dig deeper
* and you will find it.
*
*/
#if defined(__DJGPP__) || defined(__GO32__)
# if defined(__DJGPP__) && (__DJGPP__ > 1)
# define CURL_TYPEOF_CURL_OFF_T long long
# define CURL_FORMAT_CURL_OFF_T "lld"
# define CURL_FORMAT_CURL_OFF_TU "llu"
# define CURL_SUFFIX_CURL_OFF_T LL
# define CURL_SUFFIX_CURL_OFF_TU ULL
# else
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# endif
# define CURL_TYPEOF_CURL_SOCKLEN_T int
#elif defined(__SALFORDC__)
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# define CURL_TYPEOF_CURL_SOCKLEN_T int
#elif defined(__BORLANDC__)
# if (__BORLANDC__ < 0x520)
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# else
# define CURL_TYPEOF_CURL_OFF_T __int64
# define CURL_FORMAT_CURL_OFF_T "I64d"
# define CURL_FORMAT_CURL_OFF_TU "I64u"
# define CURL_SUFFIX_CURL_OFF_T i64
# define CURL_SUFFIX_CURL_OFF_TU ui64
# endif
# define CURL_TYPEOF_CURL_SOCKLEN_T int
#elif defined(__TURBOC__)
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# define CURL_TYPEOF_CURL_SOCKLEN_T int
#elif defined(__WATCOMC__)
# if defined(__386__)
# define CURL_TYPEOF_CURL_OFF_T __int64
# define CURL_FORMAT_CURL_OFF_T "I64d"
# define CURL_FORMAT_CURL_OFF_TU "I64u"
# define CURL_SUFFIX_CURL_OFF_T i64
# define CURL_SUFFIX_CURL_OFF_TU ui64
# else
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# endif
# define CURL_TYPEOF_CURL_SOCKLEN_T int
#elif defined(__POCC__)
# if (__POCC__ < 280)
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# elif defined(_MSC_VER)
# define CURL_TYPEOF_CURL_OFF_T __int64
# define CURL_FORMAT_CURL_OFF_T "I64d"
# define CURL_FORMAT_CURL_OFF_TU "I64u"
# define CURL_SUFFIX_CURL_OFF_T i64
# define CURL_SUFFIX_CURL_OFF_TU ui64
# else
# define CURL_TYPEOF_CURL_OFF_T long long
# define CURL_FORMAT_CURL_OFF_T "lld"
# define CURL_FORMAT_CURL_OFF_TU "llu"
# define CURL_SUFFIX_CURL_OFF_T LL
# define CURL_SUFFIX_CURL_OFF_TU ULL
# endif
# define CURL_TYPEOF_CURL_SOCKLEN_T int
#elif defined(__LCC__)
# if defined(__e2k__) /* MCST eLbrus C Compiler */
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
# define CURL_PULL_SYS_TYPES_H 1
# define CURL_PULL_SYS_SOCKET_H 1
# else /* Local (or Little) C Compiler */
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# define CURL_TYPEOF_CURL_SOCKLEN_T int
# endif
#elif defined(__SYMBIAN32__)
# if defined(__EABI__) /* Treat all ARM compilers equally */
# define CURL_TYPEOF_CURL_OFF_T long long
# define CURL_FORMAT_CURL_OFF_T "lld"
# define CURL_FORMAT_CURL_OFF_TU "llu"
# define CURL_SUFFIX_CURL_OFF_T LL
# define CURL_SUFFIX_CURL_OFF_TU ULL
# elif defined(__CW32__)
# pragma longlong on
# define CURL_TYPEOF_CURL_OFF_T long long
# define CURL_FORMAT_CURL_OFF_T "lld"
# define CURL_FORMAT_CURL_OFF_TU "llu"
# define CURL_SUFFIX_CURL_OFF_T LL
# define CURL_SUFFIX_CURL_OFF_TU ULL
# elif defined(__VC32__)
# define CURL_TYPEOF_CURL_OFF_T __int64
# define CURL_FORMAT_CURL_OFF_T "lld"
# define CURL_FORMAT_CURL_OFF_TU "llu"
# define CURL_SUFFIX_CURL_OFF_T LL
# define CURL_SUFFIX_CURL_OFF_TU ULL
# endif
# define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int
#elif defined(__MWERKS__)
# define CURL_TYPEOF_CURL_OFF_T long long
# define CURL_FORMAT_CURL_OFF_T "lld"
# define CURL_FORMAT_CURL_OFF_TU "llu"
# define CURL_SUFFIX_CURL_OFF_T LL
# define CURL_SUFFIX_CURL_OFF_TU ULL
# define CURL_TYPEOF_CURL_SOCKLEN_T int
#elif defined(_WIN32_WCE)
# define CURL_TYPEOF_CURL_OFF_T __int64
# define CURL_FORMAT_CURL_OFF_T "I64d"
# define CURL_FORMAT_CURL_OFF_TU "I64u"
# define CURL_SUFFIX_CURL_OFF_T i64
# define CURL_SUFFIX_CURL_OFF_TU ui64
# define CURL_TYPEOF_CURL_SOCKLEN_T int
#elif defined(__MINGW32__)
# define CURL_TYPEOF_CURL_OFF_T long long
# define CURL_FORMAT_CURL_OFF_T "I64d"
# define CURL_FORMAT_CURL_OFF_TU "I64u"
# define CURL_SUFFIX_CURL_OFF_T LL
# define CURL_SUFFIX_CURL_OFF_TU ULL
# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
# define CURL_PULL_SYS_TYPES_H 1
# define CURL_PULL_WS2TCPIP_H 1
#elif defined(__VMS)
# if defined(__VAX)
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# else
# define CURL_TYPEOF_CURL_OFF_T long long
# define CURL_FORMAT_CURL_OFF_T "lld"
# define CURL_FORMAT_CURL_OFF_TU "llu"
# define CURL_SUFFIX_CURL_OFF_T LL
# define CURL_SUFFIX_CURL_OFF_TU ULL
# endif
# define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int
#elif defined(__OS400__)
# if defined(__ILEC400__)
# define CURL_TYPEOF_CURL_OFF_T long long
# define CURL_FORMAT_CURL_OFF_T "lld"
# define CURL_FORMAT_CURL_OFF_TU "llu"
# define CURL_SUFFIX_CURL_OFF_T LL
# define CURL_SUFFIX_CURL_OFF_TU ULL
# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
# define CURL_PULL_SYS_TYPES_H 1
# define CURL_PULL_SYS_SOCKET_H 1
# endif
#elif defined(__MVS__)
# if defined(__IBMC__) || defined(__IBMCPP__)
# if defined(_ILP32)
# elif defined(_LP64)
# endif
# if defined(_LONG_LONG)
# define CURL_TYPEOF_CURL_OFF_T long long
# define CURL_FORMAT_CURL_OFF_T "lld"
# define CURL_FORMAT_CURL_OFF_TU "llu"
# define CURL_SUFFIX_CURL_OFF_T LL
# define CURL_SUFFIX_CURL_OFF_TU ULL
# elif defined(_LP64)
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# else
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# endif
# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
# define CURL_PULL_SYS_TYPES_H 1
# define CURL_PULL_SYS_SOCKET_H 1
# endif
#elif defined(__370__)
# if defined(__IBMC__) || defined(__IBMCPP__)
# if defined(_ILP32)
# elif defined(_LP64)
# endif
# if defined(_LONG_LONG)
# define CURL_TYPEOF_CURL_OFF_T long long
# define CURL_FORMAT_CURL_OFF_T "lld"
# define CURL_FORMAT_CURL_OFF_TU "llu"
# define CURL_SUFFIX_CURL_OFF_T LL
# define CURL_SUFFIX_CURL_OFF_TU ULL
# elif defined(_LP64)
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# else
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# endif
# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
# define CURL_PULL_SYS_TYPES_H 1
# define CURL_PULL_SYS_SOCKET_H 1
# endif
#elif defined(TPF)
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# define CURL_TYPEOF_CURL_SOCKLEN_T int
#elif defined(__TINYC__) /* also known as tcc */
# define CURL_TYPEOF_CURL_OFF_T long long
# define CURL_FORMAT_CURL_OFF_T "lld"
# define CURL_FORMAT_CURL_OFF_TU "llu"
# define CURL_SUFFIX_CURL_OFF_T LL
# define CURL_SUFFIX_CURL_OFF_TU ULL
# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
# define CURL_PULL_SYS_TYPES_H 1
# define CURL_PULL_SYS_SOCKET_H 1
#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) /* Oracle Solaris Studio */
# if !defined(__LP64) && (defined(__ILP32) || \
defined(__i386) || \
defined(__sparcv8) || \
defined(__sparcv8plus))
# define CURL_TYPEOF_CURL_OFF_T long long
# define CURL_FORMAT_CURL_OFF_T "lld"
# define CURL_FORMAT_CURL_OFF_TU "llu"
# define CURL_SUFFIX_CURL_OFF_T LL
# define CURL_SUFFIX_CURL_OFF_TU ULL
# elif defined(__LP64) || \
defined(__amd64) || defined(__sparcv9)
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# endif
# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
# define CURL_PULL_SYS_TYPES_H 1
# define CURL_PULL_SYS_SOCKET_H 1
#elif defined(__xlc__) /* IBM xlc compiler */
# if !defined(_LP64)
# define CURL_TYPEOF_CURL_OFF_T long long
# define CURL_FORMAT_CURL_OFF_T "lld"
# define CURL_FORMAT_CURL_OFF_TU "llu"
# define CURL_SUFFIX_CURL_OFF_T LL
# define CURL_SUFFIX_CURL_OFF_TU ULL
# else
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# endif
# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
# define CURL_PULL_SYS_TYPES_H 1
# define CURL_PULL_SYS_SOCKET_H 1
/* ===================================== */
/* KEEP MSVC THE PENULTIMATE ENTRY */
/* ===================================== */
#elif defined(_MSC_VER)
# if (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64)
# define CURL_TYPEOF_CURL_OFF_T __int64
# define CURL_FORMAT_CURL_OFF_T "I64d"
# define CURL_FORMAT_CURL_OFF_TU "I64u"
# define CURL_SUFFIX_CURL_OFF_T i64
# define CURL_SUFFIX_CURL_OFF_TU ui64
# else
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# endif
# define CURL_TYPEOF_CURL_SOCKLEN_T int
/* ===================================== */
/* KEEP GENERIC GCC THE LAST ENTRY */
/* ===================================== */
#elif defined(__GNUC__) && !defined(_SCO_DS)
# if !defined(__LP64__) && \
(defined(__ILP32__) || defined(__i386__) || defined(__hppa__) || \
defined(__ppc__) || defined(__powerpc__) || defined(__arm__) || \
defined(__sparc__) || defined(__mips__) || defined(__sh__) || \
defined(__XTENSA__) || \
(defined(__SIZEOF_LONG__) && __SIZEOF_LONG__ == 4) || \
(defined(__LONG_MAX__) && __LONG_MAX__ == 2147483647L))
# define CURL_TYPEOF_CURL_OFF_T long long
# define CURL_FORMAT_CURL_OFF_T "lld"
# define CURL_FORMAT_CURL_OFF_TU "llu"
# define CURL_SUFFIX_CURL_OFF_T LL
# define CURL_SUFFIX_CURL_OFF_TU ULL
# elif defined(__LP64__) || \
defined(__x86_64__) || defined(__ppc64__) || defined(__sparc64__) || \
defined(__e2k__) || \
(defined(__SIZEOF_LONG__) && __SIZEOF_LONG__ == 8) || \
(defined(__LONG_MAX__) && __LONG_MAX__ == 9223372036854775807L)
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# endif
# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
# define CURL_PULL_SYS_TYPES_H 1
# define CURL_PULL_SYS_SOCKET_H 1
#else
/* generic "safe guess" on old 32 bit style */
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# define CURL_TYPEOF_CURL_SOCKLEN_T int
#endif
#ifdef _AIX
/* AIX needs <sys/poll.h> */
#define CURL_PULL_SYS_POLL_H
#endif
/* CURL_PULL_WS2TCPIP_H is defined above when inclusion of header file */
/* ws2tcpip.h is required here to properly make type definitions below. */
#ifdef CURL_PULL_WS2TCPIP_H
# include <winsock2.h>
# include <windows.h>
# include <ws2tcpip.h>
#endif
/* CURL_PULL_SYS_TYPES_H is defined above when inclusion of header file */
/* sys/types.h is required here to properly make type definitions below. */
#ifdef CURL_PULL_SYS_TYPES_H
# include <sys/types.h>
#endif
/* CURL_PULL_SYS_SOCKET_H is defined above when inclusion of header file */
/* sys/socket.h is required here to properly make type definitions below. */
#ifdef CURL_PULL_SYS_SOCKET_H
# include <sys/socket.h>
#endif
/* CURL_PULL_SYS_POLL_H is defined above when inclusion of header file */
/* sys/poll.h is required here to properly make type definitions below. */
#ifdef CURL_PULL_SYS_POLL_H
# include <sys/poll.h>
#endif
/* Data type definition of curl_socklen_t. */
#ifdef CURL_TYPEOF_CURL_SOCKLEN_T
typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t;
#endif
/* Data type definition of curl_off_t. */
#ifdef CURL_TYPEOF_CURL_OFF_T
typedef CURL_TYPEOF_CURL_OFF_T curl_off_t;
#endif
/*
* CURL_ISOCPP and CURL_OFF_T_C definitions are done here in order to allow
* these to be visible and exported by the external libcurl interface API,
* while also making them visible to the library internals, simply including
* curl_setup.h, without actually needing to include curl.h internally.
* If some day this section would grow big enough, all this should be moved
* to its own header file.
*/
/*
* Figure out if we can use the ## preprocessor operator, which is supported
* by ISO/ANSI C and C++. Some compilers support it without setting __STDC__
* or __cplusplus so we need to carefully check for them too.
*/
#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) || \
defined(__HP_aCC) || defined(__BORLANDC__) || defined(__LCC__) || \
defined(__POCC__) || defined(__SALFORDC__) || defined(__HIGHC__) || \
defined(__ILEC400__)
/* This compiler is believed to have an ISO compatible preprocessor */
#define CURL_ISOCPP
#else
/* This compiler is believed NOT to have an ISO compatible preprocessor */
#undef CURL_ISOCPP
#endif
/*
* Macros for minimum-width signed and unsigned curl_off_t integer constants.
*/
#if defined(__BORLANDC__) && (__BORLANDC__ == 0x0551)
# define CURLINC_OFF_T_C_HLPR2(x) x
# define CURLINC_OFF_T_C_HLPR1(x) CURLINC_OFF_T_C_HLPR2(x)
# define CURL_OFF_T_C(Val) CURLINC_OFF_T_C_HLPR1(Val) ## \
CURLINC_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_T)
# define CURL_OFF_TU_C(Val) CURLINC_OFF_T_C_HLPR1(Val) ## \
CURLINC_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_TU)
#else
# ifdef CURL_ISOCPP
# define CURLINC_OFF_T_C_HLPR2(Val,Suffix) Val ## Suffix
# else
# define CURLINC_OFF_T_C_HLPR2(Val,Suffix) Val/**/Suffix
# endif
# define CURLINC_OFF_T_C_HLPR1(Val,Suffix) CURLINC_OFF_T_C_HLPR2(Val,Suffix)
# define CURL_OFF_T_C(Val) CURLINC_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_T)
# define CURL_OFF_TU_C(Val) CURLINC_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_TU)
#endif
#endif /* CURLINC_SYSTEM_H */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,125 @@
#ifndef CURLINC_URLAPI_H
#define CURLINC_URLAPI_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2018 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include "curl.h"
#ifdef __cplusplus
extern "C" {
#endif
/* the error codes for the URL API */
typedef enum {
CURLUE_OK,
CURLUE_BAD_HANDLE, /* 1 */
CURLUE_BAD_PARTPOINTER, /* 2 */
CURLUE_MALFORMED_INPUT, /* 3 */
CURLUE_BAD_PORT_NUMBER, /* 4 */
CURLUE_UNSUPPORTED_SCHEME, /* 5 */
CURLUE_URLDECODE, /* 6 */
CURLUE_OUT_OF_MEMORY, /* 7 */
CURLUE_USER_NOT_ALLOWED, /* 8 */
CURLUE_UNKNOWN_PART, /* 9 */
CURLUE_NO_SCHEME, /* 10 */
CURLUE_NO_USER, /* 11 */
CURLUE_NO_PASSWORD, /* 12 */
CURLUE_NO_OPTIONS, /* 13 */
CURLUE_NO_HOST, /* 14 */
CURLUE_NO_PORT, /* 15 */
CURLUE_NO_QUERY, /* 16 */
CURLUE_NO_FRAGMENT /* 17 */
} CURLUcode;
typedef enum {
CURLUPART_URL,
CURLUPART_SCHEME,
CURLUPART_USER,
CURLUPART_PASSWORD,
CURLUPART_OPTIONS,
CURLUPART_HOST,
CURLUPART_PORT,
CURLUPART_PATH,
CURLUPART_QUERY,
CURLUPART_FRAGMENT,
CURLUPART_ZONEID /* added in 7.65.0 */
} CURLUPart;
#define CURLU_DEFAULT_PORT (1<<0) /* return default port number */
#define CURLU_NO_DEFAULT_PORT (1<<1) /* act as if no port number was set,
if the port number matches the
default for the scheme */
#define CURLU_DEFAULT_SCHEME (1<<2) /* return default scheme if
missing */
#define CURLU_NON_SUPPORT_SCHEME (1<<3) /* allow non-supported scheme */
#define CURLU_PATH_AS_IS (1<<4) /* leave dot sequences */
#define CURLU_DISALLOW_USER (1<<5) /* no user+password allowed */
#define CURLU_URLDECODE (1<<6) /* URL decode on get */
#define CURLU_URLENCODE (1<<7) /* URL encode on set */
#define CURLU_APPENDQUERY (1<<8) /* append a form style part */
#define CURLU_GUESS_SCHEME (1<<9) /* legacy curl-style guessing */
#define CURLU_NO_AUTHORITY (1<<10) /* Allow empty authority when the
scheme is unknown. */
typedef struct Curl_URL CURLU;
/*
* curl_url() creates a new CURLU handle and returns a pointer to it.
* Must be freed with curl_url_cleanup().
*/
CURL_EXTERN CURLU *curl_url(void);
/*
* curl_url_cleanup() frees the CURLU handle and related resources used for
* the URL parsing. It will not free strings previously returned with the URL
* API.
*/
CURL_EXTERN void curl_url_cleanup(CURLU *handle);
/*
* curl_url_dup() duplicates a CURLU handle and returns a new copy. The new
* handle must also be freed with curl_url_cleanup().
*/
CURL_EXTERN CURLU *curl_url_dup(CURLU *in);
/*
* curl_url_get() extracts a specific part of the URL from a CURLU
* handle. Returns error code. The returned pointer MUST be freed with
* curl_free() afterwards.
*/
CURL_EXTERN CURLUcode curl_url_get(CURLU *handle, CURLUPart what,
char **part, unsigned int flags);
/*
* curl_url_set() sets a specific part of the URL in a CURLU handle. Returns
* error code. The passed in string will be copied. Passing a NULL instead of
* a part string, clears that part.
*/
CURL_EXTERN CURLUcode curl_url_set(CURLU *handle, CURLUPart what,
const char *part, unsigned int flags);
#ifdef __cplusplus
} /* end of extern "C" */
#endif
#endif /* CURLINC_URLAPI_H */

Binary file not shown.

BIN
libs/curl/lib32/libcurl.dll Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -1,2 +0,0 @@
# DON'T REMOVE
# This keeps the folder from disappearing

View file

@ -1,2 +0,0 @@
# DON'T REMOVE
# This keeps the folder from disappearing

View file

@ -16,6 +16,7 @@ set(SRB2_CORE_SOURCES
f_finale.c
f_wipe.c
filesrch.c
g_demo.c
g_game.c
g_input.c
hu_stuff.c
@ -35,6 +36,7 @@ set(SRB2_CORE_SOURCES
m_random.c
md5.c
mserv.c
http-mserv.c
s_sound.c
screen.c
sounds.c
@ -71,6 +73,7 @@ set(SRB2_CORE_HEADERS
f_finale.h
fastcmp.h
filesrch.h
g_demo.h
g_game.h
g_input.h
g_state.h
@ -99,6 +102,7 @@ set(SRB2_CORE_HEADERS
m_swap.h
md5.h
mserv.h
http-mserv.h
p5prof.h
s_sound.h
screen.h
@ -120,6 +124,7 @@ set(SRB2_CORE_RENDER_SOURCES
r_main.c
r_plane.c
r_segs.c
r_skins.c
r_sky.c
r_splats.c
r_things.c
@ -134,6 +139,7 @@ set(SRB2_CORE_RENDER_SOURCES
r_main.h
r_plane.h
r_segs.h
r_skins.h
r_sky.h
r_splats.h
r_state.h
@ -214,8 +220,6 @@ source_group("Assembly" FILES ${SRB2_ASM_SOURCES} ${SRB2_NASM_SOURCES})
### Configuration
set(SRB2_CONFIG_HAVE_BLUA ON CACHE BOOL
"Enable Lua interpreter support")
set(SRB2_CONFIG_HAVE_PNG ON CACHE BOOL
"Enable PNG support. Depends on zlib, so will be disabled if you don't enable that too.")
set(SRB2_CONFIG_HAVE_ZLIB ON CACHE BOOL
@ -224,6 +228,14 @@ set(SRB2_CONFIG_HAVE_GME ON CACHE BOOL
"Enable GME support.")
set(SRB2_CONFIG_HAVE_OPENMPT ON CACHE BOOL
"Enable OpenMPT support.")
set(SRB2_CONFIG_HAVE_CURL ON CACHE BOOL
"Enable curl support, used for downloading files via HTTP.")
if(${CMAKE_SYSTEM} MATCHES Windows)
set(SRB2_CONFIG_HAVE_MIXERX ON CACHE BOOL
"Enable SDL Mixer X support.")
else()
set(SRB2_CONFIG_HAVE_MIXERX OFF)
endif()
set(SRB2_CONFIG_HWRENDER ON CACHE BOOL
"Enable hardware rendering through OpenGL.")
set(SRB2_CONFIG_USEASM OFF CACHE BOOL
@ -239,93 +251,90 @@ if(${CMAKE_SYSTEM} MATCHES "Windows") ###set on Windows only
"Use SRB2's internal copies of required dependencies (SDL2, PNG, zlib, GME, OpenMPT).")
endif()
if(${SRB2_CONFIG_HAVE_BLUA})
add_definitions(-DHAVE_BLUA)
set(SRB2_LUA_SOURCES
lua_baselib.c
lua_blockmaplib.c
lua_consolelib.c
lua_hooklib.c
lua_hudlib.c
lua_infolib.c
lua_maplib.c
lua_mathlib.c
lua_mobjlib.c
lua_playerlib.c
lua_script.c
lua_skinlib.c
lua_thinkerlib.c
)
set(SRB2_LUA_HEADERS
lua_hook.h
lua_hud.h
lua_libs.h
lua_script.h
)
set(SRB2_LUA_SOURCES
lua_baselib.c
lua_blockmaplib.c
lua_consolelib.c
lua_hooklib.c
lua_hudlib.c
lua_infolib.c
lua_maplib.c
lua_mathlib.c
lua_mobjlib.c
lua_playerlib.c
lua_script.c
lua_skinlib.c
lua_thinkerlib.c
)
set(SRB2_LUA_HEADERS
lua_hook.h
lua_hud.h
lua_libs.h
lua_script.h
)
prepend_sources(SRB2_LUA_SOURCES)
prepend_sources(SRB2_LUA_HEADERS)
prepend_sources(SRB2_LUA_SOURCES)
prepend_sources(SRB2_LUA_HEADERS)
source_group("LUA" FILES ${SRB2_LUA_SOURCES} ${SRB2_LUA_HEADERS})
source_group("LUA" FILES ${SRB2_LUA_SOURCES} ${SRB2_LUA_HEADERS})
set(SRB2_BLUA_SOURCES
blua/lapi.c
blua/lauxlib.c
blua/lbaselib.c
blua/lcode.c
blua/ldebug.c
blua/ldo.c
blua/ldump.c
blua/lfunc.c
blua/lgc.c
blua/linit.c
blua/liolib.c
blua/llex.c
blua/lmem.c
blua/lobject.c
blua/lopcodes.c
blua/lparser.c
blua/lstate.c
blua/lstring.c
blua/lstrlib.c
blua/ltable.c
blua/ltablib.c
blua/ltm.c
blua/lundump.c
blua/lvm.c
blua/lzio.c
)
set(SRB2_BLUA_HEADERS
blua/lapi.h
blua/lauxlib.h
blua/lcode.h
blua/ldebug.h
blua/ldo.h
blua/lfunc.h
blua/lgc.h
blua/llex.h
blua/llimits.h
blua/lmem.h
blua/lobject.h
blua/lopcodes.h
blua/lparser.h
blua/lstate.h
blua/lstring.h
blua/ltable.h
blua/ltm.h
blua/lua.h
blua/luaconf.h
blua/lualib.h
blua/lundump.h
blua/lvm.h
blua/lzio.h
)
set(SRB2_BLUA_SOURCES
blua/lapi.c
blua/lauxlib.c
blua/lbaselib.c
blua/lcode.c
blua/ldebug.c
blua/ldo.c
blua/ldump.c
blua/lfunc.c
blua/lgc.c
blua/linit.c
blua/liolib.c
blua/llex.c
blua/lmem.c
blua/lobject.c
blua/lopcodes.c
blua/lparser.c
blua/lstate.c
blua/lstring.c
blua/lstrlib.c
blua/ltable.c
blua/ltablib.c
blua/ltm.c
blua/lundump.c
blua/lvm.c
blua/lzio.c
)
set(SRB2_BLUA_HEADERS
blua/lapi.h
blua/lauxlib.h
blua/lcode.h
blua/ldebug.h
blua/ldo.h
blua/lfunc.h
blua/lgc.h
blua/llex.h
blua/llimits.h
blua/lmem.h
blua/lobject.h
blua/lopcodes.h
blua/lparser.h
blua/lstate.h
blua/lstring.h
blua/ltable.h
blua/ltm.h
blua/lua.h
blua/luaconf.h
blua/lualib.h
blua/lundump.h
blua/lvm.h
blua/lzio.h
)
prepend_sources(SRB2_BLUA_SOURCES)
prepend_sources(SRB2_BLUA_HEADERS)
prepend_sources(SRB2_BLUA_SOURCES)
prepend_sources(SRB2_BLUA_HEADERS)
source_group("LUA\\Interpreter" FILES ${SRB2_BLUA_SOURCES} ${SRB2_BLUA_HEADERS})
endif()
source_group("LUA\\Interpreter" FILES ${SRB2_BLUA_SOURCES} ${SRB2_BLUA_HEADERS})
if(${SRB2_CONFIG_HAVE_GME})
if(${SRB2_CONFIG_USE_INTERNAL_LIBRARIES})
@ -367,6 +376,30 @@ if(${SRB2_CONFIG_HAVE_OPENMPT})
endif()
endif()
if(${SRB2_CONFIG_HAVE_MIXERX})
if(${SRB2_CONFIG_USE_INTERNAL_LIBRARIES})
set(MIXERX_FOUND ON)
set(MIXERX_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/libs/SDLMixerX/i686-w64-mingw32/include/SDL2)
if(${SRB2_SYSTEM_BITS} EQUAL 64)
set(MIXERX_LIBRARIES "-L${CMAKE_SOURCE_DIR}/libs/SDLMixerX/x86_64-w64-mingw32/lib -lSDL2_mixer_ext")
else() # 32-bit
set(MIXERX_LIBRARIES "-L${CMAKE_SOURCE_DIR}/libs/SDLMixerX/i686-w64-mingw32/lib -lSDL2_mixer_ext")
endif()
else()
# No support for non-Windows (yet?)
#find_package(MIXERX)
message(WARNING "SDL Mixer X is not supported as an external library.")
set(MIXERX_FOUND OFF)
endif()
if(${MIXERX_FOUND})
set(SRB2_HAVE_MIXERX ON)
set(SRB2_SDL2_SOUNDIMPL mixer_sound.c)
add_definitions(-DHAVE_MIXERX)
else()
message(WARNING "You have specified that SDL Mixer X is available but it was not found.")
endif()
endif()
if(${SRB2_CONFIG_HAVE_ZLIB})
if(${SRB2_CONFIG_USE_INTERNAL_LIBRARIES})
set(ZLIB_FOUND ON)
@ -416,9 +449,30 @@ if(${SRB2_CONFIG_HAVE_PNG} AND ${SRB2_CONFIG_HAVE_ZLIB})
endif()
endif()
if(${SRB2_CONFIG_HAVE_CURL})
if(${SRB2_CONFIG_USE_INTERNAL_LIBRARIES})
set(CURL_FOUND ON)
set(CURL_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/libs/curl)
if(${SRB2_SYSTEM_BITS} EQUAL 64)
set(CURL_LIBRARIES "-L${CMAKE_SOURCE_DIR}/libs/curl/lib64 -lcurl")
else() # 32-bit
set(CURL_LIBRARIES "-L${CMAKE_SOURCE_DIR}/libs/curl/lib32 -lcurl")
endif()
else()
find_package(CURL)
endif()
if(${CURL_FOUND})
set(SRB2_HAVE_CURL ON)
add_definitions(-DHAVE_CURL)
else()
message(WARNING "You have specified that CURL is available but it was not found. SRB2 may not compile correctly.")
endif()
endif()
if(${SRB2_CONFIG_HWRENDER})
add_definitions(-DHWRENDER)
set(SRB2_HWRENDER_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_batching.c
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_bsp.c
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_cache.c
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_clip.c
@ -429,17 +483,16 @@ if(${SRB2_CONFIG_HWRENDER})
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md2load.c
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md3load.c
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_model.c
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_trick.c
${CMAKE_CURRENT_SOURCE_DIR}/hardware/u_list.c
)
set (SRB2_HWRENDER_HEADERS
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_batching.h
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_clip.h
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_data.h
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_defs.h
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_dll.h
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_drv.h
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_glide.h
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_glob.h
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_light.h
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_main.h
@ -494,6 +547,27 @@ endif()
# Targets
# If using CCACHE, then force it.
# https://github.com/Cockatrice/Cockatrice/pull/3052/files
if (${CMAKE_SYSTEM} MATCHES "Darwin")
get_property(RULE_LAUNCH_COMPILE GLOBAL PROPERTY RULE_LAUNCH_COMPILE)
if(RULE_LAUNCH_COMPILE)
MESSAGE(STATUS "Force enabling CCache usage under macOS")
# Set up wrapper scripts
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../cmake/launch-c.in ${CMAKE_BINARY_DIR}/launch-c)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../cmake/launch-cxx.in ${CMAKE_BINARY_DIR}/launch-cxx)
execute_process(COMMAND chmod a+rx
"${CMAKE_BINARY_DIR}/launch-c"
"${CMAKE_BINARY_DIR}/launch-cxx")
# Set Xcode project attributes to route compilation through our scripts
set(CMAKE_XCODE_ATTRIBUTE_CC "${CMAKE_BINARY_DIR}/launch-c")
set(CMAKE_XCODE_ATTRIBUTE_CXX "${CMAKE_BINARY_DIR}/launch-cxx")
set(CMAKE_XCODE_ATTRIBUTE_LD "${CMAKE_BINARY_DIR}/launch-c")
set(CMAKE_XCODE_ATTRIBUTE_LDPLUSPLUS "${CMAKE_BINARY_DIR}/launch-cxx")
endif()
endif()
# Compatibility flag with later versions of GCC
# We should really fix our code to not need this
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")

View file

@ -8,13 +8,11 @@
# terms of the GNU General Public License, version 2.
# See the 'LICENSE' file for more details.
#
# -DPC_DOS -> use DOS specific code (eg:textmode stuff)...
# -DLINUX -> use for the GNU/Linux specific
# -D_WINDOWS -> use for the Win32/DirectX specific
# -DHAVE_SDL -> use for the SDL interface
#
# Sets:
# Compile the DGJPP/DOS version with 'make WATTCP=1'
# Compile the DirectX/Mingw version with 'make MINGW=1'
# Compile the SDL/Mingw version with 'make MINGW=1 SDL=1'
# Compile the SDL/Linux version with 'make LINUX=1'
@ -146,10 +144,6 @@ NOHW=1
NOHS=1
endif
ifdef DJGPPDOS
include djgppdos/Makefile.cfg
endif
ifndef NOOPENMPT
HAVE_OPENMPT=1
endif
@ -213,6 +207,7 @@ endif
ifdef NONET
OPTS+=-DNONET
NOCURL=1
else
ifdef NO_IPV6
OPTS+=-DNO_IPV6
@ -222,12 +217,10 @@ endif
ifdef NOHW
OPTS+=-DNOHW
else
#Hurdler: not really supported and not tested recently
#OPTS+=-DUSE_PALETTED_TEXTURE
OPTS+=-DHWRENDER
OBJS+=$(OBJDIR)/hw_bsp.o $(OBJDIR)/hw_draw.o $(OBJDIR)/hw_light.o \
$(OBJDIR)/hw_main.o $(OBJDIR)/hw_clip.o $(OBJDIR)/hw_md2.o $(OBJDIR)/hw_cache.o $(OBJDIR)/hw_trick.o \
$(OBJDIR)/hw_md2load.o $(OBJDIR)/hw_md3load.o $(OBJDIR)/hw_model.o $(OBJDIR)/u_list.o
$(OBJDIR)/hw_main.o $(OBJDIR)/hw_clip.o $(OBJDIR)/hw_md2.o $(OBJDIR)/hw_cache.o \
$(OBJDIR)/hw_md2load.o $(OBJDIR)/hw_md3load.o $(OBJDIR)/hw_model.o $(OBJDIR)/u_list.o $(OBJDIR)/hw_batching.o
endif
ifdef NOHS
@ -324,6 +317,16 @@ else
NOPNG=1
endif
ifndef NOCURL
OPTS+=-DHAVE_CURL
CURLCONFIG?=curl-config
CURL_CFLAGS?=$(shell $(CURLCONFIG) --cflags)
CURL_LDFLAGS?=$(shell $(CURLCONFIG) --libs)
LIBS+=$(CURL_LDFLAGS)
CFLAGS+=$(CURL_CFLAGS)
endif
ifdef STATIC
LIBS:=-static $(LIBS)
endif
@ -340,9 +343,7 @@ CFLAGS+=-DHAVE_MINIUPNPC
endif
endif
ifndef NO_LUA
include blua/Makefile.cfg
endif
include blua/Makefile.cfg
ifdef NOMD5
OPTS+=-DNOMD5
@ -424,6 +425,7 @@ OBJS:=$(i_main_o) \
$(OBJDIR)/z_zone.o \
$(OBJDIR)/f_finale.o \
$(OBJDIR)/f_wipe.o \
$(OBJDIR)/g_demo.o \
$(OBJDIR)/g_game.o \
$(OBJDIR)/g_input.o \
$(OBJDIR)/am_map.o \
@ -468,6 +470,7 @@ OBJS:=$(i_main_o) \
$(OBJDIR)/r_main.o \
$(OBJDIR)/r_plane.o \
$(OBJDIR)/r_segs.o \
$(OBJDIR)/r_skins.o \
$(OBJDIR)/r_sky.o \
$(OBJDIR)/r_splats.o \
$(OBJDIR)/r_things.o \
@ -480,11 +483,11 @@ OBJS:=$(i_main_o) \
$(OBJDIR)/w_wad.o \
$(OBJDIR)/filesrch.o \
$(OBJDIR)/mserv.o \
$(OBJDIR)/http-mserv.o\
$(OBJDIR)/i_tcp.o \
$(OBJDIR)/lzf.o \
$(OBJDIR)/vid_copy.o \
$(OBJDIR)/b_bot.o \
$(i_cdmus_o) \
$(i_net_o) \
$(i_system_o) \
$(i_sound_o) \
@ -500,10 +503,6 @@ POS:=$(BIN)/en.mo
OPTS+=-DGETTEXT
endif
ifdef DJGPPDOS
all: pre-build $(BIN)/$(EXENAME)
endif
ifdef PANDORA
all: pre-build $(BIN)/$(PNDNAME)
endif
@ -647,7 +646,7 @@ ifdef SDL
ifdef MINGW
$(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \
doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \
command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \
command.h hardware/hw_data.h hardware/hw_defs.h \
hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \
hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \
am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \
@ -656,7 +655,7 @@ $(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h
else
$(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \
doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \
command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \
command.h hardware/hw_data.h hardware/hw_defs.h \
hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \
hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \
am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \
@ -682,9 +681,7 @@ $(OBJDIR)/depend.dep:
ifndef NOHW
$(CC) $(CFLAGS) -MM hardware/*.c >> $(OBJDIR)/depend.ped
endif
ifndef NO_LUA
$(CC) $(CFLAGS) -MM blua/*.c >> $(OBJDIR)/depend.ped
endif
@sed -e 's,\(.*\)\.o: ,$(subst /,\/,$(OBJDIR))\/&,g' < $(OBJDIR)/depend.ped > $(OBJDIR)/depend.dep
$(REMOVE) $(OBJDIR)/depend.ped
@echo "Created dependency file, depend.dep"
@ -736,7 +733,7 @@ ifndef SDL
ifndef NOHW
$(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \
doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \
command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \
command.h hardware/hw_data.h hardware/hw_defs.h \
hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \
hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \
am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \
@ -745,7 +742,7 @@ $(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h
$(OBJDIR)/ogl_win.o: hardware/r_opengl/ogl_win.c hardware/r_opengl/r_opengl.h \
doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \
command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \
command.h hardware/hw_data.h hardware/hw_defs.h \
hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \
hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \
am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \

View file

@ -1,3 +1,4 @@
# vim: ft=make
#
# Makefile.cfg for SRB2
#
@ -7,7 +8,88 @@
# and other things
#
# See the following variable don't start with 'GCC'. This is
# to avoid a false positive with the version detection...
SUPPORTED_GCC_VERSIONS:=\
101 102\
91 92 93\
81 82 83 84\
71 72 73 74 75\
61 62 63 64\
51 52 53 54 55\
40 41 42 43 44 45 46 47 48 49
LATEST_GCC_VERSION=10.2
# gcc or g++
ifdef PREFIX
CC=$(PREFIX)-gcc
CXX=$(PREFIX)-g++
OBJCOPY=$(PREFIX)-objcopy
OBJDUMP=$(PREFIX)-objdump
STRIP=$(PREFIX)-strip
WINDRES=$(PREFIX)-windres
else
OBJCOPY=objcopy
OBJDUMP=objdump
STRIP=strip
WINDRES=windres
endif
# because Apple screws with us on this
# need to get bintools from homebrew
ifdef MACOSX
CC=clang
CXX=clang
OBJCOPY=gobjcopy
OBJDUMP=gobjdump
endif
# Automatically set version flag, but not if one was manually set
ifeq (,$(filter GCC%,$(.VARIABLES)))
ifneq (,$(findstring gcc,$(shell $(CC) --version))) # if it's GCC
version:=$(shell $(CC) -dumpversion)
# Turn version into words of major, minor
v:=$(subst ., ,$(version))
# concat. major minor
v:=$(word 1,$(v))$(word 2,$(v))
# If this version is not in the list, default to the latest supported
ifeq (,$(filter $(v),$(SUPPORTED_GCC_VERSIONS)))
$(info\
Your compiler version, GCC $(version), is not supported by the Makefile.\
The Makefile will assume GCC $(LATEST_GCC_VERSION).)
GCC$(subst .,,$(LATEST_GCC_VERSION))=1
else
$(info Detected GCC $(version) (GCC$(v)))
GCC$(v)=1
endif
endif
endif
ifdef GCC102
GCC101=1
endif
ifdef GCC101
GCC93=1
endif
ifdef GCC93
GCC92=1
endif
ifdef GCC92
GCC91=1
endif
ifdef GCC91
GCC84=1
endif
ifdef GCC84
GCC83=1
endif
@ -20,6 +102,18 @@ GCC81=1
endif
ifdef GCC81
GCC75=1
endif
ifdef GCC75
GCC74=1
endif
ifdef GCC74
GCC73=1
endif
ifdef GCC73
GCC72=1
endif
@ -44,6 +138,10 @@ GCC61=1
endif
ifdef GCC61
GCC55=1
endif
ifdef GCC55
GCC54=1
endif
@ -247,7 +345,7 @@ ifndef MINGW
ifndef MINGW64
ifndef SDL
ifndef DUMMY
DJGPPDOS=1
$(error No interface or platform flag defined)
endif
endif
endif
@ -257,7 +355,6 @@ endif
endif
#determine the interface directory (where you put all i_*.c)
i_cdmus_o=$(OBJDIR)/i_cdmus.o
i_net_o=$(OBJDIR)/i_net.o
i_system_o=$(OBJDIR)/i_system.o
i_sound_o=$(OBJDIR)/i_sound.o
@ -283,16 +380,6 @@ UPX_OPTS+=-q
endif
#Interface Setup
ifdef DJGPPDOS
INTERFACE=djgppdos
NASMFORMAT=coff
OBJDIR:=$(OBJDIR)/djgppdos
ifdef WATTCP
OBJDIR:=$(OBJDIR)/wattcp
endif
WFLAGS+=-Wno-format
BIN:=$(BIN)/Dos
else
ifdef DUMMY
INTERFACE=dummy
OBJDIR:=$(OBJDIR)/dummy
@ -351,37 +438,12 @@ endif
endif
endif
endif
endif
ifdef ARCHNAME
OBJDIR:=$(OBJDIR)/$(ARCHNAME)
BIN:=$(BIN)/$(ARCHNAME)
endif
# gcc or g++
ifdef PREFIX
CC=$(PREFIX)-gcc
CXX=$(PREFIX)-g++
OBJCOPY=$(PREFIX)-objcopy
OBJDUMP=$(PREFIX)-objdump
STRIP=$(PREFIX)-strip
WINDRES=$(PREFIX)-windres
else
OBJCOPY=objcopy
OBJDUMP=objdump
STRIP=strip
WINDRES=windres
endif
# because Apple screws with us on this
# need to get bintools from homebrew
ifdef MACOSX
CC=clang
CXX=clang
OBJCOPY=gobjcopy
OBJDUMP=gobjdump
endif
OBJDUMP_OPTS?=--wide --source --line-numbers
LD=$(CC)

View file

@ -920,10 +920,8 @@ static inline void AM_drawWalls(void)
{
size_t i;
static mline_t l;
#ifdef ESLOPE
fixed_t frontf1,frontf2, frontc1, frontc2; // front floor/ceiling ends
fixed_t backf1 = 0, backf2 = 0, backc1 = 0, backc2 = 0; // back floor ceiling ends
#endif
for (i = 0; i < numlines; i++)
{
@ -931,13 +929,10 @@ static inline void AM_drawWalls(void)
l.a.y = lines[i].v1->y >> FRACTOMAPBITS;
l.b.x = lines[i].v2->x >> FRACTOMAPBITS;
l.b.y = lines[i].v2->y >> FRACTOMAPBITS;
#ifdef ESLOPE
#define SLOPEPARAMS(slope, end1, end2, normalheight) \
if (slope) { \
end1 = P_GetZAt(slope, lines[i].v1->x, lines[i].v1->y); \
end2 = P_GetZAt(slope, lines[i].v2->x, lines[i].v2->y); \
} else \
end1 = end2 = normalheight;
end1 = P_GetZAt(slope, lines[i].v1->x, lines[i].v1->y, normalheight); \
end2 = P_GetZAt(slope, lines[i].v2->x, lines[i].v2->y, normalheight);
SLOPEPARAMS(lines[i].frontsector->f_slope, frontf1, frontf2, lines[i].frontsector->floorheight)
SLOPEPARAMS(lines[i].frontsector->c_slope, frontc1, frontc2, lines[i].frontsector->ceilingheight)
@ -946,7 +941,6 @@ static inline void AM_drawWalls(void)
SLOPEPARAMS(lines[i].backsector->c_slope, backc1, backc2, lines[i].backsector->ceilingheight)
}
#undef SLOPEPARAMS
#endif
if (!lines[i].backsector) // 1-sided
{
@ -955,19 +949,11 @@ static inline void AM_drawWalls(void)
else
AM_drawMline(&l, WALLCOLORS);
}
#ifdef ESLOPE
else if ((backf1 == backc1 && backf2 == backc2) // Back is thok barrier
|| (frontf1 == frontc1 && frontf2 == frontc2)) // Front is thok barrier
{
if (backf1 == backc1 && backf2 == backc2
&& frontf1 == frontc1 && frontf2 == frontc2) // BOTH are thok barriers
#else
else if (lines[i].backsector->floorheight == lines[i].backsector->ceilingheight // Back is thok barrier
|| lines[i].frontsector->floorheight == lines[i].frontsector->ceilingheight) // Front is thok barrier
{
if (lines[i].backsector->floorheight == lines[i].backsector->ceilingheight
&& lines[i].frontsector->floorheight == lines[i].frontsector->ceilingheight) // BOTH are thok barriers
#endif
{
if (lines[i].flags & ML_NOCLIMB)
AM_drawMline(&l, NOCLIMBTSWALLCOLORS);
@ -985,20 +971,10 @@ static inline void AM_drawWalls(void)
else
{
if (lines[i].flags & ML_NOCLIMB) {
#ifdef ESLOPE
if (backf1 != frontf1 || backf2 != frontf2) {
#else
if (lines[i].backsector->floorheight
!= lines[i].frontsector->floorheight) {
#endif
AM_drawMline(&l, NOCLIMBFDWALLCOLORS); // floor level change
}
#ifdef ESLOPE
else if (backc1 != frontc1 || backc2 != frontc2) {
#else
else if (lines[i].backsector->ceilingheight
!= lines[i].frontsector->ceilingheight) {
#endif
AM_drawMline(&l, NOCLIMBCDWALLCOLORS); // ceiling level change
}
else
@ -1006,20 +982,10 @@ static inline void AM_drawWalls(void)
}
else
{
#ifdef ESLOPE
if (backf1 != frontf1 || backf2 != frontf2) {
#else
if (lines[i].backsector->floorheight
!= lines[i].frontsector->floorheight) {
#endif
AM_drawMline(&l, FDWALLCOLORS); // floor level change
}
#ifdef ESLOPE
else if (backc1 != frontc1 || backc2 != frontc2) {
#else
else if (lines[i].backsector->ceilingheight
!= lines[i].frontsector->ceilingheight) {
#endif
AM_drawMline(&l, CDWALLCOLORS); // ceiling level change
}
else

View file

@ -19,10 +19,10 @@ boolean allow_fullscreen = false;
consvar_t cv_vidwait = {"vid_wait", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
void I_StartupGraphics(void){}
void I_StartupHardwareGraphics(void){}
void I_ShutdownGraphics(void){}
void VID_StartupOpenGL(void){}
void I_SetPalette(RGBA_t *palette)
{
(void)palette;
@ -52,10 +52,8 @@ INT32 VID_SetMode(INT32 modenum)
return 0;
}
void VID_CheckRenderer(void)
{
// ..............
}
void VID_CheckRenderer(void) {}
void VID_CheckGLLoaded(rendermode_t oldrender) {}
const char *VID_GetModeName(INT32 modenum)
{

View file

@ -74,11 +74,9 @@ static void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd)
if (!sonic || sonic->health <= 0)
return;
#ifdef HAVE_BLUA
// Lua can handle it!
if (LUAh_BotAI(sonic, tails, cmd))
return;
#endif
if (tails->player->powers[pw_carry] == CR_MACESPIN || tails->player->powers[pw_carry] == CR_GENERIC)
{
@ -195,7 +193,7 @@ static void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd)
{
cmd->forwardmove = pcmd->forwardmove;
cmd->sidemove = pcmd->sidemove;
if (pcmd->buttons & BT_USE)
if (pcmd->buttons & BT_SPIN)
{
spin = true;
jump = false;
@ -364,11 +362,9 @@ void B_BuildTiccmd(player_t *player, ticcmd_t *cmd)
// Bot AI isn't programmed in analog.
CV_SetValue(&cv_analog[1], false);
#ifdef HAVE_BLUA
// Let Lua scripts build ticcmds
if (LUAh_BotTiccmd(player, cmd))
return;
#endif
// We don't have any main character AI, sorry. D:
if (player-players == consoleplayer)
@ -445,7 +441,7 @@ void B_KeysToTiccmd(mobj_t *mo, ticcmd_t *cmd, boolean forward, boolean backward
if (jump)
cmd->buttons |= BT_JUMP;
if (spin)
cmd->buttons |= BT_USE;
cmd->buttons |= BT_SPIN;
}
void B_MoveBlocked(player_t *player)
@ -463,6 +459,19 @@ boolean B_CheckRespawn(player_t *player)
if (!sonic || sonic->health <= 0)
return false;
// B_RespawnBot doesn't do anything if the condition above this isn't met
{
UINT8 shouldForce = LUAh_BotRespawn(sonic, tails);
if (P_MobjWasRemoved(sonic) || P_MobjWasRemoved(tails))
return (shouldForce == 1); // mobj was removed
if (shouldForce == 1)
return true;
else if (shouldForce == 2)
return false;
}
// Check if Sonic is busy first.
// If he's doing any of these things, he probably doesn't want to see us.
if (sonic->player->pflags & (PF_GLIDING|PF_SLIDING|PF_BOUNCING)

View file

@ -10,8 +10,6 @@ WFLAGS+=-Wno-logical-op
endif
endif
OPTS+=-DHAVE_BLUA
OBJS:=$(OBJS) \
$(OBJDIR)/lapi.o \
$(OBJDIR)/lbaselib.o \

View file

@ -11,6 +11,10 @@
#include <stdlib.h>
#include <string.h>
#include "../doomdef.h"
#include "../lua_script.h"
#include "../w_wad.h"
#define lbaselib_c
#define LUA_LIB
@ -263,6 +267,27 @@ static int luaB_ipairs (lua_State *L) {
}
// Edited to load PK3 entries instead
static int luaB_dofile (lua_State *L) {
const char *filename = luaL_checkstring(L, 1);
char fullfilename[256];
UINT16 lumpnum;
int n = lua_gettop(L);
if (wadfiles[numwadfiles - 1]->type != RET_PK3)
luaL_error(L, "dofile() only works with PK3 files");
snprintf(fullfilename, sizeof(fullfilename), "Lua/%s", filename);
lumpnum = W_CheckNumForFullNamePK3(fullfilename, numwadfiles - 1, 0);
if (lumpnum == INT16_MAX)
luaL_error(L, "can't find script " LUA_QS, fullfilename);
LUA_LoadLump(numwadfiles - 1, lumpnum, false);
return lua_gettop(L) - n;
}
static int luaB_assert (lua_State *L) {
luaL_checkany(L, 1);
if (!lua_toboolean(L, 1))
@ -380,6 +405,7 @@ static const luaL_Reg base_funcs[] = {
{"assert", luaB_assert},
{"collectgarbage", luaB_collectgarbage},
{"error", luaB_error},
{"dofile", luaB_dofile},
{"gcinfo", luaB_gcinfo},
{"getfenv", luaB_getfenv},
{"getmetatable", luaB_getmetatable},

View file

@ -34,7 +34,8 @@
#define FMT_FILECALLBACKID "file_callback_%d"
static const char *whitelist[] = { // Allow scripters to write files of these types to SRB2's folder
// Allow scripters to write files of these types to SRB2's folder
static const char *whitelist[] = {
".bmp",
".cfg",
".csv",
@ -283,8 +284,16 @@ void Got_LuaFile(UINT8 **cp, INT32 playernum)
// Push the first argument (file handle or nil) on the stack
if (success)
{
char mode[4];
// Ensure we are opening in binary mode
// (if it's a text file, newlines have been converted already)
strcpy(mode, luafiletransfers->mode);
if (!strchr(mode, 'b'))
strcat(mode, "b");
pf = newfile(gL); // Create and push the file handle
*pf = fopen(luafiletransfers->realfilename, luafiletransfers->mode); // Open the file
*pf = fopen(luafiletransfers->realfilename, mode); // Open the file
if (!*pf)
I_Error("Can't open file \"%s\"\n", luafiletransfers->realfilename); // The file SHOULD exist
}
@ -312,17 +321,14 @@ void Got_LuaFile(UINT8 **cp, INT32 playernum)
RemoveLuaFileTransfer();
if (server && luafiletransfers)
if (waitingforluafilecommand)
{
if (FIL_FileOK(luafiletransfers->realfilename))
SV_PrepareSendLuaFileToNextNode();
else
{
// Send a net command with 0 as its first byte to indicate the file couldn't be opened
success = 0;
SendNetXCmd(XD_LUAFILE, &success, 1);
}
waitingforluafilecommand = false;
CL_PrepareDownloadLuaFile();
}
if (server && luafiletransfers)
SV_PrepareSendLuaFile();
}
@ -508,7 +514,6 @@ static int io_readline (lua_State *L) {
static int g_write (lua_State *L, FILE *f, int arg) {
int nargs = lua_gettop(L) - 1;
int status = 1;
size_t count;
for (; nargs--; arg++) {
if (lua_type(L, arg) == LUA_TNUMBER) {
/* optimization: could be done exactly as for strings */
@ -518,12 +523,10 @@ static int g_write (lua_State *L, FILE *f, int arg) {
else {
size_t l;
const char *s = luaL_checklstring(L, arg, &l);
count += l;
if (ftell(f) + l > FILELIMIT)
{
luaL_error(L,"write limit bypassed in file. Changes have been discarded.");
break;
}
if (ftell(f) + l > FILELIMIT) {
luaL_error(L,"write limit bypassed in file. Changes have been discarded.");
break;
}
status = status && (fwrite(s, sizeof(char), l, f) == l);
}
}

View file

@ -150,15 +150,15 @@ FUNCINLINE static ATTRINLINE UINT32 readulong(void *ptr)
#undef DEALIGNED
#define WRITESTRINGN(p,s,n) { size_t tmp_i = 0; for (; tmp_i < n && s[tmp_i] != '\0'; tmp_i++) WRITECHAR(p, s[tmp_i]); if (tmp_i < n) WRITECHAR(p, '\0');}
#define WRITESTRING(p,s) { size_t tmp_i = 0; for (; s[tmp_i] != '\0'; tmp_i++) WRITECHAR(p, s[tmp_i]); WRITECHAR(p, '\0');}
#define WRITEMEM(p,s,n) { memcpy(p, s, n); p += n; }
#define WRITESTRINGN(p,s,n) do { size_t tmp_i = 0; for (; tmp_i < n && s[tmp_i] != '\0'; tmp_i++) WRITECHAR(p, s[tmp_i]); if (tmp_i < n) WRITECHAR(p, '\0');} while (0)
#define WRITESTRING(p,s) do { size_t tmp_i = 0; for (; s[tmp_i] != '\0'; tmp_i++) WRITECHAR(p, s[tmp_i]); WRITECHAR(p, '\0');} while (0)
#define WRITEMEM(p,s,n) do { memcpy(p, s, n); p += n; } while (0)
#define SKIPSTRING(p) while (READCHAR(p) != '\0')
#define READSTRINGN(p,s,n) { size_t tmp_i = 0; for (; tmp_i < n && (s[tmp_i] = READCHAR(p)) != '\0'; tmp_i++); s[tmp_i] = '\0';}
#define READSTRING(p,s) { size_t tmp_i = 0; for (; (s[tmp_i] = READCHAR(p)) != '\0'; tmp_i++); s[tmp_i] = '\0';}
#define READMEM(p,s,n) { memcpy(s, p, n); p += n; }
#define READSTRINGN(p,s,n) ({ size_t tmp_i = 0; for (; tmp_i < n && (s[tmp_i] = READCHAR(p)) != '\0'; tmp_i++); s[tmp_i] = '\0';})
#define READSTRING(p,s) ({ size_t tmp_i = 0; for (; (s[tmp_i] = READCHAR(p)) != '\0'; tmp_i++); s[tmp_i] = '\0';})
#define READMEM(p,s,n) ({ memcpy(s, p, n); p += n; })
#if 0 // old names
#define WRITEBYTE(p,b) WRITEUINT8(p,b)

View file

@ -33,6 +33,7 @@
#include "p_setup.h"
#include "lua_script.h"
#include "d_netfil.h" // findfile
#include "r_data.h" // Color_cons_t
//========
// protos.
@ -56,7 +57,13 @@ static boolean CV_FilterVarByVersion(consvar_t *v, const char *valstr);
static boolean CV_Command(void);
consvar_t *CV_FindVar(const char *name);
static const char *CV_StringValue(const char *var_name);
static consvar_t *consvar_vars; // list of registered console variables
static UINT16 consvar_number_of_netids = 0;
#ifdef OLD22DEMOCOMPAT
static old_demo_var_t *consvar_old_demo_vars;
#endif
static char com_token[1024];
static char *COM_Parse(char *data);
@ -80,7 +87,7 @@ static boolean joyaxis2_default = false;
static INT32 joyaxis_count = 0;
static INT32 joyaxis2_count = 0;
#define COM_BUF_SIZE 8192 // command buffer size
#define COM_BUF_SIZE (32<<10) // command buffer size
#define MAX_ALIAS_RECURSION 100 // max recursion allowed for aliases
static INT32 com_wait; // one command per frame (for cmd sequences)
@ -481,13 +488,11 @@ void COM_AddCommand(const char *name, com_func_t func)
{
if (!stricmp(name, cmd->name)) //case insensitive now that we have lower and uppercase!
{
#ifdef HAVE_BLUA
// don't I_Error for Lua commands
// Lua commands can replace game commands, and they have priority.
// BUT, if for some reason we screwed up and made two console commands with the same name,
// it's good to have this here so we find out.
if (cmd->function != COM_Lua_f)
#endif
I_Error("Command %s already exists\n", name);
return;
@ -501,7 +506,6 @@ void COM_AddCommand(const char *name, com_func_t func)
com_commands = cmd;
}
#ifdef HAVE_BLUA
/** Adds a console command for Lua.
* No I_Errors allowed; return a negative code instead.
*
@ -534,7 +538,6 @@ int COM_AddLuaCommand(const char *name)
com_commands = cmd;
return 0;
}
#endif
/** Tests if a command exists.
*
@ -624,7 +627,7 @@ static void COM_ExecuteString(char *ptext)
// check cvars
// Hurdler: added at Ebola's request ;)
// (don't flood the console in software mode with bad gr_xxx command)
// (don't flood the console in software mode with bad gl_xxx command)
if (!CV_Command() && con_destlines)
CONS_Printf(M_GetText("Unknown command '%s'\n"), COM_Argv(0));
}
@ -816,6 +819,18 @@ static void COM_Help_f(void)
CONS_Printf(" Yes or No (On or Off, 1 or 0)\n");
else if (cvar->PossibleValue == CV_OnOff)
CONS_Printf(" On or Off (Yes or No, 1 or 0)\n");
else if (cvar->PossibleValue == Color_cons_t)
{
for (i = 1; i < numskincolors; ++i)
{
if (skincolors[i].accessible)
{
CONS_Printf(" %-2d : %s\n", i, skincolors[i].name);
if (i == cvar->value)
cvalue = skincolors[i].name;
}
}
}
else
{
#define MINVAL 0
@ -1125,14 +1140,16 @@ consvar_t *CV_FindVar(const char *name)
return NULL;
}
/** Builds a unique Net Variable identifier number, which is used
* in network packets instead of the full name.
#ifdef OLD22DEMOCOMPAT
/** Builds a unique Net Variable identifier number, which was used
* in network packets and demos instead of the full name.
*
* This function only still exists to keep compatibility with old demos.
*
* \param s Name of the variable.
* \return A new unique identifier.
* \sa CV_FindNetVar
*/
static inline UINT16 CV_ComputeNetid(const char *s)
static inline UINT16 CV_ComputeOldDemoID(const char *s)
{
UINT16 ret = 0, i = 0;
static UINT16 premiers[16] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53};
@ -1146,16 +1163,47 @@ static inline UINT16 CV_ComputeNetid(const char *s)
return ret;
}
/** Finds a net variable based on its old style hash. If a hash collides, a
* warning is printed and this function returns NULL.
*
* \param chk The variable's old style hash.
* \return A pointer to the variable itself if found, or NULL.
*/
static old_demo_var_t *CV_FindOldDemoVar(UINT16 chk)
{
old_demo_var_t *demovar;
for (demovar = consvar_old_demo_vars; demovar; demovar = demovar->next)
{
if (demovar->checksum == chk)
{
if (demovar->collides)
{
CONS_Alert(CONS_WARNING,
"Old demo netvar id %hu is a collision\n", chk);
return NULL;
}
return demovar;
}
}
return NULL;
}
#endif/*OLD22DEMOCOMPAT*/
/** Finds a net variable based on its identifier number.
*
* \param netid The variable's identifier number.
* \return A pointer to the variable itself if found, or NULL.
* \sa CV_ComputeNetid
*/
static consvar_t *CV_FindNetVar(UINT16 netid)
{
consvar_t *cvar;
if (netid >= consvar_number_of_netids)
return NULL;
for (cvar = consvar_vars; cvar; cvar = cvar->next)
if (cvar->netid == netid)
return cvar;
@ -1165,6 +1213,32 @@ static consvar_t *CV_FindNetVar(UINT16 netid)
static void Setvalue(consvar_t *var, const char *valstr, boolean stealth);
#ifdef OLD22DEMOCOMPAT
/* Sets up a netvar for compatibility with old demos. */
static void CV_RegisterOldDemoVar(consvar_t *variable)
{
old_demo_var_t *demovar;
UINT16 old_demo_id;
old_demo_id = CV_ComputeOldDemoID(variable->name);
demovar = CV_FindOldDemoVar(old_demo_id);
if (demovar)
demovar->collides = true;
else
{
demovar = ZZ_Calloc(sizeof *demovar);
demovar->checksum = old_demo_id;
demovar->cvar = variable;
demovar->next = consvar_old_demo_vars;
consvar_old_demo_vars = demovar;
}
}
#endif
/** Registers a variable for later use from the console.
*
* \param variable The variable to register.
@ -1188,11 +1262,15 @@ void CV_RegisterVar(consvar_t *variable)
// check net variables
if (variable->flags & CV_NETVAR)
{
const consvar_t *netvar;
variable->netid = CV_ComputeNetid(variable->name);
netvar = CV_FindNetVar(variable->netid);
if (netvar)
I_Error("Variables %s and %s have same netid\n", variable->name, netvar->name);
variable->netid = consvar_number_of_netids++;
/* in case of overflow... */
if (variable->netid > consvar_number_of_netids)
I_Error("Way too many netvars");
#ifdef OLD22DEMOCOMPAT
CV_RegisterOldDemoVar(variable);
#endif
}
// link the variable in
@ -1427,9 +1505,7 @@ finish:
}
var->flags |= CV_MODIFIED;
// raise 'on change' code
#ifdef HAVE_BLUA
LUA_CVarChanged(var->name); // let consolelib know what cvar this is.
#endif
if (var->flags & CV_CALL && !stealth)
var->func();
@ -1454,12 +1530,100 @@ badinput:
static boolean serverloading = false;
static consvar_t *
ReadNetVar (UINT8 **p, char **return_value, boolean *return_stealth)
{
UINT16 netid;
char *val;
boolean stealth;
consvar_t *cvar;
netid = READUINT16 (*p);
val = (char *)*p;
SKIPSTRING (*p);
stealth = READUINT8 (*p);
cvar = CV_FindNetVar(netid);
if (cvar)
{
(*return_value) = val;
(*return_stealth) = stealth;
DEBFILE(va("Netvar received: %s [netid=%d] value %s\n", cvar->name, netid, val));
}
else
CONS_Alert(CONS_WARNING, "Netvar not found with netid %hu\n", netid);
return cvar;
}
#ifdef OLD22DEMOCOMPAT
static consvar_t *
ReadOldDemoVar (UINT8 **p, char **return_value, boolean *return_stealth)
{
UINT16 id;
char *val;
boolean stealth;
old_demo_var_t *demovar;
id = READUINT16 (*p);
val = (char *)*p;
SKIPSTRING (*p);
stealth = READUINT8 (*p);
demovar = CV_FindOldDemoVar(id);
if (demovar)
{
(*return_value) = val;
(*return_stealth) = stealth;
return demovar->cvar;
}
else
{
CONS_Alert(CONS_WARNING, "Netvar not found with old demo id %hu\n", id);
return NULL;
}
}
#endif/*OLD22DEMOCOMPAT*/
static consvar_t *
ReadDemoVar (UINT8 **p, char **return_value, boolean *return_stealth)
{
char *name;
char *val;
boolean stealth;
consvar_t *cvar;
name = (char *)*p;
SKIPSTRING (*p);
val = (char *)*p;
SKIPSTRING (*p);
stealth = READUINT8 (*p);
cvar = CV_FindVar(name);
if (cvar)
{
(*return_value) = val;
(*return_stealth) = stealth;
}
else
CONS_Alert(CONS_WARNING, "Netvar not found with name %s\n", name);
return cvar;
}
static void Got_NetVar(UINT8 **p, INT32 playernum)
{
consvar_t *cvar;
UINT16 netid;
char *svalue;
UINT8 stealth = false;
boolean stealth;
if (playernum != serverplayer && !IsPlayerAdmin(playernum) && !serverloading)
{
@ -1469,23 +1633,14 @@ static void Got_NetVar(UINT8 **p, INT32 playernum)
SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
return;
}
netid = READUINT16(*p);
cvar = CV_FindNetVar(netid);
svalue = (char *)*p;
SKIPSTRING(*p);
stealth = READUINT8(*p);
if (!cvar)
{
CONS_Alert(CONS_WARNING, "Netvar not found with netid %hu\n", netid);
return;
}
DEBFILE(va("Netvar received: %s [netid=%d] value %s\n", cvar->name, netid, svalue));
cvar = ReadNetVar(p, &svalue, &stealth);
Setvalue(cvar, svalue, stealth);
if (cvar)
Setvalue(cvar, svalue, stealth);
}
void CV_SaveNetVars(UINT8 **p)
void CV_SaveVars(UINT8 **p, boolean in_demo)
{
consvar_t *cvar;
UINT8 *count_p = *p;
@ -1497,7 +1652,10 @@ void CV_SaveNetVars(UINT8 **p)
for (cvar = consvar_vars; cvar; cvar = cvar->next)
if ((cvar->flags & CV_NETVAR) && !CV_IsSetToDefault(cvar))
{
WRITEUINT16(*p, cvar->netid);
if (in_demo)
WRITESTRING(*p, cvar->name);
else
WRITEUINT16(*p, cvar->netid);
WRITESTRING(*p, cvar->string);
WRITEUINT8(*p, false);
++count;
@ -1505,11 +1663,15 @@ void CV_SaveNetVars(UINT8 **p)
WRITEUINT16(count_p, count);
}
void CV_LoadNetVars(UINT8 **p)
static void CV_LoadVars(UINT8 **p,
consvar_t *(*got)(UINT8 **p, char **ret_value, boolean *ret_stealth))
{
consvar_t *cvar;
UINT16 count;
char *val;
boolean stealth;
// prevent "invalid command received"
serverloading = true;
@ -1519,11 +1681,33 @@ void CV_LoadNetVars(UINT8 **p)
count = READUINT16(*p);
while (count--)
Got_NetVar(p, 0);
{
cvar = (*got)(p, &val, &stealth);
if (cvar)
Setvalue(cvar, val, stealth);
}
serverloading = false;
}
void CV_LoadNetVars(UINT8 **p)
{
CV_LoadVars(p, ReadNetVar);
}
#ifdef OLD22DEMOCOMPAT
void CV_LoadOldDemoVars(UINT8 **p)
{
CV_LoadVars(p, ReadOldDemoVar);
}
#endif
void CV_LoadDemoVars(UINT8 **p)
{
CV_LoadVars(p, ReadDemoVar);
}
static void CV_SetCVar(consvar_t *var, const char *value, boolean stealth);
void CV_ResetCheatNetVars(void)
@ -1580,7 +1764,7 @@ static void CV_SetCVar(consvar_t *var, const char *value, boolean stealth)
// send the value of the variable
UINT8 buf[128];
UINT8 *p = buf;
if (!(server || (IsPlayerAdmin(consoleplayer))))
if (!(server || (addedtogame && IsPlayerAdmin(consoleplayer))))
{
CONS_Printf(M_GetText("Only the server or admin can change: %s %s\n"), var->name, var->string);
return;

View file

@ -144,6 +144,19 @@ typedef struct consvar_s //NULL, NULL, 0, NULL, NULL |, 0, NULL, NULL, 0, 0, NUL
struct consvar_s *next;
} consvar_t;
#ifdef OLD22DEMOCOMPAT
typedef struct old_demo_var old_demo_var_t;
struct old_demo_var
{
UINT16 checksum;
boolean collides;/* this var is a collision of multiple hashes */
consvar_t *cvar;
old_demo_var_t *next;
};
#endif/*OLD22DEMOCOMPAT*/
extern CV_PossibleValue_t CV_OnOff[];
extern CV_PossibleValue_t CV_YesNo[];
extern CV_PossibleValue_t CV_Unsigned[];
@ -184,9 +197,18 @@ void CV_AddValue(consvar_t *var, INT32 increment);
void CV_SaveVariables(FILE *f);
// load/save gamesate (load and save option and for network join in game)
void CV_SaveNetVars(UINT8 **p);
void CV_SaveVars(UINT8 **p, boolean in_demo);
#define CV_SaveNetVars(p) CV_SaveVars(p, false)
void CV_LoadNetVars(UINT8 **p);
#define CV_SaveDemoVars(p) CV_SaveVars(p, true)
void CV_LoadDemoVars(UINT8 **p);
#ifdef OLD22DEMOCOMPAT
void CV_LoadOldDemoVars(UINT8 **p);
#endif
// reset cheat netvars after cheats is deactivated
void CV_ResetCheatNetVars(void);

View file

@ -28,12 +28,16 @@
/* Manually defined asset hashes for non-CMake builds
* Last updated 2020 / 02 / 15 - v2.2.1 - main assets
* Last updated 2020 / 02 / 22 - v2.2.2 - patch.pk3
* Last updated 2020 / 05 / 10 - v2.2.3 - player.dta & patch.pk3
* Last updated 2020 / 05 / 11 - v2.2.4 - patch.pk3
* Last updated 2020 / 07 / 07 - v2.2.5 - player.dta & patch.pk3
* Last updated 2020 / 07 / 10 - v2.2.6 - player.dta & patch.pk3
*/
#define ASSET_HASH_SRB2_PK3 "0277c9416756627004e83cbb5b2e3e28"
#define ASSET_HASH_ZONES_PK3 "f7e88afb6af7996a834c7d663144bead"
#define ASSET_HASH_PLAYER_DTA "ad49e07b17cc662f1ad70c454910b4ae"
#define ASSET_HASH_PLAYER_DTA "49dad7b24634c89728cc3e0b689e12bb"
#ifdef USE_PATCH_DTA
#define ASSET_HASH_PATCH_PK3 "ee54330ecb743314c5f962af4db731ff"
#define ASSET_HASH_PATCH_PK3 "ecf00060f03c76b3e49c6ae3925b627f"
#endif
#endif

View file

@ -29,6 +29,7 @@
#include "i_video.h"
#include "z_zone.h"
#include "i_system.h"
#include "i_threads.h"
#include "d_main.h"
#include "m_menu.h"
#include "filesrch.h"
@ -44,6 +45,16 @@
#define MAXHUDLINES 20
#ifdef HAVE_THREADS
I_mutex con_mutex;
# define Lock_state() I_lock_mutex(&con_mutex)
# define Unlock_state() I_unlock_mutex(con_mutex)
#else/*HAVE_THREADS*/
# define Lock_state()
# define Unlock_state()
#endif/*HAVE_THREADS*/
static boolean con_started = false; // console has been initialised
boolean con_startup = false; // true at game startup, screen need refreshing
static boolean con_forcepic = true; // at startup toggle console translucency when first off
@ -97,6 +108,7 @@ static void CON_InputInit(void);
static void CON_RecalcSize(void);
static void CON_ChangeHeight(void);
static void CON_DrawBackpic(void);
static void CONS_hudlines_Change(void);
static void CONS_backcolor_Change(void);
@ -149,6 +161,8 @@ static void CONS_hudlines_Change(void)
{
INT32 i;
Lock_state();
// Clear the currently displayed lines
for (i = 0; i < con_hudlines; i++)
con_hudtime[i] = 0;
@ -160,6 +174,8 @@ static void CONS_hudlines_Change(void)
con_hudlines = cons_hudlines.value;
Unlock_state();
CONS_Printf(M_GetText("Number of console HUD lines is now %d\n"), con_hudlines);
}
@ -167,12 +183,16 @@ static void CONS_hudlines_Change(void)
//
static void CONS_Clear_f(void)
{
Lock_state();
memset(con_buffer, 0, CON_BUFFERSIZE);
con_cx = 0;
con_cy = con_totallines-1;
con_line = &con_buffer[con_cy*con_width];
con_scrollup = 0;
Unlock_state();
}
// Choose english keymap
@ -376,20 +396,29 @@ void CON_Init(void)
for (i = 0; i < NUMINPUTS; i++)
bindtable[i] = NULL;
Lock_state();
// clear all lines
memset(con_buffer, 0, CON_BUFFERSIZE);
// make sure it is ready for the loading screen
con_width = 0;
Unlock_state();
CON_RecalcSize();
CON_SetupColormaps();
Lock_state();
//note: CON_Ticker should always execute at least once before D_Display()
con_clipviewtop = -1; // -1 does not clip
con_hudlines = atoi(cons_hudlines.defaultvalue);
Unlock_state();
// setup console input filtering
CON_InputInit();
@ -398,15 +427,23 @@ void CON_Init(void)
COM_AddCommand("cls", CONS_Clear_f);
//COM_AddCommand("english", CONS_English_f);
// set console full screen for game startup MAKE SURE VID_Init() done !!!
Lock_state();
con_destlines = vid.height;
con_curlines = vid.height;
Unlock_state();
if (!dedicated)
{
Lock_state();
con_started = true;
con_startup = true; // need explicit screen refresh until we are in Doom loop
consoletoggle = false;
Unlock_state();
CV_RegisterVar(&cons_msgtimeout);
CV_RegisterVar(&cons_hudlines);
CV_RegisterVar(&cons_speed);
@ -417,19 +454,27 @@ void CON_Init(void)
}
else
{
Lock_state();
con_started = true;
con_startup = false; // need explicit screen refresh until we are in Doom loop
consoletoggle = true;
Unlock_state();
}
}
// Console input initialization
//
static void CON_InputInit(void)
{
Lock_state();
// prepare the first prompt line
memset(inputlines, 0, sizeof (inputlines));
inputline = 0;
input_cur = input_sel = input_len = 0;
Unlock_state();
}
//======================================================================
@ -445,6 +490,8 @@ static void CON_RecalcSize(void)
char *tmp_buffer;
char *string;
Lock_state();
switch (cv_constextsize.value)
{
case V_NOSCALEPATCH:
@ -482,11 +529,18 @@ static void CON_RecalcSize(void)
// check for change of video width
if (conw == con_width)
{
Unlock_state();
return; // didn't change
}
Unlock_state();
tmp_buffer = Z_Malloc(CON_BUFFERSIZE, PU_STATIC, NULL);
string = Z_Malloc(CON_BUFFERSIZE, PU_STATIC, NULL); // BP: it is a line but who know
Lock_state();
oldcon_width = con_width;
oldnumlines = con_totallines;
oldcon_cy = con_cy;
@ -507,6 +561,8 @@ static void CON_RecalcSize(void)
con_line = &con_buffer[con_cy*con_width];
con_scrollup = 0;
Unlock_state();
// re-arrange console text buffer to keep text
if (oldcon_width) // not the first time
{
@ -531,7 +587,11 @@ static void CON_RecalcSize(void)
static void CON_ChangeHeight(void)
{
INT32 minheight = 20 * con_scalefactor; // 20 = 8+8+4
INT32 minheight;
Lock_state();
minheight = 20 * con_scalefactor; // 20 = 8+8+4
// toggle console in
con_destlines = (cons_height.value*vid.height)/100;
@ -541,13 +601,19 @@ static void CON_ChangeHeight(void)
con_destlines = vid.height;
con_destlines &= ~0x3; // multiple of text row height
Unlock_state();
}
// Handles Console moves in/out of screen (per frame)
//
static void CON_MoveConsole(void)
{
const fixed_t conspeed = FixedDiv(cons_speed.value*vid.fdupy, FRACUNIT);
fixed_t conspeed;
Lock_state();
conspeed = FixedDiv(cons_speed.value*vid.fdupy, FRACUNIT);
// instant
if (!cons_speed.value)
@ -569,6 +635,8 @@ static void CON_MoveConsole(void)
if (con_curlines < con_destlines)
con_curlines = con_destlines;
}
Unlock_state();
}
// Clear time of console heads up messages
@ -577,16 +645,25 @@ void CON_ClearHUD(void)
{
INT32 i;
Lock_state();
for (i = 0; i < con_hudlines; i++)
con_hudtime[i] = 0;
Unlock_state();
}
// Force console to move out immediately
// note: con_ticker will set consoleready false
void CON_ToggleOff(void)
{
Lock_state();
if (!con_destlines)
{
Unlock_state();
return;
}
con_destlines = 0;
con_curlines = 0;
@ -595,11 +672,19 @@ void CON_ToggleOff(void)
con_clipviewtop = -1; // remove console clipping of view
I_UpdateMouseGrab();
Unlock_state();
}
boolean CON_Ready(void)
{
return consoleready;
boolean ready;
Lock_state();
{
ready = consoleready;
}
Unlock_state();
return ready;
}
// Console ticker: handles console move in/out, cursor blinking
@ -607,7 +692,11 @@ boolean CON_Ready(void)
void CON_Ticker(void)
{
INT32 i;
INT32 minheight = 20 * con_scalefactor; // 20 = 8+8+4
INT32 minheight;
Lock_state();
minheight = 20 * con_scalefactor; // 20 = 8+8+4
// cursor blinking
con_tick++;
@ -658,6 +747,8 @@ void CON_Ticker(void)
if (con_hudtime[i] < 0)
con_hudtime[i] = 0;
}
Unlock_state();
}
//
@ -669,32 +760,51 @@ void CON_Ticker(void)
static void CON_InputClear(void)
{
Lock_state();
memset(inputlines[inputline], 0, CON_MAXPROMPTCHARS);
input_cur = input_sel = input_len = 0;
Unlock_state();
}
static void CON_InputSetString(const char *c)
{
Lock_state();
memset(inputlines[inputline], 0, CON_MAXPROMPTCHARS);
strcpy(inputlines[inputline], c);
input_cur = input_sel = input_len = strlen(c);
Unlock_state();
}
static void CON_InputAddString(const char *c)
{
size_t csize = strlen(c);
Lock_state();
if (input_len + csize > CON_MAXPROMPTCHARS-1)
{
Unlock_state();
return;
}
if (input_cur != input_len)
memmove(&inputlines[inputline][input_cur+csize], &inputlines[inputline][input_cur], input_len-input_cur);
memcpy(&inputlines[inputline][input_cur], c, csize);
input_len += csize;
input_sel = (input_cur += csize);
Unlock_state();
}
static void CON_InputDelSelection(void)
{
size_t start, end, len;
Lock_state();
if (input_cur > input_sel)
{
start = input_sel;
@ -713,27 +823,39 @@ static void CON_InputDelSelection(void)
input_len -= len;
input_sel = input_cur = start;
Unlock_state();
}
static void CON_InputAddChar(char c)
{
if (input_len >= CON_MAXPROMPTCHARS-1)
return;
Lock_state();
if (input_cur != input_len)
memmove(&inputlines[inputline][input_cur+1], &inputlines[inputline][input_cur], input_len-input_cur);
inputlines[inputline][input_cur++] = c;
inputlines[inputline][++input_len] = 0;
input_sel = input_cur;
Unlock_state();
}
static void CON_InputDelChar(void)
{
if (!input_cur)
return;
Lock_state();
if (input_cur != input_len)
memmove(&inputlines[inputline][input_cur-1], &inputlines[inputline][input_cur], input_len-input_cur);
inputlines[inputline][--input_len] = 0;
input_sel = --input_cur;
Unlock_state();
}
//
@ -769,7 +891,7 @@ boolean CON_Responder(event_t *ev)
// check for console toggle key
if (ev->type != ev_console)
{
if (modeattacking || metalrecording)
if (modeattacking || metalrecording || marathonmode)
return false;
if (key == gamecontrol[gc_console][0] || key == gamecontrol[gc_console][1])
@ -834,6 +956,44 @@ boolean CON_Responder(event_t *ev)
return true;
}
// backspace and delete command prompt
if (input_sel != input_cur)
{
if (key == KEY_BACKSPACE || key == KEY_DEL)
{
CON_InputDelSelection();
return true;
}
}
else if (key == KEY_BACKSPACE)
{
if (ctrldown)
{
input_sel = M_JumpWordReverse(inputlines[inputline], input_cur);
CON_InputDelSelection();
}
else
CON_InputDelChar();
return true;
}
else if (key == KEY_DEL)
{
if (input_cur == input_len)
return true;
if (ctrldown)
{
input_sel = input_cur + M_JumpWord(&inputlines[inputline][input_cur]);
CON_InputDelSelection();
}
else
{
++input_cur;
CON_InputDelChar();
}
return true;
}
// ctrl modifier -- changes behavior, adds shortcuts
if (ctrldown)
{
@ -1024,29 +1184,6 @@ boolean CON_Responder(event_t *ev)
return true;
}
// backspace and delete command prompt
if (input_sel != input_cur)
{
if (key == KEY_BACKSPACE || key == KEY_DEL)
{
CON_InputDelSelection();
return true;
}
}
else if (key == KEY_BACKSPACE)
{
CON_InputDelChar();
return true;
}
else if (key == KEY_DEL)
{
if (input_cur == input_len)
return true;
++input_cur;
CON_InputDelChar();
return true;
}
// move back in input history
if (key == KEY_UPARROW)
{
@ -1152,6 +1289,8 @@ static void CON_Print(char *msg)
S_StartSound(NULL, sfx_radio);
}
Lock_state();
if (!(*msg & 0x80))
{
con_line[con_cx++] = '\x80';
@ -1212,7 +1351,10 @@ static void CON_Print(char *msg)
}
if (*msg == '\0')
{
Unlock_state();
return;
}
// printable character
for (l = 0; l < (con_width-11) && msg[l] > ' '; l++)
@ -1230,6 +1372,8 @@ static void CON_Print(char *msg)
for (; l > 0; l--)
con_line[con_cx++] = *(msg++);
}
Unlock_state();
}
void CON_LogMessage(const char *msg)
@ -1261,6 +1405,7 @@ void CONS_Printf(const char *fmt, ...)
{
va_list argptr;
static char *txt = NULL;
boolean startup;
if (txt == NULL)
txt = malloc(8192);
@ -1272,27 +1417,22 @@ void CONS_Printf(const char *fmt, ...)
// echo console prints to log file
DEBFILE(txt);
if (!con_started)
{
#ifdef PC_DOS
CON_LogMessage(txt);
free(txt);
return;
#endif
}
else
// write message in con text buffer
// write message in con text buffer
if (con_started)
CON_Print(txt);
#ifndef PC_DOS
CON_LogMessage(txt);
#endif
CON_LogMessage(txt);
Lock_state();
// make sure new text is visible
con_scrollup = 0;
startup = con_startup;
Unlock_state();
// if not in display loop, force screen update
if (con_startup && (!setrenderneeded))
if (startup && (!setrenderneeded))
{
#ifdef _WINDOWS
patch_t *con_backpic = W_CachePatchName("CONSBACK", PU_PATCH);
@ -1530,6 +1670,51 @@ static void CON_DrawHudlines(void)
con_clearlines = y; // this is handled by HU_Erase();
}
// Lactozilla: Draws the console's background picture.
static void CON_DrawBackpic(void)
{
patch_t *con_backpic;
lumpnum_t piclump;
int x, w, h;
// Get the lumpnum for CONSBACK, or fallback into MISSING.
piclump = W_CheckNumForName("CONSBACK");
if (piclump == LUMPERROR)
piclump = W_GetNumForName("MISSING");
// Cache the Software patch.
con_backpic = W_CacheSoftwarePatchNum(piclump, PU_PATCH);
// Center the backpic, and draw a vertically cropped patch.
w = (con_backpic->width * vid.dupx);
x = (vid.width / 2) - (w / 2);
h = con_curlines/vid.dupy;
// If the patch doesn't fill the entire screen,
// then fill the sides with a solid color.
if (x > 0)
{
column_t *column = (column_t *)((UINT8 *)(con_backpic) + LONG(con_backpic->columnofs[0]));
if (!column->topdelta)
{
UINT8 *source = (UINT8 *)(column) + 3;
INT32 color = (source[0] | V_NOSCALESTART);
// left side
V_DrawFill(0, 0, x, con_curlines, color);
// right side
V_DrawFill((x + w), 0, (vid.width - w), con_curlines, color);
}
}
// Cache the patch normally.
con_backpic = W_CachePatchNum(piclump, PU_PATCH);
V_DrawCroppedPatch(x << FRACBITS, 0, FRACUNIT, V_NOSCALESTART, con_backpic,
0, ( BASEVIDHEIGHT - h ), BASEVIDWIDTH, h);
// Unlock the cached patch.
W_UnlockCachedPatch(con_backpic);
}
// draw the console background, text, and prompt if enough place
//
static void CON_DrawConsole(void)
@ -1551,19 +1736,7 @@ static void CON_DrawConsole(void)
// draw console background
if (cons_backpic.value || con_forcepic)
{
patch_t *con_backpic = W_CachePatchName("CONSBACK", PU_PATCH);
int h;
h = con_curlines/vid.dupy;
// Jimita: CON_DrawBackpic just called V_DrawScaledPatch
//V_DrawScaledPatch(0, 0, 0, con_backpic);
V_DrawCroppedPatch(0, 0, FRACUNIT, 0, con_backpic,
0, ( BASEVIDHEIGHT - h ), BASEVIDWIDTH, h);
W_UnlockCachedPatch(con_backpic);
}
CON_DrawBackpic();
else
{
// inu: no more width (was always 0 and vid.width)
@ -1611,14 +1784,16 @@ static void CON_DrawConsole(void)
//
void CON_Drawer(void)
{
Lock_state();
if (!con_started || !graphics_started)
{
Unlock_state();
return;
}
if (needpatchrecache)
{
W_FlushCachedPatches();
HU_LoadGraphics();
}
if (con_recalc)
{
@ -1633,4 +1808,6 @@ void CON_Drawer(void)
|| gamestate == GS_INTERMISSION || gamestate == GS_ENDING || gamestate == GS_CUTSCENE
|| gamestate == GS_CREDITS || gamestate == GS_EVALUATION)
CON_DrawHudlines();
Unlock_state();
}

View file

@ -12,11 +12,16 @@
#include "d_event.h"
#include "command.h"
#include "i_threads.h"
void CON_Init(void);
boolean CON_Responder(event_t *ev);
#ifdef HAVE_THREADS
extern I_mutex con_mutex;
#endif
// set true when screen size has changed, to adapt console
extern boolean con_recalc;

File diff suppressed because it is too large Load diff

View file

@ -18,16 +18,14 @@
#include "d_net.h"
#include "tables.h"
#include "d_player.h"
#include "mserv.h"
/*
The 'packet version' may be used with packets whose
format is expected to change between versions.
This version is independent of the mod name, and standard
version and subversion. It should only account for the
basic fields of the packet, and change infrequently.
The 'packet version' is used to distinguish packet formats.
This version is independent of VERSION and SUBVERSION. Different
applications may follow different packet versions.
*/
#define PACKETVERSION 2
#define PACKETVERSION 3
// Network play related stuff.
// There is a data struct that stores network
@ -36,7 +34,8 @@ basic fields of the packet, and change infrequently.
// be transmitted.
// Networking and tick handling related.
#define BACKUPTICS 32
#define BACKUPTICS 1024
#define CLIENTBACKUPTICS 32
#define MAXTEXTCMD 256
//
// Packet structure
@ -69,11 +68,9 @@ typedef enum
PT_CANRECEIVEGAMESTATE, // Okay Server, I'm ready to receive it, you can go ahead.
PT_RECEIVEDGAMESTATE, // Thank you Server, I am ready to play again!
#ifdef HAVE_BLUA
PT_SENDINGLUAFILE, // Server telling a client Lua needs to open a file
PT_ASKLUAFILE, // Client telling the server they don't have the file
PT_HASLUAFILE, // Client telling the server they have the file
#endif
// Add non-PT_CANFAIL packet types here to avoid breaking MS compatibility.
@ -82,6 +79,8 @@ typedef enum
// In addition, this packet can't occupy all the available slots.
PT_FILEFRAGMENT = PT_CANFAIL, // A part of a file.
PT_FILEACK,
PT_FILERECEIVED,
PT_TEXTCMD, // Extra text commands from the client.
PT_TEXTCMD2, // Splitscreen text commands.
@ -133,7 +132,7 @@ typedef struct
// this packet is too large
typedef struct
{
UINT8 starttic;
tic_t starttic;
UINT8 numtics;
UINT8 numslots; // "Slots filled": Highest player number in use plus one.
ticcmd_t cmds[45]; // Normally [BACKUPTIC][MAXPLAYERS] but too large
@ -158,13 +157,30 @@ typedef struct
char server_context[8]; // Unique context id, generated at server startup.
} ATTRPACK serverconfig_pak;
typedef struct {
typedef struct
{
UINT8 fileid;
UINT32 filesize;
UINT8 iteration;
UINT32 position;
UINT16 size;
UINT8 data[0]; // Size is variable using hardware_MAXPACKETLENGTH
} ATTRPACK filetx_pak;
typedef struct
{
UINT32 start;
UINT32 acks;
} ATTRPACK fileacksegment_t;
typedef struct
{
UINT8 fileid;
UINT8 iteration;
UINT8 numsegments;
fileacksegment_t segments[0];
} ATTRPACK fileack_pak;
#ifdef _MSC_VER
#pragma warning(default : 4200)
#endif
@ -200,6 +216,7 @@ typedef struct
UINT8 subversion;
UINT8 numberofplayer;
UINT8 maxplayer;
UINT8 refusereason; // 0: joinable, 1: joins disabled, 2: full
char gametypename[24];
UINT8 modifiedgame;
UINT8 cheatsenabled;
@ -251,7 +268,7 @@ typedef struct
{
char name[MAXPLAYERNAME+1];
UINT8 skin;
UINT8 color;
UINT16 color;
UINT32 pflags;
UINT32 score;
UINT8 ctfteam;
@ -276,6 +293,8 @@ typedef struct
serverconfig_pak servercfg; // 773 bytes
UINT8 textcmd[MAXTEXTCMD+1]; // 66049 bytes (wut??? 64k??? More like 257 bytes...)
filetx_pak filetxpak; // 139 bytes
fileack_pak fileack;
UINT8 filereceived;
clientconfig_pak clientcfg; // 136 bytes
UINT8 md5sum[16];
serverinfo_pak serverinfo; // 1024 bytes
@ -335,6 +354,7 @@ typedef enum
} kickreason_t;
extern boolean server;
extern boolean serverrunning;
#define client (!server)
extern boolean dedicated; // For dedicated server
extern UINT16 software_MAXPACKETLENGTH;
@ -349,12 +369,12 @@ extern UINT32 realpingtable[MAXPLAYERS];
extern UINT32 playerpingtable[MAXPLAYERS];
extern tic_t servermaxping;
extern consvar_t cv_allownewplayer, cv_joinnextround, cv_maxplayers, cv_rejointimeout;
extern consvar_t cv_netticbuffer, cv_allownewplayer, cv_joinnextround, cv_maxplayers, cv_joindelay, cv_rejointimeout;
extern consvar_t cv_resynchattempts, cv_blamecfail;
extern consvar_t cv_maxsend, cv_noticedownload, cv_downloadspeed;
// Used in d_net, the only dependence
tic_t ExpandTics(INT32 low);
tic_t ExpandTics(INT32 low, INT32 node);
void D_ClientServerInit(void);
// Initialise the other field
@ -368,13 +388,13 @@ void NetUpdate(void);
void SV_StartSinglePlayerServer(void);
boolean SV_SpawnServer(void);
void SV_SpawnPlayer(INT32 playernum, INT32 x, INT32 y, angle_t angle);
void SV_StopServer(void);
void SV_ResetServer(void);
void CL_AddSplitscreenPlayer(void);
void CL_RemoveSplitscreenPlayer(void);
void CL_Reset(void);
void CL_ClearPlayer(INT32 playernum);
void CL_QueryServerList(msg_server_t *list);
void CL_UpdateServerList(boolean internetsearch, INT32 room);
// Is there a game running
boolean Playing(void);

View file

@ -24,12 +24,6 @@
#include <unistd.h> // for getcwd
#endif
#ifdef PC_DOS
#include <stdio.h> // for snprintf
int snprintf(char *str, size_t n, const char *fmt, ...);
//int vsnprintf(char *str, size_t n, const char *fmt, va_list ap);
#endif
#ifdef _WIN32
#include <direct.h>
#include <malloc.h>
@ -46,6 +40,7 @@ int snprintf(char *str, size_t n, const char *fmt, ...);
#include "hu_stuff.h"
#include "i_sound.h"
#include "i_system.h"
#include "i_threads.h"
#include "i_video.h"
#include "m_argv.h"
#include "m_menu.h"
@ -91,9 +86,11 @@ int snprintf(char *str, size_t n, const char *fmt, ...);
#include "hardware/hw3sound.h"
#endif
#ifdef HAVE_BLUA
#include "lua_script.h"
#endif
// Version numbers for netplay :upside_down_face:
int VERSION;
int SUBVERSION;
// platform independant focus loss
UINT8 window_notinfocus = false;
@ -127,6 +124,12 @@ boolean advancedemo;
INT32 debugload = 0;
#endif
UINT16 numskincolors;
menucolor_t *menucolorhead, *menucolortail;
char savegamename[256];
char liveeventbackup[256];
char srb2home[256] = ".";
char srb2path[256] = ".";
boolean usehome = true;
@ -154,10 +157,6 @@ void D_PostEvent(const event_t *ev)
events[eventhead] = *ev;
eventhead = (eventhead+1) & (MAXEVENTS-1);
}
// just for lock this function
#if defined (PC_DOS) && !defined (DOXYGEN)
void D_PostEvent_end(void) {};
#endif
// modifier keys
// Now handled in I_OsPolling
@ -174,6 +173,8 @@ void D_ProcessEvents(void)
{
event_t *ev;
boolean eaten;
for (; eventtail != eventhead; eventtail = (eventtail+1) & (MAXEVENTS-1))
{
ev = &events[eventtail];
@ -189,11 +190,31 @@ void D_ProcessEvents(void)
}
// Menu input
if (M_Responder(ev))
#ifdef HAVE_THREADS
I_lock_mutex(&m_menu_mutex);
#endif
{
eaten = M_Responder(ev);
}
#ifdef HAVE_THREADS
I_unlock_mutex(m_menu_mutex);
#endif
if (eaten)
continue; // menu ate the event
// console input
if (CON_Responder(ev))
#ifdef HAVE_THREADS
I_lock_mutex(&con_mutex);
#endif
{
eaten = CON_Responder(ev);
}
#ifdef HAVE_THREADS
I_unlock_mutex(con_mutex);
#endif
if (eaten)
continue; // ate the event
G_Responder(ev);
@ -312,7 +333,9 @@ static void D_Display(void)
F_WipeStartScreen();
// Check for Mega Genesis fade
wipestyleflags = WSF_FADEOUT;
if (F_TryColormapFade(31))
if (wipegamestate == (gamestate_t)FORCEWIPE)
F_WipeColorFill(31);
else if (F_TryColormapFade(31))
wipetypepost = -1; // Don't run the fade below this one
F_WipeEndScreen();
F_RunWipe(wipetypepre, gamestate != GS_TIMEATTACK && gamestate != GS_TITLESCREEN);
@ -411,6 +434,7 @@ static void D_Display(void)
if (!automapactive && !dedicated && cv_renderview.value)
{
rs_rendercalltime = I_GetTimeMicros();
if (players[displayplayer].mo || players[displayplayer].playerstate == PST_DEAD)
{
topleft = screens[0] + viewwindowy*vid.width + viewwindowx;
@ -457,6 +481,7 @@ static void D_Display(void)
if (postimgtype2)
V_DoPostProcessor(1, postimgtype2, postimgparam2);
}
rs_rendercalltime = I_GetTimeMicros() - rs_rendercalltime;
}
if (lastdraw)
@ -508,7 +533,13 @@ static void D_Display(void)
// vid size change is now finished if it was on...
vid.recalc = 0;
#ifdef HAVE_THREADS
I_lock_mutex(&m_menu_mutex);
#endif
M_Drawer(); // menu is drawn even on top of everything
#ifdef HAVE_THREADS
I_unlock_mutex(m_menu_mutex);
#endif
// focus lost moved to M_Drawer
CON_Drawer();
@ -592,22 +623,96 @@ static void D_Display(void)
V_DrawRightAlignedString(BASEVIDWIDTH, BASEVIDHEIGHT-ST_HEIGHT-10, V_YELLOWMAP, s);
}
if (cv_renderstats.value)
{
char s[50];
int frametime = I_GetTimeMicros() - rs_prevframetime;
int divisor = 1;
rs_prevframetime = I_GetTimeMicros();
if (rs_rendercalltime > 10000) divisor = 1000;
snprintf(s, sizeof s - 1, "ft %d", frametime / divisor);
V_DrawThinString(30, 10, V_MONOSPACE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "rtot %d", rs_rendercalltime / divisor);
V_DrawThinString(30, 20, V_MONOSPACE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "bsp %d", rs_bsptime / divisor);
V_DrawThinString(30, 30, V_MONOSPACE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "nbsp %d", rs_numbspcalls);
V_DrawThinString(80, 10, V_MONOSPACE | V_BLUEMAP, s);
snprintf(s, sizeof s - 1, "nspr %d", rs_numsprites);
V_DrawThinString(80, 20, V_MONOSPACE | V_BLUEMAP, s);
snprintf(s, sizeof s - 1, "nnod %d", rs_numdrawnodes);
V_DrawThinString(80, 30, V_MONOSPACE | V_BLUEMAP, s);
snprintf(s, sizeof s - 1, "npob %d", rs_numpolyobjects);
V_DrawThinString(80, 40, V_MONOSPACE | V_BLUEMAP, s);
if (rendermode == render_opengl) // OpenGL specific stats
{
snprintf(s, sizeof s - 1, "nsrt %d", rs_hw_nodesorttime / divisor);
V_DrawThinString(30, 40, V_MONOSPACE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "ndrw %d", rs_hw_nodedrawtime / divisor);
V_DrawThinString(30, 50, V_MONOSPACE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "ssrt %d", rs_hw_spritesorttime / divisor);
V_DrawThinString(30, 60, V_MONOSPACE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "sdrw %d", rs_hw_spritedrawtime / divisor);
V_DrawThinString(30, 70, V_MONOSPACE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "fin %d", rs_swaptime / divisor);
V_DrawThinString(30, 80, V_MONOSPACE | V_YELLOWMAP, s);
if (cv_glbatching.value)
{
snprintf(s, sizeof s - 1, "bsrt %d", rs_hw_batchsorttime / divisor);
V_DrawThinString(80, 55, V_MONOSPACE | V_REDMAP, s);
snprintf(s, sizeof s - 1, "bdrw %d", rs_hw_batchdrawtime / divisor);
V_DrawThinString(80, 65, V_MONOSPACE | V_REDMAP, s);
snprintf(s, sizeof s - 1, "npol %d", rs_hw_numpolys);
V_DrawThinString(130, 10, V_MONOSPACE | V_PURPLEMAP, s);
snprintf(s, sizeof s - 1, "ndc %d", rs_hw_numcalls);
V_DrawThinString(130, 20, V_MONOSPACE | V_PURPLEMAP, s);
snprintf(s, sizeof s - 1, "nshd %d", rs_hw_numshaders);
V_DrawThinString(130, 30, V_MONOSPACE | V_PURPLEMAP, s);
snprintf(s, sizeof s - 1, "nvrt %d", rs_hw_numverts);
V_DrawThinString(130, 40, V_MONOSPACE | V_PURPLEMAP, s);
snprintf(s, sizeof s - 1, "ntex %d", rs_hw_numtextures);
V_DrawThinString(185, 10, V_MONOSPACE | V_PURPLEMAP, s);
snprintf(s, sizeof s - 1, "npf %d", rs_hw_numpolyflags);
V_DrawThinString(185, 20, V_MONOSPACE | V_PURPLEMAP, s);
snprintf(s, sizeof s - 1, "ncol %d", rs_hw_numcolors);
V_DrawThinString(185, 30, V_MONOSPACE | V_PURPLEMAP, s);
}
}
else // software specific stats
{
snprintf(s, sizeof s - 1, "prtl %d", rs_sw_portaltime / divisor);
V_DrawThinString(30, 40, V_MONOSPACE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "plns %d", rs_sw_planetime / divisor);
V_DrawThinString(30, 50, V_MONOSPACE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "mskd %d", rs_sw_maskedtime / divisor);
V_DrawThinString(30, 60, V_MONOSPACE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "fin %d", rs_swaptime / divisor);
V_DrawThinString(30, 70, V_MONOSPACE | V_YELLOWMAP, s);
}
}
rs_swaptime = I_GetTimeMicros();
I_FinishUpdate(); // page flip or blit buffer
rs_swaptime = I_GetTimeMicros() - rs_swaptime;
}
needpatchflush = false;
needpatchrecache = false;
}
// Lactozilla: Check the renderer's state
// Check the renderer's state
// after a possible renderer switch.
void D_CheckRendererState(void)
{
// flush all patches from memory
// (also frees memory tagged with PU_CACHE)
// (which are not necessarily patches but I don't care)
if (needpatchflush)
{
Z_FlushCachedPatches();
needpatchflush = false;
}
// some patches have been freed,
// so cache them again
@ -663,7 +768,7 @@ void D_SRB2Loop(void)
*/
/* Smells like a hack... Don't fade Sonic's ass into the title screen. */
if (gamestate != GS_TITLESCREEN)
V_DrawScaledPatch(0, 0, 0, W_CachePatchNum(W_GetNumForName("CONSBACK"), PU_CACHE));
V_DrawScaledPatch(0, 0, 0, W_CachePatchNum(W_GetNumForName("CONSBACK"), PU_PATCH));
for (;;)
{
@ -739,16 +844,11 @@ void D_SRB2Loop(void)
S_UpdateSounds(); // move positional sounds
S_UpdateClosedCaptions();
// check for media change, loop music..
I_UpdateCD();
#ifdef HW3SOUND
HW3S_EndFrameUpdate();
#endif
#ifdef HAVE_BLUA
LUA_Step();
#endif
}
}
@ -817,6 +917,7 @@ void D_StartTitle(void)
// In case someone exits out at the same time they start a time attack run,
// reset modeattacking
modeattacking = ATTACKING_NONE;
marathonmode = 0;
// empty maptol so mario/etc sounds don't play in sound test when they shouldn't
maptol = 0;
@ -880,6 +981,40 @@ static inline void D_CleanFile(void)
}
}
///\brief Checks if a netgame URL is being handled, and changes working directory to the EXE's if so.
/// Done because browsers (at least, Firefox on Windows) launch the game from the browser's directory, which causes problems.
static void ChangeDirForUrlHandler(void)
{
// URL handlers are opened by web browsers (at least Firefox) from the browser's working directory, not the game's stored directory,
// so chdir to that directory unless overridden.
if (M_GetUrlProtocolArg() != NULL && !M_CheckParm("-nochdir"))
{
size_t i;
CONS_Printf("%s connect links load game files from the SRB2 application's stored directory. Switching to ", SERVER_URL_PROTOCOL);
strlcpy(srb2path, myargv[0], sizeof(srb2path));
// Get just the directory, minus the EXE name
for (i = strlen(srb2path)-1; i > 0; i--)
{
if (srb2path[i] == '/' || srb2path[i] == '\\')
{
srb2path[i] = '\0';
break;
}
}
CONS_Printf("%s\n", srb2path);
#if defined (_WIN32)
SetCurrentDirectoryA(srb2path);
#else
if (chdir(srb2path) == -1)
I_OutputMsg("Couldn't change working directory\n");
#endif
}
}
// ==========================================================================
// Identify the SRB2 version, and IWAD file to use.
// ==========================================================================
@ -961,6 +1096,7 @@ static void IdentifyVersion(void)
}
MUSICTEST("music.dta")
MUSICTEST("patch_music.pk3")
#ifdef DEVELOP // remove when music_new.dta is merged into music.dta
MUSICTEST("music_new.dta")
#endif
@ -968,63 +1104,20 @@ static void IdentifyVersion(void)
#endif
}
#ifdef PC_DOS
/* ======================================================================== */
// Code for printing SRB2's title bar in DOS
/* ======================================================================== */
//
// Center the title string, then add the date and time of compilation.
//
static inline void D_MakeTitleString(char *s)
static void
D_ConvertVersionNumbers (void)
{
char temp[82];
char *t;
const char *u;
INT32 i;
/* leave at defaults (0) under DEVELOP */
#ifndef DEVELOP
int major;
int minor;
for (i = 0, t = temp; i < 82; i++)
*t++=' ';
sscanf(SRB2VERSION, "%d.%d.%d", &major, &minor, &SUBVERSION);
for (t = temp + (80-strlen(s))/2, u = s; *u != '\0' ;)
*t++ = *u++;
u = compdate;
for (t = temp + 1, i = 11; i-- ;)
*t++ = *u++;
u = comptime;
for (t = temp + 71, i = 8; i-- ;)
*t++ = *u++;
temp[80] = '\0';
strcpy(s, temp);
}
static inline void D_Titlebar(void)
{
char title1[82]; // srb2 title banner
char title2[82];
strcpy(title1, "Sonic Robo Blast 2");
strcpy(title2, "Sonic Robo Blast 2");
D_MakeTitleString(title1);
// SRB2 banner
clrscr();
textattr((BLUE<<4)+WHITE);
clreol();
cputs(title1);
// standard srb2 banner
textattr((RED<<4)+WHITE);
clreol();
gotoxy((80-strlen(title2))/2, 2);
cputs(title2);
normvideo();
gotoxy(1,3);
}
/* this is stupid */
VERSION = ( major * 100 ) + minor;
#endif
}
//
// D_SRB2Main
@ -1036,6 +1129,9 @@ void D_SRB2Main(void)
INT32 pstartmap = 1;
boolean autostart = false;
/* break the version string into version numbers, for netplay */
D_ConvertVersionNumbers();
// Print GPL notice for our console users (Linux)
CONS_Printf(
"\n\nSonic Robo Blast 2\n"
@ -1051,7 +1147,7 @@ void D_SRB2Main(void)
"in this program.\n\n");
// keep error messages until the final flush(stderr)
#if !defined (PC_DOS) && !defined(NOTERMIOS)
#if !defined(NOTERMIOS)
if (setvbuf(stderr, NULL, _IOFBF, 1000))
I_OutputMsg("setvbuf didnt work\n");
#endif
@ -1068,6 +1164,9 @@ void D_SRB2Main(void)
// Test Dehacked lists
DEH_Check();
// Netgame URL special case: change working dir to EXE folder.
ChangeDirForUrlHandler();
// identify the main IWAD file to use
IdentifyVersion();
@ -1086,15 +1185,12 @@ void D_SRB2Main(void)
dedicated = M_CheckParm("-dedicated") != 0;
#endif
#ifdef PC_DOS
D_Titlebar();
#endif
if (devparm)
CONS_Printf(M_GetText("Development mode ON.\n"));
// default savegame
strcpy(savegamename, SAVEGAMENAME"%u.ssg");
strcpy(liveeventbackup, "live"SAVEGAMENAME".bkp"); // intentionally not ending with .ssg
{
const char *userhome = D_Home(); //Alam: path to home
@ -1123,10 +1219,9 @@ void D_SRB2Main(void)
// can't use sprintf since there is %u in savegamename
strcatbf(savegamename, srb2home, PATHSEP);
strcatbf(liveeventbackup, srb2home, PATHSEP);
#ifdef HAVE_BLUA
snprintf(luafiledir, sizeof luafiledir, "%s" PATHSEP "luafiles", srb2home);
#endif
#else // DEFAULTDIR
snprintf(srb2home, sizeof srb2home, "%s", userhome);
snprintf(downloaddir, sizeof downloaddir, "%s", userhome);
@ -1137,10 +1232,9 @@ void D_SRB2Main(void)
// can't use sprintf since there is %u in savegamename
strcatbf(savegamename, userhome, PATHSEP);
strcatbf(liveeventbackup, userhome, PATHSEP);
#ifdef HAVE_BLUA
snprintf(luafiledir, sizeof luafiledir, "%s" PATHSEP "luafiles", userhome);
#endif
#endif // DEFAULTDIR
}
@ -1153,13 +1247,26 @@ void D_SRB2Main(void)
// rand() needs seeded regardless of password
srand((unsigned int)time(NULL));
rand();
rand();
rand();
if (M_CheckParm("-password") && M_IsNextParm())
D_SetPassword(M_GetNextParm());
// player setup menu colors must be initialized before
// any wad file is added, as they may contain colors themselves
M_InitPlayerSetupColors();
CONS_Printf("Z_Init(): Init zone memory allocation daemon. \n");
Z_Init();
// Do this up here so that WADs loaded through the command line can use ExecCfg
COM_Init();
// add any files specified on the command line with -file wadfile
// to the wad list
if (!(M_CheckParm("-connect") && !M_CheckParm("-server")))
if (!((M_GetUrlProtocolArg() || M_CheckParm("-connect")) && !M_CheckParm("-server")))
{
if (M_CheckParm("-file"))
{
@ -1184,9 +1291,6 @@ void D_SRB2Main(void)
if (M_CheckParm("-server") || dedicated)
netgame = server = true;
CONS_Printf("Z_Init(): Init zone memory allocation daemon. \n");
Z_Init();
// adapt tables to SRB2's needs, including extra slots for dehacked file support
P_PatchInfoTables();
@ -1194,7 +1298,7 @@ void D_SRB2Main(void)
M_InitMenuPresTables();
// init title screen display params
if (M_CheckParm("-connect"))
if (M_GetUrlProtocolArg() || M_CheckParm("-connect"))
F_InitMenuPresValues();
//---------------------------------------------------- READY TIME
@ -1258,7 +1362,6 @@ void D_SRB2Main(void)
CONS_Printf("HU_Init(): Setting up heads up display.\n");
HU_Init();
COM_Init();
CON_Init();
D_RegisterServerCommands();
@ -1283,13 +1386,19 @@ void D_SRB2Main(void)
// Lactozilla: Does the render mode need to change?
if ((setrenderneeded != 0) && (setrenderneeded != rendermode))
{
CONS_Printf("Switching the renderer...\n");
CONS_Printf(M_GetText("Switching the renderer...\n"));
Z_PreparePatchFlush();
// set needpatchflush / needpatchrecache true for D_CheckRendererState
needpatchflush = true;
needpatchrecache = true;
// Set cv_renderer to the new render mode
VID_CheckRenderer();
SCR_ChangeRendererCVars(setrenderneeded);
SCR_ChangeRendererCVars(rendermode);
// check the renderer's state
D_CheckRendererState();
setrenderneeded = 0;
}
wipegamestate = gamestate;
@ -1315,10 +1424,6 @@ void D_SRB2Main(void)
}
}
// Initialize CD-Audio
if (M_CheckParm("-usecd") && !dedicated)
I_InitCD();
if (M_CheckParm("-noupload"))
COM_BufAddText("downloading 0\n");

View file

@ -715,10 +715,8 @@ void Net_CloseConnection(INT32 node)
InitNode(&nodes[node]);
SV_AbortSendFiles(node);
#ifdef HAVE_BLUA
if (server)
SV_AbortLuaFileTransfer(node);
#endif
I_NetFreeNodenum(node);
#endif
}
@ -804,17 +802,19 @@ static const char *packettypename[NUMPACKETTYPE] =
"CANRECEIVEGAMESTATE",
"RECEIVEDGAMESTATE",
#ifdef HAVE_BLUA
"SENDINGLUAFILE",
"ASKLUAFILE",
"HASLUAFILE",
#endif
"FILEFRAGMENT",
"FILEACK",
"FILERECEIVED",
"TEXTCMD",
"TEXTCMD2",
"CLIENTJOIN",
"NODETIMEOUT",
"LOGIN",
"PING"
};
@ -841,7 +841,7 @@ static void DebugPrintpacket(const char *header)
size_t ntxtcmd = &((UINT8 *)netbuffer)[doomcom->datalength] - cmd;
fprintf(debugfile, " firsttic %u ply %d tics %d ntxtcmd %s\n ",
(UINT32)ExpandTics(serverpak->starttic), serverpak->numslots, serverpak->numtics, sizeu1(ntxtcmd));
(UINT32)serverpak->starttic, serverpak->numslots, serverpak->numtics, sizeu1(ntxtcmd));
/// \todo Display more readable information about net commands
fprintfstringnewline((char *)cmd, ntxtcmd);
/*fprintfstring((char *)cmd, 3);
@ -860,8 +860,8 @@ static void DebugPrintpacket(const char *header)
case PT_NODEKEEPALIVE:
case PT_NODEKEEPALIVEMIS:
fprintf(debugfile, " tic %4u resendfrom %u\n",
(UINT32)ExpandTics(netbuffer->u.clientpak.client_tic),
(UINT32)ExpandTics (netbuffer->u.clientpak.resendfrom));
(UINT32)ExpandTics(netbuffer->u.clientpak.client_tic, doomcom->remotenode),
(UINT32)ExpandTics (netbuffer->u.clientpak.resendfrom, doomcom->remotenode));
break;
case PT_TEXTCMD:
case PT_TEXTCMD2:

View file

@ -22,7 +22,7 @@
#include "g_input.h"
#include "m_menu.h"
#include "r_local.h"
#include "r_things.h"
#include "r_skins.h"
#include "p_local.h"
#include "p_setup.h"
#include "s_sound.h"
@ -157,10 +157,8 @@ static void Command_Isgamemodified_f(void);
static void Command_Cheats_f(void);
#ifdef _DEBUG
static void Command_Togglemodified_f(void);
#ifdef HAVE_BLUA
static void Command_Archivetest_f(void);
#endif
#endif
// =========================================================================
// CLIENT VARIABLES
@ -227,6 +225,7 @@ consvar_t cv_allowseenames = {"allowseenames", "Yes", CV_NETVAR, CV_YesNo, NULL,
consvar_t cv_playername = {"name", "Sonic", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Name_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_playername2 = {"name2", "Tails", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Name2_OnChange, 0, NULL, NULL, 0, 0, NULL};
// player colors
UINT16 lastgoodcolor = SKINCOLOR_BLUE, lastgoodcolor2 = SKINCOLOR_BLUE;
consvar_t cv_playercolor = {"color", "Blue", CV_CALL|CV_NOINIT, Color_cons_t, Color_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_playercolor2 = {"color2", "Orange", CV_CALL|CV_NOINIT, Color_cons_t, Color2_OnChange, 0, NULL, NULL, 0, 0, NULL};
// player's skin, saved for commodity, when using a favorite skins wad..
@ -415,11 +414,9 @@ const char *netxcmdnames[MAXNETXCMD - 1] =
"DELFILE", // replace next time we add an XD
"SETMOTD",
"SUICIDE",
#ifdef HAVE_BLUA
"LUACMD",
"LUAVAR",
"LUAFILE"
#endif
};
// =========================================================================
@ -452,10 +449,8 @@ void D_RegisterServerCommands(void)
RegisterNetXCmd(XD_PAUSE, Got_Pause);
RegisterNetXCmd(XD_SUICIDE, Got_Suicide);
RegisterNetXCmd(XD_RUNSOC, Got_RunSOCcmd);
#ifdef HAVE_BLUA
RegisterNetXCmd(XD_LUACMD, Got_Luacmd);
RegisterNetXCmd(XD_LUAFILE, Got_LuaFile);
#endif
// Remote Administration
COM_AddCommand("password", Command_Changepassword_f);
@ -504,10 +499,10 @@ void D_RegisterServerCommands(void)
COM_AddCommand("cheats", Command_Cheats_f); // test
#ifdef _DEBUG
COM_AddCommand("togglemodified", Command_Togglemodified_f);
#ifdef HAVE_BLUA
COM_AddCommand("archivetest", Command_Archivetest_f);
#endif
#endif
COM_AddCommand("downloads", Command_Downloads_f);
// for master server connection
AddMServCommands();
@ -581,6 +576,7 @@ void D_RegisterServerCommands(void)
// d_clisrv
CV_RegisterVar(&cv_maxplayers);
CV_RegisterVar(&cv_joindelay);
CV_RegisterVar(&cv_rejointimeout);
CV_RegisterVar(&cv_resynchattempts);
CV_RegisterVar(&cv_maxsend);
@ -626,7 +622,7 @@ void D_RegisterClientCommands(void)
for (i = 0; i < MAXSKINCOLORS; i++)
{
Color_cons_t[i].value = i;
Color_cons_t[i].strvalue = Color_Names[i];
Color_cons_t[i].strvalue = skincolors[i].name;
}
Color_cons_t[MAXSKINCOLORS].value = 0;
Color_cons_t[MAXSKINCOLORS].strvalue = NULL;
@ -679,6 +675,7 @@ void D_RegisterClientCommands(void)
// GIF variables
CV_RegisterVar(&cv_gif_optimize);
CV_RegisterVar(&cv_gif_downscale);
CV_RegisterVar(&cv_gif_dynamicdelay);
CV_RegisterVar(&cv_gif_localcolortable);
#ifdef WALLSPLATS
@ -704,6 +701,7 @@ void D_RegisterClientCommands(void)
#endif
CV_RegisterVar(&cv_rollingdemos);
CV_RegisterVar(&cv_netstat);
CV_RegisterVar(&cv_netticbuffer);
#ifdef NETGAME_DEVMODE
CV_RegisterVar(&cv_fishcake);
@ -863,10 +861,6 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_midimusicvolume);
CV_RegisterVar(&cv_numChannels);
// i_cdmus.c
CV_RegisterVar(&cd_volume);
CV_RegisterVar(&cdUpdate);
// screen.c
CV_RegisterVar(&cv_fullscreen);
CV_RegisterVar(&cv_renderview);
@ -915,7 +909,7 @@ void D_RegisterClientCommands(void)
#ifdef _DEBUG
COM_AddCommand("causecfail", Command_CauseCfail_f);
#endif
#if defined(HAVE_BLUA) && defined(LUA_ALLOW_BYTECODE)
#ifdef LUA_ALLOW_BYTECODE
COM_AddCommand("dumplua", Command_Dumplua_f);
#endif
}
@ -1160,7 +1154,7 @@ UINT8 CanChangeSkin(INT32 playernum)
// Server has skin change restrictions.
if (cv_restrictskinchange.value)
{
if (gametype == GT_COOP)
if (gametyperules & GTR_FRIENDLY)
return true;
// Can change skin during initial countdown.
@ -1228,15 +1222,20 @@ static void SendNameAndColor(void)
CV_StealthSetValue(&cv_playercolor, skincolor_blueteam);
}
// never allow the color "none"
if (!cv_playercolor.value)
// don't allow inaccessible colors
if (!skincolors[cv_playercolor.value].accessible)
{
if (players[consoleplayer].skincolor)
if (players[consoleplayer].skincolor && skincolors[players[consoleplayer].skincolor].accessible)
CV_StealthSetValue(&cv_playercolor, players[consoleplayer].skincolor);
else if (skins[players[consoleplayer].skin].prefcolor)
CV_StealthSetValue(&cv_playercolor, skins[players[consoleplayer].skin].prefcolor);
else
else if (skincolors[atoi(cv_playercolor.defaultvalue)].accessible)
CV_StealthSet(&cv_playercolor, cv_playercolor.defaultvalue);
else if (skins[players[consoleplayer].skin].prefcolor && skincolors[skins[players[consoleplayer].skin].prefcolor].accessible)
CV_StealthSetValue(&cv_playercolor, skins[players[consoleplayer].skin].prefcolor);
else {
UINT16 i = 0;
while (i<numskincolors && !skincolors[i].accessible) i++;
CV_StealthSetValue(&cv_playercolor, (i != numskincolors) ? i : SKINCOLOR_BLUE);
}
}
if (!strcmp(cv_playername.string, player_names[consoleplayer])
@ -1260,7 +1259,7 @@ static void SendNameAndColor(void)
players[consoleplayer].skincolor = cv_playercolor.value;
if (players[consoleplayer].mo)
if (players[consoleplayer].mo && !players[consoleplayer].powers[pw_dye])
players[consoleplayer].mo->color = players[consoleplayer].skincolor;
if (metalrecording)
@ -1283,10 +1282,10 @@ static void SendNameAndColor(void)
{
CV_StealthSetValue(&cv_playercolor, skins[cv_skin.value].prefcolor);
players[consoleplayer].skincolor = cv_playercolor.value % MAXSKINCOLORS;
players[consoleplayer].skincolor = cv_playercolor.value % numskincolors;
if (players[consoleplayer].mo)
players[consoleplayer].mo->color = (UINT8)players[consoleplayer].skincolor;
players[consoleplayer].mo->color = (UINT16)players[consoleplayer].skincolor;
}*/
}
else
@ -1324,7 +1323,7 @@ static void SendNameAndColor(void)
// Finally write out the complete packet and send it off.
WRITESTRINGN(p, cv_playername.zstring, MAXPLAYERNAME);
WRITEUINT32(p, (UINT32)players[consoleplayer].availabilities);
WRITEUINT8(p, (UINT8)cv_playercolor.value);
WRITEUINT16(p, (UINT16)cv_playercolor.value);
WRITEUINT8(p, (UINT8)cv_skin.value);
SendNetXCmd(XD_NAMEANDCOLOR, buf, p - buf);
}
@ -1351,15 +1350,20 @@ static void SendNameAndColor2(void)
CV_StealthSetValue(&cv_playercolor2, skincolor_blueteam);
}
// never allow the color "none"
if (!cv_playercolor2.value)
// don't allow inaccessible colors
if (!skincolors[cv_playercolor2.value].accessible)
{
if (players[secondplaya].skincolor)
if (players[secondplaya].skincolor && skincolors[players[secondplaya].skincolor].accessible)
CV_StealthSetValue(&cv_playercolor2, players[secondplaya].skincolor);
else if (skins[players[secondplaya].skin].prefcolor)
else if (skincolors[atoi(cv_playercolor2.defaultvalue)].accessible)
CV_StealthSet(&cv_playercolor, cv_playercolor2.defaultvalue);
else if (skins[players[secondplaya].skin].prefcolor && skincolors[skins[players[secondplaya].skin].prefcolor].accessible)
CV_StealthSetValue(&cv_playercolor2, skins[players[secondplaya].skin].prefcolor);
else
CV_StealthSet(&cv_playercolor2, cv_playercolor2.defaultvalue);
else {
UINT16 i = 0;
while (i<numskincolors && !skincolors[i].accessible) i++;
CV_StealthSetValue(&cv_playercolor2, (i != numskincolors) ? i : SKINCOLOR_BLUE);
}
}
players[secondplaya].availabilities = R_GetSkinAvailabilities();
@ -1372,8 +1376,9 @@ static void SendNameAndColor2(void)
if (botingame)
{
players[secondplaya].skincolor = botcolor;
if (players[secondplaya].mo)
if (players[secondplaya].mo && !players[secondplaya].powers[pw_dye])
players[secondplaya].mo->color = players[secondplaya].skincolor;
SetPlayerSkinByNum(secondplaya, botskin-1);
return;
}
@ -1386,7 +1391,7 @@ static void SendNameAndColor2(void)
// don't use secondarydisplayplayer: the second player must be 1
players[secondplaya].skincolor = cv_playercolor2.value;
if (players[secondplaya].mo)
if (players[secondplaya].mo && !players[secondplaya].powers[pw_dye])
players[secondplaya].mo->color = players[secondplaya].skincolor;
if (cv_forceskin.value >= 0 && (netgame || multiplayer)) // Server wants everyone to use the same player
@ -1411,7 +1416,7 @@ static void SendNameAndColor2(void)
{
CV_StealthSetValue(&cv_playercolor2, skins[players[secondplaya].skin].prefcolor);
players[secondplaya].skincolor = cv_playercolor2.value % MAXSKINCOLORS;
players[secondplaya].skincolor = cv_playercolor2.value % numskincolors;
if (players[secondplaya].mo)
players[secondplaya].mo->color = players[secondplaya].skincolor;
@ -1434,7 +1439,8 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum)
{
player_t *p = &players[playernum];
char name[MAXPLAYERNAME+1];
UINT8 color, skin;
UINT16 color;
UINT8 skin;
#ifdef PARANOIA
if (playernum < 0 || playernum > MAXPLAYERS)
@ -1453,7 +1459,7 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum)
READSTRINGN(*cp, name, MAXPLAYERNAME);
p->availabilities = READUINT32(*cp);
color = READUINT8(*cp);
color = READUINT16(*cp);
skin = READUINT8(*cp);
// set name
@ -1461,9 +1467,9 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum)
SetPlayerName(playernum, name);
// set color
p->skincolor = color % MAXSKINCOLORS;
p->skincolor = color % numskincolors;
if (p->mo)
p->mo->color = (UINT8)p->skincolor;
p->mo->color = (UINT16)p->skincolor;
// normal player colors
if (server && (p != &players[consoleplayer] && p != &players[secondarydisplayplayer]))
@ -1480,8 +1486,8 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum)
kick = true;
}
// don't allow color "none"
if (!p->skincolor)
// don't allow inaccessible colors
if (skincolors[p->skincolor].accessible == false)
kick = true;
// availabilities
@ -1739,7 +1745,7 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pultmode, boolean rese
}
CONS_Debug(DBG_GAMELOGIC, "Map change: mapnum=%d gametype=%d ultmode=%d resetplayers=%d delay=%d skipprecutscene=%d\n",
mapnum, newgametype, pultmode, resetplayers, delay, skipprecutscene);
if ((netgame || multiplayer) && !((gametype == newgametype) && (newgametype == GT_COOP)))
if ((netgame || multiplayer) && !((gametype == newgametype) && (gametypedefaultrules[newgametype] & GTR_CAMPAIGN)))
FLS = false;
if (delay != 2)
@ -1981,7 +1987,7 @@ static void Command_Map_f(void)
fromlevelselect =
( netgame || multiplayer ) &&
newgametype == gametype &&
newgametype == GT_COOP;
gametypedefaultrules[newgametype] & GTR_CAMPAIGN;
}
}
@ -2029,9 +2035,7 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
UINT8 flags;
INT32 resetplayer = 1, lastgametype;
UINT8 skipprecutscene, FLS;
#ifdef HAVE_BLUA
INT16 mapnumber;
#endif
if (playernum != serverplayer && !IsPlayerAdmin(playernum))
{
@ -2093,10 +2097,8 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
CV_StealthSetValue(&cv_playercolor, players[0].skincolor);
}
#ifdef HAVE_BLUA
mapnumber = M_MapNumber(mapname[3], mapname[4]);
LUAh_MapChange(mapnumber);
#endif
G_InitNew(ultimatemode, mapname, resetplayer, skipprecutscene, FLS);
if (demoplayback && !timingdemo)
@ -2680,11 +2682,9 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
return;
}
#ifdef HAVE_BLUA
// Don't switch team, just go away, please, go awaayyyy, aaauuauugghhhghgh
if (!LUAh_TeamSwitch(&players[playernum], NetPacket.packet.newteam, players[playernum].spectator, NetPacket.packet.autobalance, NetPacket.packet.scrambled))
return;
#endif
//no status changes after hidetime
if ((gametyperules & GTR_HIDEFROZEN) && (leveltime >= (hidetime * TICRATE)))
@ -2777,7 +2777,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
players[playernum].spectator = false;
//If joining after hidetime in normal tag, default to being IT.
if (gametype == GT_TAG && (leveltime > (hidetime * TICRATE)))
if (((gametyperules & (GTR_TAG|GTR_HIDEFROZEN)) == GTR_TAG) && (leveltime > (hidetime * TICRATE)))
{
NetPacket.packet.newteam = 1; //minor hack, causes the "is it" message to be printed later.
players[playernum].pflags |= PF_TAGIT; //make the player IT.
@ -2841,12 +2841,10 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
//reset view if you are changed, or viewing someone who was changed.
if (playernum == consoleplayer || displayplayer == playernum)
{
#ifdef HAVE_BLUA
// Call ViewpointSwitch hooks here.
// The viewpoint was forcibly changed.
if (displayplayer != consoleplayer) // You're already viewing yourself. No big deal.
LUAh_ViewpointSwitch(&players[playernum], &players[displayplayer], true);
#endif
LUAh_ViewpointSwitch(&players[consoleplayer], &players[consoleplayer], true);
displayplayer = consoleplayer;
}
@ -3344,10 +3342,6 @@ static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum)
boolean kick = false;
boolean toomany = false;
INT32 i,j;
serverinfo_pak *dummycheck = NULL;
// Shut the compiler up.
(void)dummycheck;
READSTRINGN(*cp, filename, 240);
READMEM(*cp, md5sum, 16);
@ -3478,7 +3472,7 @@ static void Command_Version_f(void)
#ifdef DEVELOP
CONS_Printf("Sonic Robo Blast 2 %s-%s (%s %s) ", compbranch, comprevision, compdate, comptime);
#else
CONS_Printf("Sonic Robo Blast 2 %s (%s %s %s) ", VERSIONSTRING, compdate, comptime, comprevision);
CONS_Printf("Sonic Robo Blast 2 %s (%s %s %s %s) ", VERSIONSTRING, compdate, comptime, comprevision, compbranch);
#endif
// Base library
@ -3574,6 +3568,8 @@ static void Command_Playintro_f(void)
*/
FUNCNORETURN static ATTRNORETURN void Command_Quit_f(void)
{
if (Playing())
LUAh_GameQuit();
I_Quit();
}
@ -3631,7 +3627,7 @@ static void PointLimit_OnChange(void)
static void NumLaps_OnChange(void)
{
// Just don't be verbose
if (gametype == GT_RACE)
if ((gametyperules & (GTR_RACE|GTR_LIVES)) == GTR_RACE)
CONS_Printf(M_GetText("Number of laps set to %d\n"), cv_numlaps.value);
}
@ -3745,7 +3741,7 @@ static void ExitMove_OnChange(void)
{
UINT8 i;
if (!(netgame || multiplayer) || gametype != GT_COOP)
if (!(netgame || multiplayer) || !(gametyperules & GTR_FRIENDLY))
return;
if (cv_exitmove.value)
@ -3755,11 +3751,11 @@ static void ExitMove_OnChange(void)
{
if (players[i].mo->target && players[i].mo->target->type == MT_SIGN)
P_SetTarget(&players[i].mo->target, NULL);
if (players[i].pflags & PF_FINISHED)
P_GiveFinishFlags(&players[i]);
}
CONS_Printf(M_GetText("Players can now move after completing the level.\n"));
}
else
@ -4235,6 +4231,9 @@ void Command_ExitGame_f(void)
{
INT32 i;
if (Playing())
LUAh_GameQuit();
D_QuitNetGame();
CL_Reset();
CV_ClearChangedFlags();
@ -4336,7 +4335,6 @@ static void Command_Togglemodified_f(void)
modifiedgame = !modifiedgame;
}
#ifdef HAVE_BLUA
extern UINT8 *save_p;
static void Command_Archivetest_f(void)
{
@ -4381,7 +4379,6 @@ static void Command_Archivetest_f(void)
CONS_Printf("Done. No crash.\n");
}
#endif
#endif
/** Makes a change to ::cv_forceskin take effect immediately.
*
@ -4493,25 +4490,30 @@ static void Skin2_OnChange(void)
*/
static void Color_OnChange(void)
{
if (!Playing())
return; // do whatever you want
if (!(cv_debug || devparm) && !(multiplayer || netgame)) // In single player.
{
CV_StealthSet(&cv_skin, skins[players[consoleplayer].skin].name);
return;
}
if (!P_PlayerMoving(consoleplayer))
{
// Color change menu scrolling fix is no longer necessary
SendNameAndColor();
if (!Playing()) {
if (!cv_playercolor.value || !skincolors[cv_playercolor.value].accessible)
CV_StealthSetValue(&cv_playercolor, lastgoodcolor);
}
else
{
CV_StealthSetValue(&cv_playercolor,
players[consoleplayer].skincolor);
if (!(cv_debug || devparm) && !(multiplayer || netgame)) // In single player.
{
CV_StealthSet(&cv_skin, skins[players[consoleplayer].skin].name);
return;
}
if (!P_PlayerMoving(consoleplayer) && skincolors[players[consoleplayer].skincolor].accessible == true)
{
// Color change menu scrolling fix is no longer necessary
SendNameAndColor();
}
else
{
CV_StealthSetValue(&cv_playercolor,
players[consoleplayer].skincolor);
}
}
lastgoodcolor = cv_playercolor.value;
}
/** Sends a color change for the secondary splitscreen player, unless that
@ -4522,18 +4524,24 @@ static void Color_OnChange(void)
static void Color2_OnChange(void)
{
if (!Playing() || !splitscreen)
return; // do whatever you want
if (!P_PlayerMoving(secondarydisplayplayer))
{
// Color change menu scrolling fix is no longer necessary
SendNameAndColor2();
if (!cv_playercolor2.value || !skincolors[cv_playercolor2.value].accessible)
CV_StealthSetValue(&cv_playercolor2, lastgoodcolor2);
}
else
{
CV_StealthSetValue(&cv_playercolor2,
players[secondarydisplayplayer].skincolor);
if (!P_PlayerMoving(secondarydisplayplayer) && skincolors[players[secondarydisplayplayer].skincolor].accessible == true)
{
// Color change menu scrolling fix is no longer necessary
SendNameAndColor2();
}
else
{
CV_StealthSetValue(&cv_playercolor2,
players[secondarydisplayplayer].skincolor);
}
}
lastgoodcolor2 = cv_playercolor2.value;
}
/** Displays the result of the chat being muted or unmuted.
@ -4610,7 +4618,7 @@ static void Command_ShowTime_f(void)
static void BaseNumLaps_OnChange(void)
{
if (gametype == GT_RACE)
if ((gametyperules & (GTR_RACE|GTR_LIVES)) == GTR_RACE)
{
if (cv_basenumlaps.value)
CONS_Printf(M_GetText("Number of laps will be changed to map defaults next round.\n"));

View file

@ -142,11 +142,9 @@ typedef enum
XD_SETMOTD, // 19
XD_SUICIDE, // 20
XD_DEMOTED, // 21
#ifdef HAVE_BLUA
XD_LUACMD, // 22
XD_LUAVAR, // 23
XD_LUAFILE, // 24
#endif
MAXNETXCMD
} netxcmd_t;

View file

@ -56,7 +56,7 @@
#include <errno.h>
// Prototypes
static boolean SV_SendFile(INT32 node, const char *filename, UINT8 fileid);
static boolean AddFileToSendQueue(INT32 node, const char *filename, UINT8 fileid);
// Sender structure
typedef struct filetx_s
@ -69,7 +69,6 @@ typedef struct filetx_s
UINT32 size; // Size of the file
UINT8 fileid;
INT32 node; // Destination
boolean textmode; // For files requested by Lua without the "b" option
struct filetx_s *next; // Next file in the list
} filetx_t;
@ -77,8 +76,13 @@ typedef struct filetx_s
typedef struct filetran_s
{
filetx_t *txlist; // Linked list of all files for the node
UINT8 iteration;
UINT8 ackediteration;
UINT32 position; // The current position in the file
boolean *ackedfragments;
UINT32 ackedsize;
FILE *currentfile; // The file currently being sent/received
tic_t dontsenduntil;
} filetran_t;
static filetran_t transfer[MAXNETNODES];
@ -88,18 +92,29 @@ static filetran_t transfer[MAXNETNODES];
// Receiver structure
INT32 fileneedednum; // Number of files needed to join the server
fileneeded_t fileneeded[MAX_WADFILES]; // List of needed files
static tic_t lasttimeackpacketsent = 0;
char downloaddir[512] = "DOWNLOAD";
#ifdef CLIENT_LOADINGSCREEN
// For resuming failed downloads
typedef struct
{
char filename[MAX_WADPATH];
UINT8 md5sum[16];
boolean *receivedfragments;
UINT32 fragmentsize;
UINT32 currentsize;
} pauseddownload_t;
static pauseddownload_t *pauseddownload = NULL;
#ifndef NONET
// for cl loading screen
INT32 lastfilenum = -1;
#endif
#ifdef HAVE_BLUA
luafiletransfer_t *luafiletransfers = NULL;
boolean waitingforluafiletransfer = false;
boolean waitingforluafilecommand = false;
char luafiledir[256 + 16] = "luafiles";
#endif
/** Fills a serverinfo packet with information about wad files loaded.
@ -161,25 +176,29 @@ void D_ParseFileneeded(INT32 fileneedednum_parm, UINT8 *fileneededstr)
for (i = 0; i < fileneedednum; i++)
{
fileneeded[i].status = FS_NOTFOUND; // We haven't even started looking for the file yet
fileneeded[i].justdownloaded = false;
filestatus = READUINT8(p); // The first byte is the file status
fileneeded[i].willsend = (UINT8)(filestatus >> 4);
fileneeded[i].totalsize = READUINT32(p); // The four next bytes are the file size
fileneeded[i].file = NULL; // The file isn't open yet
READSTRINGN(p, fileneeded[i].filename, MAX_WADPATH); // The next bytes are the file name
READMEM(p, fileneeded[i].md5sum, 16); // The last 16 bytes are the file checksum
fileneeded[i].textmode = false;
}
}
void CL_PrepareDownloadSaveGame(const char *tmpsave)
{
#ifndef NONET
lastfilenum = -1;
#endif
fileneedednum = 1;
fileneeded[0].status = FS_REQUESTED;
fileneeded[0].justdownloaded = false;
fileneeded[0].totalsize = UINT32_MAX;
fileneeded[0].file = NULL;
memset(fileneeded[0].md5sum, 0, 16);
strcpy(fileneeded[0].filename, tmpsave);
fileneeded[0].textmode = false;
}
/** Checks the server to see if we CAN download all the files,
@ -248,6 +267,31 @@ boolean CL_CheckDownloadable(void)
return false;
}
/** Returns true if a needed file transfer can be resumed
*
* \param file The needed file to resume the transfer for
* \return True if the transfer can be resumed
*
*/
static boolean CL_CanResumeDownload(fileneeded_t *file)
{
return pauseddownload
&& !strcmp(pauseddownload->filename, file->filename) // Same name
&& !memcmp(pauseddownload->md5sum, file->md5sum, 16) // Same checksum
&& pauseddownload->fragmentsize == file->fragmentsize; // Same fragment size
}
void CL_AbortDownloadResume(void)
{
if (!pauseddownload)
return;
free(pauseddownload->receivedfragments);
remove(pauseddownload->filename);
free(pauseddownload);
pauseddownload = NULL;
}
/** Sends requests for files in the ::fileneeded table with a status of
* ::FS_NOTFOUND.
*
@ -255,7 +299,7 @@ boolean CL_CheckDownloadable(void)
* \note Sends a PT_REQUESTFILE packet
*
*/
boolean CL_SendRequestFile(void)
boolean CL_SendFileRequest(void)
{
char *p;
INT32 i;
@ -300,7 +344,7 @@ boolean CL_SendRequestFile(void)
// get request filepak and put it on the send queue
// returns false if a requested file was not found or cannot be sent
boolean Got_RequestFilePak(INT32 node)
boolean PT_RequestFile(INT32 node)
{
char wad[MAX_WADPATH+1];
UINT8 *p = netbuffer->u.textcmd;
@ -311,7 +355,7 @@ boolean Got_RequestFilePak(INT32 node)
if (id == 0xFF)
break;
READSTRINGN(p, wad, MAX_WADPATH);
if (!SV_SendFile(node, wad, id))
if (!AddFileToSendQueue(node, wad, id))
{
SV_AbortSendFiles(node);
return false; // don't read the rest of the files
@ -458,15 +502,12 @@ void CL_LoadServerFiles(void)
}
}
#ifdef HAVE_BLUA
void AddLuaFileTransfer(const char *filename, const char *mode)
{
luafiletransfer_t **prevnext; // A pointer to the "next" field of the last transfer in the list
luafiletransfer_t *filetransfer;
static INT32 id;
//CONS_Printf("AddLuaFileTransfer \"%s\"\n", filename);
// Find the last transfer in the list and set a pointer to its "next" field
prevnext = &luafiletransfers;
while (*prevnext)
@ -496,26 +537,11 @@ void AddLuaFileTransfer(const char *filename, const char *mode)
strlcpy(filetransfer->mode, mode, sizeof(filetransfer->mode));
if (server)
{
INT32 i;
// Set status to "waiting" for everyone
for (i = 0; i < MAXNETNODES; i++)
filetransfer->nodestatus[i] = LFTNS_WAITING;
if (!luafiletransfers->next) // Only if there is no transfer already going on
{
if (FIL_ReadFileOK(filetransfer->realfilename))
SV_PrepareSendLuaFileToNextNode();
else
{
// Send a net command with 0 as its first byte to indicate the file couldn't be opened
UINT8 success = 0;
SendNetXCmd(XD_LUAFILE, &success, 1);
}
}
}
// Only if there is no transfer already going on
if (server && filetransfer == luafiletransfers)
SV_PrepareSendLuaFile();
else
filetransfer->ongoing = false;
// Store the callback so it can be called once everyone has the file
filetransfer->id = id;
@ -529,7 +555,7 @@ void AddLuaFileTransfer(const char *filename, const char *mode)
}
}
void SV_PrepareSendLuaFileToNextNode(void)
static void SV_PrepareSendLuaFileToNextNode(void)
{
INT32 i;
UINT8 success = 1;
@ -553,6 +579,45 @@ void SV_PrepareSendLuaFileToNextNode(void)
SendNetXCmd(XD_LUAFILE, &success, 1);
}
void SV_PrepareSendLuaFile(void)
{
char *binfilename;
INT32 i;
luafiletransfers->ongoing = true;
// Set status to "waiting" for everyone
for (i = 0; i < MAXNETNODES; i++)
luafiletransfers->nodestatus[i] = LFTNS_WAITING;
if (FIL_ReadFileOK(luafiletransfers->realfilename))
{
// If opening in text mode, convert all newlines to LF
if (!strchr(luafiletransfers->mode, 'b'))
{
binfilename = strdup(va("%s" PATHSEP "$$$%d%d.tmp",
luafiledir, rand(), rand()));
if (!binfilename)
I_Error("SV_PrepareSendLuaFile: Out of memory\n");
if (!FIL_ConvertTextFileToBinary(luafiletransfers->realfilename, binfilename))
I_Error("SV_PrepareSendLuaFile: Failed to convert file newlines\n");
// Use the temporary file instead
free(luafiletransfers->realfilename);
luafiletransfers->realfilename = binfilename;
}
SV_PrepareSendLuaFileToNextNode();
}
else
{
// Send a net command with 0 as its first byte to indicate the file couldn't be opened
UINT8 success = 0;
SendNetXCmd(XD_LUAFILE, &success, 1);
}
}
void SV_HandleLuaFileSent(UINT8 node)
{
luafiletransfers->nodestatus[node] = LFTNS_SENT;
@ -563,6 +628,10 @@ void RemoveLuaFileTransfer(void)
{
luafiletransfer_t *filetransfer = luafiletransfers;
// If it was a temporary file, delete it
if (server && !strchr(filetransfer->mode, 'b'))
remove(filetransfer->realfilename);
RemoveLuaFileCallback(filetransfer->id);
luafiletransfers = filetransfer->next;
@ -599,22 +668,29 @@ void CL_PrepareDownloadLuaFile(void)
return;
}
if (luafiletransfers->ongoing)
{
waitingforluafilecommand = true;
return;
}
// Tell the server we are ready to receive the file
netbuffer->packettype = PT_ASKLUAFILE;
HSendPacket(servernode, true, 0, 0);
fileneedednum = 1;
fileneeded[0].status = FS_REQUESTED;
fileneeded[0].justdownloaded = false;
fileneeded[0].totalsize = UINT32_MAX;
fileneeded[0].file = NULL;
memset(fileneeded[0].md5sum, 0, 16);
strcpy(fileneeded[0].filename, luafiletransfers->realfilename);
fileneeded[0].textmode = !strchr(luafiletransfers->mode, 'b');
// Make sure all directories in the file path exist
MakePathDirs(fileneeded[0].filename);
luafiletransfers->ongoing = true;
}
#endif
// Number of files to send
// Little optimization to quickly test if there is a file in the queue
@ -624,12 +700,12 @@ static INT32 filestosend = 0;
*
* \param node The node to send the file to
* \param filename The file to send
* \param fileid ???
* \sa SV_SendRam
* \sa SV_SendLuaFile
* \param fileid The index of the file in the list of added files
* \sa AddRamToSendQueue
* \sa AddLuaFileToSendQueue
*
*/
static boolean SV_SendFile(INT32 node, const char *filename, UINT8 fileid)
static boolean AddFileToSendQueue(INT32 node, const char *filename, UINT8 fileid)
{
filetx_t **q; // A pointer to the "next" field of the last file in the list
filetx_t *p; // The new file request
@ -647,7 +723,7 @@ static boolean SV_SendFile(INT32 node, const char *filename, UINT8 fileid)
// Allocate a file request and append it to the file list
p = *q = (filetx_t *)malloc(sizeof (filetx_t));
if (!p)
I_Error("SV_SendFile: No more memory\n");
I_Error("AddFileToSendQueue: No more memory\n");
// Initialise with zeros
memset(p, 0, sizeof (filetx_t));
@ -655,7 +731,7 @@ static boolean SV_SendFile(INT32 node, const char *filename, UINT8 fileid)
// Allocate the file name
p->id.filename = (char *)malloc(MAX_WADPATH);
if (!p->id.filename)
I_Error("SV_SendFile: No more memory\n");
I_Error("AddFileToSendQueue: No more memory\n");
// Set the file name and get rid of the path
strlcpy(p->id.filename, filename, MAX_WADPATH);
@ -715,12 +791,12 @@ static boolean SV_SendFile(INT32 node, const char *filename, UINT8 fileid)
* \param data The memory block to send
* \param size The size of the block in bytes
* \param freemethod How to free the block after it has been sent
* \param fileid ???
* \sa SV_SendFile
* \sa SV_SendLuaFile
* \param fileid The index of the file in the list of added files
* \sa AddFileToSendQueue
* \sa AddLuaFileToSendQueue
*
*/
void SV_SendRam(INT32 node, void *data, size_t size, freemethod_t freemethod, UINT8 fileid)
void AddRamToSendQueue(INT32 node, void *data, size_t size, freemethod_t freemethod, UINT8 fileid)
{
filetx_t **q; // A pointer to the "next" field of the last file in the list
filetx_t *p; // The new file request
@ -733,7 +809,7 @@ void SV_SendRam(INT32 node, void *data, size_t size, freemethod_t freemethod, UI
// Allocate a file request and append it to the file list
p = *q = (filetx_t *)malloc(sizeof (filetx_t));
if (!p)
I_Error("SV_SendRam: No more memory\n");
I_Error("AddRamToSendQueue: No more memory\n");
// Initialise with zeros
memset(p, 0, sizeof (filetx_t));
@ -749,16 +825,15 @@ void SV_SendRam(INT32 node, void *data, size_t size, freemethod_t freemethod, UI
filestosend++;
}
#ifdef HAVE_BLUA
/** Adds a file requested by Lua to the file list for a node
*
* \param node The node to send the file to
* \param filename The file to send
* \sa SV_SendFile
* \sa SV_SendRam
* \sa AddFileToSendQueue
* \sa AddRamToSendQueue
*
*/
boolean SV_SendLuaFile(INT32 node, const char *filename, boolean textmode)
boolean AddLuaFileToSendQueue(INT32 node, const char *filename)
{
filetx_t **q; // A pointer to the "next" field of the last file in the list
filetx_t *p; // The new file request
@ -775,7 +850,7 @@ boolean SV_SendLuaFile(INT32 node, const char *filename, boolean textmode)
// Allocate a file request and append it to the file list
p = *q = (filetx_t *)malloc(sizeof (filetx_t));
if (!p)
I_Error("SV_SendLuaFile: No more memory\n");
I_Error("AddLuaFileToSendQueue: No more memory\n");
// Initialise with zeros
memset(p, 0, sizeof (filetx_t));
@ -783,22 +858,18 @@ boolean SV_SendLuaFile(INT32 node, const char *filename, boolean textmode)
// Allocate the file name
p->id.filename = (char *)malloc(MAX_WADPATH); // !!!
if (!p->id.filename)
I_Error("SV_SendLuaFile: No more memory\n");
I_Error("AddLuaFileToSendQueue: No more memory\n");
// Set the file name and get rid of the path
strlcpy(p->id.filename, filename, MAX_WADPATH); // !!!
//nameonly(p->id.filename);
// Open in text mode if required by the Lua script
p->textmode = textmode;
DEBFILE(va("Sending Lua file %s to %d\n", filename, node));
p->ram = SF_FILE; // It's a file, we need to close it and free its name once we're done sending it
p->next = NULL; // End of list
filestosend++;
return true;
}
#endif
/** Stops sending a file for a node, and removes the file request from the list,
* either because the file has been fully sent or because the node was disconnected
@ -810,7 +881,8 @@ static void SV_EndFileSend(INT32 node)
{
filetx_t *p = transfer[node].txlist;
// Free the file request according to the freemethod parameter used with SV_SendFile/Ram
// Free the file request according to the freemethod
// parameter used with AddFileToSendQueue/AddRamToSendQueue
switch (p->ram)
{
case SF_FILE: // It's a file, close it and free its filename
@ -835,43 +907,32 @@ static void SV_EndFileSend(INT32 node)
// Indicate that the transmission is over
transfer[node].currentfile = NULL;
if (transfer[node].ackedfragments)
free(transfer[node].ackedfragments);
transfer[node].ackedfragments = NULL;
filestosend--;
}
#define PACKETPERTIC net_bandwidth/(TICRATE*software_MAXPACKETLENGTH)
#define FILEFRAGMENTSIZE (software_MAXPACKETLENGTH - (FILETXHEADER + BASEPACKETSIZE))
/** Handles file transmission
*
* \todo Use an acknowledging method more adapted to file transmission
* The current download speed suffers from lack of ack packets,
* especially when the one downloading has high latency
*
*/
void SV_FileSendTicker(void)
void FileSendTicker(void)
{
static INT32 currentnode = 0;
filetx_pak *p;
size_t size;
size_t fragmentsize;
filetx_t *f;
INT32 packetsent, ram, i, j;
INT32 maxpacketsent;
if (!filestosend) // No file to send
return;
if (cv_downloadspeed.value) // New (and experimental) behavior
{
if (cv_downloadspeed.value) // New behavior
packetsent = cv_downloadspeed.value;
// Don't send more packets than we have free acks
#ifndef NONET
maxpacketsent = Net_GetFreeAcks(false) - 5; // Let 5 extra acks just in case
#else
maxpacketsent = 1;
#endif
if (packetsent > maxpacketsent && maxpacketsent > 0) // Send at least one packet
packetsent = maxpacketsent;
}
else // Old behavior
{
packetsent = PACKETPERTIC;
@ -888,11 +949,12 @@ void SV_FileSendTicker(void)
i = (i+1) % MAXNETNODES, j++)
{
if (transfer[i].txlist)
goto found;
break;
}
// no transfer to do
I_Error("filestosend=%d but no file to send found\n", filestosend);
found:
if (j >= MAXNETNODES)
I_Error("filestosend=%d but no file to send found\n", filestosend);
currentnode = (i+1) % MAXNETNODES;
f = transfer[i].txlist;
ram = f->ram;
@ -905,7 +967,7 @@ void SV_FileSendTicker(void)
long filesize;
transfer[i].currentfile =
fopen(f->id.filename, f->textmode ? "r" : "rb");
fopen(f->id.filename, "rb");
if (!transfer[i].currentfile)
I_Error("File %s does not exist",
@ -926,57 +988,232 @@ void SV_FileSendTicker(void)
}
else // Sending RAM
transfer[i].currentfile = (FILE *)1; // Set currentfile to a non-null value to indicate that it is open
transfer[i].iteration = 1;
transfer[i].ackediteration = 0;
transfer[i].position = 0;
transfer[i].ackedsize = 0;
transfer[i].ackedfragments = calloc(f->size / FILEFRAGMENTSIZE + 1, sizeof(*transfer[i].ackedfragments));
if (!transfer[i].ackedfragments)
I_Error("FileSendTicker: No more memory\n");
transfer[i].dontsenduntil = 0;
}
// If the client hasn't acknowledged any fragment from the previous iteration,
// it is most likely because their acks haven't had enough time to reach the server
// yet, due to latency. In that case, we wait a little to avoid useless resend.
if (I_GetTime() < transfer[i].dontsenduntil)
continue;
// Find the first non-acknowledged fragment
while (transfer[i].ackedfragments[transfer[i].position / FILEFRAGMENTSIZE])
{
transfer[i].position += FILEFRAGMENTSIZE;
if (transfer[i].position >= f->size)
{
if (transfer[i].ackediteration < transfer[i].iteration)
transfer[i].dontsenduntil = I_GetTime() + TICRATE / 2;
transfer[i].position = 0;
transfer[i].iteration++;
}
}
// Build a packet containing a file fragment
p = &netbuffer->u.filetxpak;
size = software_MAXPACKETLENGTH - (FILETXHEADER + BASEPACKETSIZE);
if (f->size-transfer[i].position < size)
size = f->size-transfer[i].position;
fragmentsize = FILEFRAGMENTSIZE;
if (f->size-transfer[i].position < fragmentsize)
fragmentsize = f->size-transfer[i].position;
if (ram)
M_Memcpy(p->data, &f->id.ram[transfer[i].position], size);
M_Memcpy(p->data, &f->id.ram[transfer[i].position], fragmentsize);
else
{
size_t n = fread(p->data, 1, size, transfer[i].currentfile);
if (n != size) // Either an error or Windows turning CR-LF into LF
{
if (f->textmode && feof(transfer[i].currentfile))
size = n;
else if (fread(p->data, 1, size, transfer[i].currentfile) != size)
I_Error("SV_FileSendTicker: can't read %s byte on %s at %d because %s", sizeu1(size), f->id.filename, transfer[i].position, M_FileError(transfer[i].currentfile));
}
fseek(transfer[i].currentfile, transfer[i].position, SEEK_SET);
if (fread(p->data, 1, fragmentsize, transfer[i].currentfile) != fragmentsize)
I_Error("FileSendTicker: can't read %s byte on %s at %d because %s", sizeu1(fragmentsize), f->id.filename, transfer[i].position, M_FileError(transfer[i].currentfile));
}
p->iteration = transfer[i].iteration;
p->position = LONG(transfer[i].position);
// Put flag so receiver knows the total size
if (transfer[i].position + size == f->size || (f->textmode && feof(transfer[i].currentfile)))
p->position |= LONG(0x80000000);
p->fileid = f->fileid;
p->size = SHORT((UINT16)size);
p->filesize = LONG(f->size);
p->size = SHORT((UINT16)FILEFRAGMENTSIZE);
// Send the packet
if (HSendPacket(i, true, 0, FILETXHEADER + size)) // Reliable SEND
if (HSendPacket(i, false, 0, FILETXHEADER + fragmentsize)) // Don't use the default acknowledgement system
{ // Success
transfer[i].position = (UINT32)(transfer[i].position + size);
if (transfer[i].position == f->size || (f->textmode && feof(transfer[i].currentfile))) // Finish?
SV_EndFileSend(i);
transfer[i].position = (UINT32)(transfer[i].position + fragmentsize);
if (transfer[i].position >= f->size)
{
if (transfer[i].ackediteration < transfer[i].iteration)
transfer[i].dontsenduntil = I_GetTime() + TICRATE / 2;
transfer[i].position = 0;
transfer[i].iteration++;
}
}
else
{ // Not sent for some odd reason, retry at next call
if (!ram)
fseek(transfer[i].currentfile,transfer[i].position, SEEK_SET);
// Exit the while (can't send this one so why should i send the next?)
break;
}
}
}
void Got_Filetxpak(void)
void PT_FileAck(void)
{
fileack_pak *packet = &netbuffer->u.fileack;
INT32 node = doomcom->remotenode;
filetran_t *trans = &transfer[node];
INT32 i, j;
// Wrong file id? Ignore it, it's probably a late packet
if (!(trans->txlist && packet->fileid == trans->txlist->fileid))
return;
if (packet->numsegments * sizeof(*packet->segments) != doomcom->datalength - BASEPACKETSIZE - sizeof(*packet))
{
Net_CloseConnection(node);
return;
}
if (packet->iteration > trans->ackediteration)
{
trans->ackediteration = packet->iteration;
if (trans->ackediteration >= trans->iteration - 1)
trans->dontsenduntil = 0;
}
for (i = 0; i < packet->numsegments; i++)
{
fileacksegment_t *segment = &packet->segments[i];
for (j = 0; j < 32; j++)
if (LONG(segment->acks) & (1 << j))
{
if (LONG(segment->start) * FILEFRAGMENTSIZE >= trans->txlist->size)
{
Net_CloseConnection(node);
return;
}
if (!trans->ackedfragments[LONG(segment->start) + j])
{
trans->ackedfragments[LONG(segment->start) + j] = true;
trans->ackedsize += FILEFRAGMENTSIZE;
// If the last missing fragment was acked, finish!
if (trans->ackedsize == trans->txlist->size)
{
SV_EndFileSend(node);
return;
}
}
}
}
}
void PT_FileReceived(void)
{
filetx_t *trans = transfer[doomcom->remotenode].txlist;
if (trans && netbuffer->u.filereceived == trans->fileid)
SV_EndFileSend(doomcom->remotenode);
}
static void SendAckPacket(fileack_pak *packet, UINT8 fileid)
{
size_t packetsize;
INT32 i;
packetsize = sizeof(*packet) + packet->numsegments * sizeof(*packet->segments);
// Finalise the packet
packet->fileid = fileid;
for (i = 0; i < packet->numsegments; i++)
{
packet->segments[i].start = LONG(packet->segments[i].start);
packet->segments[i].acks = LONG(packet->segments[i].acks);
}
// Send the packet
netbuffer->packettype = PT_FILEACK;
M_Memcpy(&netbuffer->u.fileack, packet, packetsize);
HSendPacket(servernode, false, 0, packetsize);
// Clear the packet
memset(packet, 0, sizeof(*packet) + 512);
}
static void AddFragmentToAckPacket(fileack_pak *packet, UINT8 iteration, UINT32 fragmentpos, UINT8 fileid)
{
fileacksegment_t *segment = &packet->segments[packet->numsegments - 1];
packet->iteration = max(packet->iteration, iteration);
if (packet->numsegments == 0
|| fragmentpos < segment->start
|| fragmentpos - segment->start >= 32)
{
// If the packet becomes too big, send it
if ((packet->numsegments + 1) * sizeof(*segment) > 512)
SendAckPacket(packet, fileid);
packet->numsegments++;
segment = &packet->segments[packet->numsegments - 1];
segment->start = fragmentpos;
}
// Set the bit that represents the fragment
segment->acks |= 1 << (fragmentpos - segment->start);
}
void FileReceiveTicker(void)
{
INT32 i;
for (i = 0; i < fileneedednum; i++)
{
fileneeded_t *file = &fileneeded[i];
if (file->status == FS_DOWNLOADING)
{
if (lasttimeackpacketsent - I_GetTime() > TICRATE / 2)
SendAckPacket(file->ackpacket, i);
// When resuming a tranfer, start with telling
// the server what parts we already received
if (file->ackresendposition != UINT32_MAX && file->status == FS_DOWNLOADING)
{
// Acknowledge ~70 MB/s, whichs means the client sends ~18 KB/s
INT32 j;
for (j = 0; j < 2048; j++)
{
if (file->receivedfragments[file->ackresendposition])
AddFragmentToAckPacket(file->ackpacket, file->iteration, file->ackresendposition, i);
file->ackresendposition++;
if (file->ackresendposition * file->fragmentsize >= file->totalsize)
{
file->ackresendposition = UINT32_MAX;
break;
}
}
}
}
}
}
void PT_FileFragment(void)
{
INT32 filenum = netbuffer->u.filetxpak.fileid;
fileneeded_t *file = &fileneeded[filenum];
UINT32 fragmentpos = LONG(netbuffer->u.filetxpak.position);
UINT16 fragmentsize = SHORT(netbuffer->u.filetxpak.size);
UINT16 boundedfragmentsize = doomcom->datalength - BASEPACKETSIZE - sizeof(netbuffer->u.filetxpak);
char *filename;
static INT32 filetime = 0;
filename = va("%s", file->filename);
nameonly(filename);
@ -1001,51 +1238,105 @@ void Got_Filetxpak(void)
if (file->status == FS_REQUESTED)
{
if (file->file)
I_Error("Got_Filetxpak: already open file\n");
file->file = fopen(filename, file->textmode ? "w" : "wb");
if (!file->file)
I_Error("Can't create file %s: %s", filename, strerror(errno));
CONS_Printf("\r%s...\n",filename);
file->currentsize = 0;
I_Error("PT_FileFragment: already open file\n");
file->status = FS_DOWNLOADING;
file->fragmentsize = fragmentsize;
file->iteration = 0;
file->ackpacket = calloc(1, sizeof(*file->ackpacket) + 512);
if (!file->ackpacket)
I_Error("FileSendTicker: No more memory\n");
if (CL_CanResumeDownload(file))
{
file->file = fopen(filename, "r+b");
if (!file->file)
I_Error("Can't reopen file %s: %s", filename, strerror(errno));
CONS_Printf("\r%s...\n", filename);
CONS_Printf("Resuming download...\n");
file->currentsize = pauseddownload->currentsize;
file->receivedfragments = pauseddownload->receivedfragments;
file->ackresendposition = 0;
free(pauseddownload);
pauseddownload = NULL;
}
else
{
CL_AbortDownloadResume();
file->file = fopen(filename, "wb");
if (!file->file)
I_Error("Can't create file %s: %s", filename, strerror(errno));
CONS_Printf("\r%s...\n",filename);
file->currentsize = 0;
file->totalsize = LONG(netbuffer->u.filetxpak.filesize);
file->ackresendposition = UINT32_MAX; // Only used for resumed downloads
file->receivedfragments = calloc(file->totalsize / fragmentsize + 1, sizeof(*file->receivedfragments));
if (!file->receivedfragments)
I_Error("FileSendTicker: No more memory\n");
}
lasttimeackpacketsent = I_GetTime();
}
if (file->status == FS_DOWNLOADING)
{
UINT32 pos = LONG(netbuffer->u.filetxpak.position);
UINT16 size = SHORT(netbuffer->u.filetxpak.size);
// Use a special trick to know when the file is complete (not always used)
// WARNING: file fragments can arrive out of order so don't stop yet!
if (pos & 0x80000000)
{
pos &= ~0x80000000;
file->totalsize = pos + size;
}
// We can receive packet in the wrong order, anyway all os support gaped file
fseek(file->file, pos, SEEK_SET);
if (size && fwrite(netbuffer->u.filetxpak.data,size,1,file->file) != 1)
I_Error("Can't write to %s: %s\n",filename, M_FileError(file->file));
file->currentsize += size;
if (fragmentpos >= file->totalsize)
I_Error("Invalid file fragment\n");
// Finished?
if (file->currentsize == file->totalsize)
file->iteration = max(file->iteration, netbuffer->u.filetxpak.iteration);
if (!file->receivedfragments[fragmentpos / fragmentsize]) // Not received yet
{
fclose(file->file);
file->file = NULL;
file->status = FS_FOUND;
CONS_Printf(M_GetText("Downloading %s...(done)\n"),
filename);
#ifdef HAVE_BLUA
if (luafiletransfers)
file->receivedfragments[fragmentpos / fragmentsize] = true;
// We can receive packets in the wrong order, anyway all OSes support gaped files
fseek(file->file, fragmentpos, SEEK_SET);
if (fragmentsize && fwrite(netbuffer->u.filetxpak.data, boundedfragmentsize, 1, file->file) != 1)
I_Error("Can't write to %s: %s\n",filename, M_FileError(file->file));
file->currentsize += boundedfragmentsize;
AddFragmentToAckPacket(file->ackpacket, file->iteration, fragmentpos / fragmentsize, filenum);
// Finished?
if (file->currentsize == file->totalsize)
{
fclose(file->file);
file->file = NULL;
free(file->receivedfragments);
free(file->ackpacket);
file->status = FS_FOUND;
file->justdownloaded = true;
CONS_Printf(M_GetText("Downloading %s...(done)\n"),
filename);
// Tell the server we have received the file
netbuffer->packettype = PT_HASLUAFILE;
HSendPacket(servernode, true, 0, 0);
netbuffer->packettype = PT_FILERECEIVED;
netbuffer->u.filereceived = filenum;
HSendPacket(servernode, true, 0, 1);
if (luafiletransfers)
{
// Tell the server we have received the file
netbuffer->packettype = PT_HASLUAFILE;
HSendPacket(servernode, true, 0, 0);
}
}
#endif
}
else // Already received
{
// If they are sending us the fragment again, it's probably because
// they missed our previous ack, so we must re-acknowledge it
AddFragmentToAckPacket(file->ackpacket, file->iteration, fragmentpos / fragmentsize, filenum);
}
}
else
else if (!file->justdownloaded)
{
const char *s;
switch(file->status)
@ -1068,14 +1359,8 @@ void Got_Filetxpak(void)
}
I_Error("Received a file not requested (file id: %d, file status: %s)\n", filenum, s);
}
// Send ack back quickly
if (++filetime == 3)
{
Net_SendAcks(servernode);
filetime = 0;
}
#ifdef CLIENT_LOADINGSCREEN
#ifndef NONET
lastfilenum = filenum;
#endif
}
@ -1086,7 +1371,7 @@ void Got_Filetxpak(void)
* \return True if the node is downloading a file
*
*/
boolean SV_SendingFile(INT32 node)
boolean SendingFile(INT32 node)
{
return transfer[node].txlist != NULL;
}
@ -1115,12 +1400,62 @@ void CloseNetFile(void)
if (fileneeded[i].status == FS_DOWNLOADING && fileneeded[i].file)
{
fclose(fileneeded[i].file);
// File is not complete delete it
remove(fileneeded[i].filename);
}
free(fileneeded[i].ackpacket);
// Remove PT_FILEFRAGMENT from acknowledge list
Net_AbortPacketType(PT_FILEFRAGMENT);
if (!pauseddownload && i != 0) // 0 is either srb2.srb or the gamestate...
{
// Don't remove the file, save it for later in case we resume the download
pauseddownload = malloc(sizeof(*pauseddownload));
if (!pauseddownload)
I_Error("CloseNetFile: No more memory\n");
strcpy(pauseddownload->filename, fileneeded[i].filename);
memcpy(pauseddownload->md5sum, fileneeded[i].md5sum, 16);
pauseddownload->currentsize = fileneeded[i].currentsize;
pauseddownload->receivedfragments = fileneeded[i].receivedfragments;
pauseddownload->fragmentsize = fileneeded[i].fragmentsize;
}
else
{
free(fileneeded[i].receivedfragments);
// File is not complete delete it
remove(fileneeded[i].filename);
}
}
}
void Command_Downloads_f(void)
{
INT32 node;
for (node = 0; node < MAXNETNODES; node++)
if (transfer[node].txlist
&& transfer[node].txlist->ram == SF_FILE) // Node is downloading a file?
{
const char *name = transfer[node].txlist->id.filename;
UINT32 position = transfer[node].ackedsize;
UINT32 size = transfer[node].txlist->size;
char ratecolor;
// Avoid division by zero errors
if (!size)
size = 1;
name = &name[strlen(name) - nameonlylength(name)];
switch (4 * (position - 1) / size)
{
case 0: ratecolor = '\x85'; break;
case 1: ratecolor = '\x87'; break;
case 2: ratecolor = '\x82'; break;
case 3: ratecolor = '\x83'; break;
default: ratecolor = '\x80';
}
CONS_Printf("%2d %c%s ", node, ratecolor, name); // Node and file name
CONS_Printf("\x80%uK\x84/\x80%uK ", position / 1024, size / 1024); // Progress in kB
CONS_Printf("\x80(%c%u%%\x80) ", ratecolor, (UINT32)(100.0 * position / size)); // Progress in %
CONS_Printf("%s\n", I_GetNodeAddress(node)); // Address and newline
}
}
// Functions cut and pasted from Doomatic :)

View file

@ -14,6 +14,7 @@
#define __D_NETFIL__
#include "d_net.h"
#include "d_clisrv.h"
#include "w_wad.h"
typedef enum
@ -39,19 +40,25 @@ typedef struct
UINT8 willsend; // Is the server willing to send it?
char filename[MAX_WADPATH];
UINT8 md5sum[16];
filestatus_t status; // The value returned by recsearch
boolean justdownloaded; // To prevent late fragments from causing an I_Error
// Used only for download
FILE *file;
boolean *receivedfragments;
UINT32 fragmentsize;
UINT8 iteration;
fileack_pak *ackpacket;
UINT32 currentsize;
UINT32 totalsize;
filestatus_t status; // The value returned by recsearch
boolean textmode; // For files requested by Lua without the "b" option
UINT32 ackresendposition; // Used when resuming downloads
} fileneeded_t;
extern INT32 fileneedednum;
extern fileneeded_t fileneeded[MAX_WADFILES];
extern char downloaddir[512];
#ifdef CLIENT_LOADINGSCREEN
#ifndef NONET
extern INT32 lastfilenum;
#endif
@ -61,18 +68,21 @@ void CL_PrepareDownloadSaveGame(const char *tmpsave);
INT32 CL_CheckFiles(void);
void CL_LoadServerFiles(void);
void SV_SendRam(INT32 node, void *data, size_t size, freemethod_t freemethod,
void AddRamToSendQueue(INT32 node, void *data, size_t size, freemethod_t freemethod,
UINT8 fileid);
void SV_FileSendTicker(void);
void Got_Filetxpak(void);
boolean SV_SendingFile(INT32 node);
void FileSendTicker(void);
void PT_FileAck(void);
void PT_FileReceived(void);
boolean SendingFile(INT32 node);
void FileReceiveTicker(void);
void PT_FileFragment(void);
boolean CL_CheckDownloadable(void);
boolean CL_SendRequestFile(void);
boolean Got_RequestFilePak(INT32 node);
boolean CL_SendFileRequest(void);
boolean PT_RequestFile(INT32 node);
#ifdef HAVE_BLUA
typedef enum
{
LFTNS_WAITING, // This node is waiting for the server to send the file
@ -87,18 +97,19 @@ typedef struct luafiletransfer_s
char *realfilename;
char mode[4]; // rb+/wb+/ab+ + null character
INT32 id; // Callback ID
boolean ongoing;
luafiletransfernodestatus_t nodestatus[MAXNETNODES];
struct luafiletransfer_s *next;
} luafiletransfer_t;
extern luafiletransfer_t *luafiletransfers;
extern boolean waitingforluafiletransfer;
extern boolean waitingforluafilecommand;
extern char luafiledir[256 + 16];
void AddLuaFileTransfer(const char *filename, const char *mode);
void SV_PrepareSendLuaFileToNextNode(void);
boolean SV_SendLuaFile(INT32 node, const char *filename, boolean textmode);
void SV_PrepareSendLuaFile(const char *filename);
void SV_PrepareSendLuaFile(void);
boolean AddLuaFileToSendQueue(INT32 node, const char *filename);
void SV_HandleLuaFileSent(UINT8 node);
void RemoveLuaFileTransfer(void);
void RemoveAllLuaFileTransfers(void);
@ -108,10 +119,12 @@ void Got_LuaFile(UINT8 **cp, INT32 playernum);
void StoreLuaFileCallback(INT32 id);
void RemoveLuaFileCallback(INT32 id);
void MakePathDirs(char *path);
#endif
void SV_AbortSendFiles(INT32 node);
void CloseNetFile(void);
void CL_AbortDownloadResume(void);
void Command_Downloads_f(void);
boolean fileexist(char *filename, time_t ptime);

View file

@ -48,6 +48,9 @@ typedef enum
SF_FASTEDGE = 1<<12, // Faster edge teeter?
SF_MULTIABILITY = 1<<13, // Revenge of Final Demo.
SF_NONIGHTSROTATION = 1<<14, // Disable sprite rotation for NiGHTS
SF_NONIGHTSSUPER = 1<<15, // Disable super colors for NiGHTS (if you have SF_SUPER)
SF_NOSUPERSPRITES = 1<<16, // Don't use super sprites while super
SF_NOSUPERJUMPBOOST = 1<<17, // Disable the jump boost given while super (i.e. Knuckles)
// free up to and including 1<<31
} skinflags_t;
@ -112,7 +115,7 @@ typedef enum
// True if button down last tic.
PF_ATTACKDOWN = 1<<7,
PF_USEDOWN = 1<<8,
PF_SPINDOWN = 1<<8,
PF_JUMPDOWN = 1<<9,
PF_WPNDOWN = 1<<10,
@ -238,7 +241,8 @@ typedef enum
CR_MACESPIN,
CR_MINECART,
CR_ROLLOUT,
CR_PTERABYTE
CR_PTERABYTE,
CR_DUSTDEVIL
} carrytype_t; // pw_carry
// Player powers. (don't edit this comment)
@ -278,8 +282,13 @@ typedef enum
pw_nights_linkfreeze,
pw_nocontrol, //for linedef exec 427
pw_dye, // for dyes
pw_justlaunched, // Launched off a slope this tic (0=none, 1=standard launch, 2=half-pipe launch)
pw_ignorelatch, // Don't grab onto CR_GENERIC, add 32768 (powers[pw_ignorelatch] & 1<<15) to avoid ALL not-NiGHTS CR_ types
NUMPOWERS
} powertype_t;
@ -327,6 +336,9 @@ typedef struct player_s
angle_t viewrollangle;
INT16 angleturn;
INT16 oldrelangleturn;
// Mouse aiming, where the guy is looking at!
// It is updated with cmd->aiming.
angle_t aiming;
@ -361,7 +373,7 @@ typedef struct player_s
UINT16 flashpal;
// Player skin colorshift, 0-15 for which color to draw player.
UINT8 skincolor;
UINT16 skincolor;
INT32 skin;
UINT32 availabilities;

View file

@ -31,7 +31,7 @@ typedef enum
BT_WEAPONPREV = 1<<5,
BT_ATTACK = 1<<6, // shoot rings
BT_USE = 1<<7, // spin
BT_SPIN = 1<<7,
BT_CAMLEFT = 1<<8, // turn camera left
BT_CAMRIGHT = 1<<9, // turn camera right
BT_TOSSFLAG = 1<<10,

View file

@ -31,6 +31,7 @@
#include "r_data.h"
#include "r_draw.h"
#include "r_patch.h"
#include "r_things.h" // R_Char2Frame
#include "r_sky.h"
#include "fastcmp.h"
#include "lua_script.h"
@ -39,28 +40,22 @@
#include "m_cond.h"
#ifdef HAVE_BLUA
#include "v_video.h" // video flags (for lua)
#endif
#ifdef HWRENDER
#include "hardware/hw_light.h"
#endif
#ifdef PC_DOS
#include <stdio.h> // for snprintf
//int snprintf(char *str, size_t n, const char *fmt, ...);
int vsnprintf(char *str, size_t n, const char *fmt, va_list ap);
#endif
// Free slot names
// The crazy word-reading stuff uses these.
static char *FREE_STATES[NUMSTATEFREESLOTS];
static char *FREE_MOBJS[NUMMOBJFREESLOTS];
static char *FREE_SKINCOLORS[NUMCOLORFREESLOTS];
static UINT8 used_spr[(NUMSPRITEFREESLOTS / 8) + 1]; // Bitwise flag for sprite freeslot in use! I would use ceil() here if I could, but it only saves 1 byte of memory anyway.
#define initfreeslots() {\
memset(FREE_STATES,0,sizeof(char *) * NUMSTATEFREESLOTS);\
memset(FREE_MOBJS,0,sizeof(char *) * NUMMOBJFREESLOTS);\
memset(FREE_SKINCOLORS,0,sizeof(char *) * NUMCOLORFREESLOTS);\
memset(used_spr,0,sizeof(UINT8) * ((NUMSPRITEFREESLOTS / 8) + 1));\
}
@ -76,10 +71,9 @@ static UINT16 get_mus(const char *word, UINT8 dehacked_mode);
#endif
static hudnum_t get_huditem(const char *word);
static menutype_t get_menutype(const char *word);
#ifndef HAVE_BLUA
static INT16 get_gametype(const char *word);
static powertype_t get_power(const char *word);
#endif
//static INT16 get_gametype(const char *word);
//static powertype_t get_power(const char *word);
skincolornum_t get_skincolor(const char *word);
boolean deh_loaded = false;
static int dbg_line;
@ -395,7 +389,7 @@ static void readPlayer(MYFILE *f, INT32 num)
// It works down here, though.
{
INT32 numline = 0;
for (i = 0; i < MAXLINELEN-1; i++)
for (i = 0; (size_t)i < sizeof(description[num].notes)-1; i++)
{
if (numline < 20 && description[num].notes[i] == '\n')
numline++;
@ -452,7 +446,7 @@ static void readPlayer(MYFILE *f, INT32 num)
else if (fastcmp(word, "OPPOSITECOLOR") || fastcmp(word, "OPPOSITECOLOUR"))
{
SLOTFOUND
description[num].oppositecolor = (UINT8)get_number(word2);
description[num].oppositecolor = (UINT16)get_number(word2);
}
else if (fastcmp(word, "NAMETAG") || fastcmp(word, "TAGNAME"))
{
@ -462,12 +456,12 @@ static void readPlayer(MYFILE *f, INT32 num)
else if (fastcmp(word, "TAGTEXTCOLOR") || fastcmp(word, "TAGTEXTCOLOUR"))
{
SLOTFOUND
description[num].tagtextcolor = (UINT8)get_number(word2);
description[num].tagtextcolor = (UINT16)get_number(word2);
}
else if (fastcmp(word, "TAGOUTLINECOLOR") || fastcmp(word, "TAGOUTLINECOLOUR"))
{
SLOTFOUND
description[num].tagoutlinecolor = (UINT8)get_number(word2);
description[num].tagoutlinecolor = (UINT16)get_number(word2);
}
else if (fastcmp(word, "STATUS"))
{
@ -574,6 +568,16 @@ static void readfreeslots(MYFILE *f)
break;
}
}
else if (fastcmp(type, "SKINCOLOR"))
{
for (i = 0; i < NUMCOLORFREESLOTS; i++)
if (!FREE_SKINCOLORS[i]) {
FREE_SKINCOLORS[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL);
strcpy(FREE_SKINCOLORS[i],word);
M_AddMenuColor(numskincolors++);
break;
}
}
else if (fastcmp(type, "SPR2"))
{
// Search if we already have an SPR2 by that name...
@ -756,6 +760,124 @@ static void readthing(MYFILE *f, INT32 num)
Z_Free(s);
}
static void readskincolor(MYFILE *f, INT32 num)
{
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
char *word = s;
char *word2;
char *tmp;
Color_cons_t[num].value = num;
do
{
if (myfgets(s, MAXLINELEN, f))
{
if (s[0] == '\n')
break;
// First remove trailing newline, if there is one
tmp = strchr(s, '\n');
if (tmp)
*tmp = '\0';
tmp = strchr(s, '#');
if (tmp)
*tmp = '\0';
if (s == tmp)
continue; // Skip comment lines, but don't break.
// Get the part before the " = "
tmp = strchr(s, '=');
if (tmp)
*(tmp-1) = '\0';
else
break;
strupr(word);
// Now get the part after
word2 = tmp += 2;
if (fastcmp(word, "NAME"))
{
size_t namesize = sizeof(skincolors[num].name);
char truncword[namesize];
UINT16 dupecheck;
deh_strlcpy(truncword, word2, namesize, va("Skincolor %d: name", num)); // truncate here to check for dupes
dupecheck = R_GetColorByName(truncword);
if (truncword[0] != '\0' && (!stricmp(truncword, skincolors[SKINCOLOR_NONE].name) || (dupecheck && dupecheck != num)))
{
size_t lastchar = strlen(truncword);
char oldword[lastchar+1];
char dupenum = '1';
strlcpy(oldword, truncword, lastchar+1);
lastchar--;
if (lastchar == namesize-2) // exactly max length, replace last character with 0
truncword[lastchar] = '0';
else // append 0
{
strcat(truncword, "0");
lastchar++;
}
while (R_GetColorByName(truncword))
{
truncword[lastchar] = dupenum;
if (dupenum == '9')
dupenum = 'A';
else if (dupenum == 'Z') // give up :?
break;
else
dupenum++;
}
deh_warning("Skincolor %d: name %s is a duplicate of another skincolor's name - renamed to %s", num, oldword, truncword);
}
strlcpy(skincolors[num].name, truncword, namesize); // already truncated
}
else if (fastcmp(word, "RAMP"))
{
UINT8 i;
tmp = strtok(word2,",");
for (i = 0; i < COLORRAMPSIZE; i++) {
skincolors[num].ramp[i] = (UINT8)get_number(tmp);
if ((tmp = strtok(NULL,",")) == NULL)
break;
}
skincolor_modified[num] = true;
}
else if (fastcmp(word, "INVCOLOR"))
{
UINT16 v = (UINT16)get_number(word2);
if (v < numskincolors)
skincolors[num].invcolor = v;
else
skincolors[num].invcolor = SKINCOLOR_GREEN;
}
else if (fastcmp(word, "INVSHADE"))
{
skincolors[num].invshade = get_number(word2)%COLORRAMPSIZE;
}
else if (fastcmp(word, "CHATCOLOR"))
{
skincolors[num].chatcolor = get_number(word2);
}
else if (fastcmp(word, "ACCESSIBLE"))
{
if (num > FIRSTSUPERCOLOR)
skincolors[num].accessible = (boolean)(atoi(word2) || word2[0] == 'T' || word2[0] == 'Y');
}
else
deh_warning("Skincolor %d: unknown word '%s'", num, word);
}
} while (!myfeof(f)); // finish when the line is empty
Z_Free(s);
}
#ifdef HWRENDER
static void readlight(MYFILE *f, INT32 num)
{
@ -1177,7 +1299,7 @@ static void readgametype(MYFILE *f, char *gtname)
// It works down here, though.
{
INT32 numline = 0;
for (i = 0; i < MAXLINELEN-1; i++)
for (i = 0; (size_t)i < sizeof(gtdescription)-1; i++)
{
if (numline < 20 && gtdescription[i] == '\n')
numline++;
@ -1415,7 +1537,6 @@ static void readlevelheader(MYFILE *f, INT32 num)
// Lua custom options also go above, contents may be case sensitive.
if (fastncmp(word, "LUA.", 4))
{
#ifdef HAVE_BLUA
UINT8 j;
customoption_t *modoption;
@ -1449,9 +1570,6 @@ static void readlevelheader(MYFILE *f, INT32 num)
modoption->option[31] = '\0';
strncpy(modoption->value, word2, 255);
modoption->value[255] = '\0';
#else
// Silently ignore.
#endif
continue;
}
@ -1564,7 +1682,7 @@ static void readlevelheader(MYFILE *f, INT32 num)
}
else if (fastcmp(word, "ACT"))
{
if (i >= 0 && i < 20) // 0 for no act number, TTL1 through TTL19
if (i >= 0 && i <= 99) // 0 for no act number
mapheaderinfo[num-1]->actnum = (UINT8)i;
else
deh_warning("Level header %d: invalid act number %d", num, i);
@ -1585,6 +1703,22 @@ static void readlevelheader(MYFILE *f, INT32 num)
mapheaderinfo[num-1]->nextlevel = (INT16)i;
}
else if (fastcmp(word, "MARATHONNEXT"))
{
if (fastcmp(word2, "TITLE")) i = 1100;
else if (fastcmp(word2, "EVALUATION")) i = 1101;
else if (fastcmp(word2, "CREDITS")) i = 1102;
else if (fastcmp(word2, "ENDING")) i = 1103;
else
// Support using the actual map name,
// i.e., MarathonNext = AB, MarathonNext = FZ, etc.
// Convert to map number
if (word2[0] >= 'A' && word2[0] <= 'Z' && word2[2] == '\0')
i = M_MapNumber(word2[0], word2[1]);
mapheaderinfo[num-1]->marathonnext = (INT16)i;
}
else if (fastcmp(word, "TYPEOFLEVEL"))
{
if (i) // it's just a number
@ -1870,6 +2004,12 @@ static void readlevelheader(MYFILE *f, INT32 num)
}
else if (fastcmp(word, "STARTRINGS"))
mapheaderinfo[num-1]->startrings = (UINT16)i;
else if (fastcmp(word, "SPECIALSTAGETIME"))
mapheaderinfo[num-1]->sstimer = i;
else if (fastcmp(word, "SPECIALSTAGESPHERES"))
mapheaderinfo[num-1]->ssspheres = i;
else if (fastcmp(word, "GRAVITY"))
mapheaderinfo[num-1]->gravity = FLOAT_TO_FIXED(atof(word2));
else
deh_warning("Level header %d: unknown word '%s'", num, word);
}
@ -2814,7 +2954,7 @@ static actionpointer_t actionpointers[] =
{{A_ThrownRing}, "A_THROWNRING"},
{{A_SetSolidSteam}, "A_SETSOLIDSTEAM"},
{{A_UnsetSolidSteam}, "A_UNSETSOLIDSTEAM"},
{{A_SignSpin}, "S_SIGNSPIN"},
{{A_SignSpin}, "A_SIGNSPIN"},
{{A_SignPlayer}, "A_SIGNPLAYER"},
{{A_OverlayThink}, "A_OVERLAYTHINK"},
{{A_JetChase}, "A_JETCHASE"},
@ -2916,6 +3056,7 @@ static actionpointer_t actionpointers[] =
{{A_SetRandomTics}, "A_SETRANDOMTICS"},
{{A_ChangeColorRelative}, "A_CHANGECOLORRELATIVE"},
{{A_ChangeColorAbsolute}, "A_CHANGECOLORABSOLUTE"},
{{A_Dye}, "A_DYE"},
{{A_MoveRelative}, "A_MOVERELATIVE"},
{{A_MoveAbsolute}, "A_MOVEABSOLUTE"},
{{A_Thrust}, "A_THRUST"},
@ -2975,6 +3116,7 @@ static actionpointer_t actionpointers[] =
{{A_NapalmScatter}, "A_NAPALMSCATTER"},
{{A_SpawnFreshCopy}, "A_SPAWNFRESHCOPY"},
{{A_FlickySpawn}, "A_FLICKYSPAWN"},
{{A_FlickyCenter}, "A_FLICKYCENTER"},
{{A_FlickyAim}, "A_FLICKYAIM"},
{{A_FlickyFly}, "A_FLICKYFLY"},
{{A_FlickySoar}, "A_FLICKYSOAR"},
@ -3033,6 +3175,7 @@ static actionpointer_t actionpointers[] =
{{A_DragonbomberSpawn}, "A_DRAGONBOMERSPAWN"},
{{A_DragonWing}, "A_DRAGONWING"},
{{A_DragonSegment}, "A_DRAGONSEGMENT"},
{{A_ChangeHeight}, "A_CHANGEHEIGHT"},
{{NULL}, "NONE"},
// This NULL entry must be the last in the list
@ -3123,22 +3266,20 @@ static void readframe(MYFILE *f, INT32 num)
}
z = 0;
#ifdef HAVE_BLUA
found = LUA_SetLuaAction(&states[num], actiontocompare);
if (!found)
#endif
while (actionpointers[z].name)
{
if (fastcmp(actiontocompare, actionpointers[z].name))
while (actionpointers[z].name)
{
states[num].action = actionpointers[z].action;
states[num].action.acv = actionpointers[z].action.acv; // assign
states[num].action.acp1 = actionpointers[z].action.acp1;
found = true;
break;
if (fastcmp(actiontocompare, actionpointers[z].name))
{
states[num].action = actionpointers[z].action;
states[num].action.acv = actionpointers[z].action.acv; // assign
states[num].action.acp1 = actionpointers[z].action.acp1;
found = true;
break;
}
z++;
}
z++;
}
if (!found)
deh_warning("Unknown action %s", actiontocompare);
@ -3889,7 +4030,26 @@ static void readmaincfg(MYFILE *f)
value = atoi(word2); // used for numerical settings
if (fastcmp(word, "EXECCFG"))
COM_BufAddText(va("exec %s\n", word2));
{
if (strchr(word2, '.'))
COM_BufAddText(va("exec %s\n", word2));
else
{
lumpnum_t lumpnum;
char newname[9];
strncpy(newname, word2, 8);
newname[8] = '\0';
lumpnum = W_CheckNumForName(newname);
if (lumpnum == LUMPERROR || W_LumpLength(lumpnum) == 0)
CONS_Debug(DBG_SETUP, "SOC Error: script lump %s not found/not valid.\n", newname);
else
COM_BufInsertText(W_CacheLumpNum(lumpnum, PU_CACHE));
}
}
else if (fastcmp(word, "SPSTAGE_START"))
{
@ -3902,7 +4062,20 @@ static void readmaincfg(MYFILE *f)
else
value = get_number(word2);
spstage_start = (INT16)value;
spstage_start = spmarathon_start = (INT16)value;
}
else if (fastcmp(word, "SPMARATHON_START"))
{
// Support using the actual map name,
// i.e., Level AB, Level FZ, etc.
// Convert to map number
if (word2[0] >= 'A' && word2[0] <= 'Z')
value = M_MapNumber(word2[0], word2[1]);
else
value = get_number(word2);
spmarathon_start = (INT16)value;
}
else if (fastcmp(word, "SSTAGE_START"))
{
@ -3934,19 +4107,19 @@ static void readmaincfg(MYFILE *f)
}
else if (fastcmp(word, "REDTEAM"))
{
skincolor_redteam = (UINT8)get_number(word2);
skincolor_redteam = (UINT16)get_number(word2);
}
else if (fastcmp(word, "BLUETEAM"))
{
skincolor_blueteam = (UINT8)get_number(word2);
skincolor_blueteam = (UINT16)get_number(word2);
}
else if (fastcmp(word, "REDRING"))
{
skincolor_redring = (UINT8)get_number(word2);
skincolor_redring = (UINT16)get_number(word2);
}
else if (fastcmp(word, "BLUERING"))
{
skincolor_bluering = (UINT8)get_number(word2);
skincolor_bluering = (UINT16)get_number(word2);
}
else if (fastcmp(word, "INVULNTICS"))
{
@ -3996,6 +4169,17 @@ static void readmaincfg(MYFILE *f)
introtoplay = 128;
introchanged = true;
}
else if (fastcmp(word, "CREDITSCUTSCENE"))
{
creditscutscene = (UINT8)get_number(word2);
// range check, you morons.
if (creditscutscene > 128)
creditscutscene = 128;
}
else if (fastcmp(word, "USEBLACKROCK"))
{
useBlackRock = (UINT8)(value || word2[0] == 'T' || word2[0] == 'Y');
}
else if (fastcmp(word, "LOOPTITLE"))
{
looptitle = (value || word2[0] == 'T' || word2[0] == 'Y');
@ -4097,13 +4281,6 @@ static void readmaincfg(MYFILE *f)
titlescrollyspeed = get_number(word2);
titlechanged = true;
}
else if (fastcmp(word, "CREDITSCUTSCENE"))
{
creditscutscene = (UINT8)get_number(word2);
// range check, you morons.
if (creditscutscene > 128)
creditscutscene = 128;
}
else if (fastcmp(word, "DISABLESPEEDADJUST"))
{
disableSpeedAdjust = (value || word2[0] == 'T' || word2[0] == 'Y');
@ -4131,6 +4308,10 @@ static void readmaincfg(MYFILE *f)
{
maxXtraLife = (UINT8)get_number(word2);
}
else if (fastcmp(word, "USECONTINUES"))
{
useContinues = (UINT8)(value || word2[0] == 'T' || word2[0] == 'Y');
}
else if (fastcmp(word, "GAMEDATA"))
{
@ -4156,6 +4337,9 @@ static void readmaincfg(MYFILE *f)
// can't use sprintf since there is %u in savegamename
strcatbf(savegamename, srb2home, PATHSEP);
strcpy(liveeventbackup, va("live%s.bkp", timeattackfolder));
strcatbf(liveeventbackup, srb2home, PATHSEP);
gamedataadded = true;
titlechanged = true;
}
@ -4534,6 +4718,18 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile)
ignorelines(f);
}
}
else if (fastcmp(word, "SKINCOLOR") || fastcmp(word, "COLOR"))
{
if (i == 0 && word2[0] != '0') // If word2 isn't a number
i = get_skincolor(word2); // find a skincolor by name
if (i && i < numskincolors)
readskincolor(f, i);
else
{
deh_warning("Skincolor %d out of range (1 - %d)", i, numskincolors-1);
ignorelines(f);
}
}
else if (fastcmp(word, "SPRITE2"))
{
if (i == 0 && word2[0] != '0') // If word2 isn't a number
@ -5173,6 +5369,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_JETJAW_CHOMP14",
"S_JETJAW_CHOMP15",
"S_JETJAW_CHOMP16",
"S_JETJAW_SOUND",
// Snailer
"S_SNAILER1",
@ -5595,10 +5792,12 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_FANG_PINCHPATHINGSTART1",
"S_FANG_PINCHPATHINGSTART2",
"S_FANG_PINCHPATHING",
"S_FANG_PINCHBOUNCE0",
"S_FANG_PINCHBOUNCE1",
"S_FANG_PINCHBOUNCE2",
"S_FANG_PINCHBOUNCE3",
"S_FANG_PINCHBOUNCE4",
"S_FANG_PINCHFALL0",
"S_FANG_PINCHFALL1",
"S_FANG_PINCHFALL2",
"S_FANG_PINCHSKID1",
@ -6210,6 +6409,14 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_ROCKET",
"S_LASER",
"S_LASER2",
"S_LASERFLASH",
"S_LASERFLAME1",
"S_LASERFLAME2",
"S_LASERFLAME3",
"S_LASERFLAME4",
"S_LASERFLAME5",
"S_TORPEDO",
@ -7977,6 +8184,9 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_GFZDEBRIS",
"S_BRICKDEBRIS",
"S_WOODDEBRIS",
"S_REDBRICKDEBRIS",
"S_BLUEBRICKDEBRIS",
"S_YELLOWBRICKDEBRIS",
#ifdef SEENAMES
"S_NAMECHECK",
@ -8724,7 +8934,6 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
"MT_ANGLEMAN",
"MT_POLYANCHOR",
"MT_POLYSPAWN",
"MT_POLYSPAWNCRUSH",
// Skybox objects
"MT_SKYBOX",
@ -8757,6 +8966,9 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
"MT_GFZDEBRIS",
"MT_BRICKDEBRIS",
"MT_WOODDEBRIS",
"MT_REDBRICKDEBRIS",
"MT_BLUEBRICKDEBRIS",
"MT_YELLOWBRICKDEBRIS",
#ifdef SEENAMES
"MT_NAMECHECK",
@ -8848,14 +9060,12 @@ static const char *const MOBJEFLAG_LIST[] = {
NULL
};
#ifdef HAVE_BLUA
static const char *const MAPTHINGFLAG_LIST[4] = {
"EXTRA", // Extra flag for objects.
"OBJECTFLIP", // Reverse gravity flag for objects.
"OBJECTSPECIAL", // Special flag used with certain objects.
"AMBUSH" // Deaf monsters/do not react to sound.
};
#endif
static const char *const PLAYERFLAG_LIST[] = {
@ -8872,7 +9082,7 @@ static const char *const PLAYERFLAG_LIST[] = {
// True if button down last tic.
"ATTACKDOWN",
"USEDOWN",
"SPINDOWN",
"JUMPDOWN",
"WPNDOWN",
@ -8952,7 +9162,6 @@ static const char *const GAMETYPERULE_LIST[] = {
NULL
};
#ifdef HAVE_BLUA
// Linedef flags
static const char *const ML_LIST[16] = {
"IMPASSIBLE",
@ -8972,10 +9181,7 @@ static const char *const ML_LIST[16] = {
"BOUNCY",
"TFERLINE"
};
#endif
// This DOES differ from r_draw's Color_Names, unfortunately.
// Also includes Super colors
static const char *COLOR_ENUMS[] = {
"NONE", // SKINCOLOR_NONE,
@ -9145,7 +9351,13 @@ static const char *const POWERS_LIST[] = {
//for linedef exec 427
"NOCONTROL",
//for dyes
"DYE",
"JUSTLAUNCHED",
"IGNORELATCH"
};
static const char *const HUDITEMS_LIST[] = {
@ -9209,6 +9421,7 @@ static const char *const MENUTYPES_LIST[] = {
"MP_CONNECT",
"MP_ROOM",
"MP_PLAYERSETUP", // MP_PlayerSetupDef shared with SPLITSCREEN if #defined NONET
"MP_SERVER_OPTIONS",
// Options
"OP_MAIN",
@ -9218,18 +9431,20 @@ static const char *const MENUTYPES_LIST[] = {
"OP_P1MOUSE",
"OP_P1JOYSTICK",
"OP_JOYSTICKSET", // OP_JoystickSetDef shared with P2
"OP_P1CAMERA",
"OP_P2CONTROLS",
"OP_P2MOUSE",
"OP_P2JOYSTICK",
"OP_P2CAMERA",
"OP_PLAYSTYLE",
"OP_VIDEO",
"OP_VIDEOMODE",
"OP_COLOR",
"OP_OPENGL",
"OP_OPENGL_LIGHTING",
"OP_OPENGL_FOG",
"OP_OPENGL_COLOR",
"OP_SOUND",
@ -9271,11 +9486,7 @@ static const char *const MENUTYPES_LIST[] = {
struct {
const char *n;
// has to be able to hold both fixed_t and angle_t, so drastic measure!!
#ifdef HAVE_BLUA
lua_Integer v;
#else
INT64 v;
#endif
} const INT_CONST[] = {
// If a mod removes some variables here,
// please leave the names in-tact and just set
@ -9306,8 +9517,6 @@ struct {
{"PUSHACCEL",PUSHACCEL},
{"MODID",MODID}, // I don't know, I just thought it would be cool for a wad to potentially know what mod it was loaded into.
{"CODEBASE",CODEBASE}, // or what release of SRB2 this is.
{"VERSION",VERSION}, // Grab the game's version!
{"SUBVERSION",SUBVERSION}, // more precise version number
{"NEWTICRATE",NEWTICRATE}, // TICRATE*NEWTICRATERATIO
{"NEWTICRATERATIO",NEWTICRATERATIO},
@ -9338,6 +9547,7 @@ struct {
{"FF_GLOBALANIM",FF_GLOBALANIM},
{"FF_FULLBRIGHT",FF_FULLBRIGHT},
{"FF_VERTICALFLIP",FF_VERTICALFLIP},
{"FF_HORIZONTALFLIP",FF_HORIZONTALFLIP},
{"FF_PAPERSPRITE",FF_PAPERSPRITE},
{"FF_TRANSMASK",FF_TRANSMASK},
{"FF_TRANSSHIFT",FF_TRANSSHIFT},
@ -9406,7 +9616,8 @@ struct {
// SKINCOLOR_ doesn't include these..!
{"MAXSKINCOLORS",MAXSKINCOLORS},
{"MAXTRANSLATIONS",MAXTRANSLATIONS},
{"FIRSTSUPERCOLOR",FIRSTSUPERCOLOR},
{"NUMSUPERCOLORS",NUMSUPERCOLORS},
// Precipitation
{"PRECIP_NONE",PRECIP_NONE},
@ -9457,6 +9668,7 @@ struct {
{"CR_MINECART",CR_MINECART},
{"CR_ROLLOUT",CR_ROLLOUT},
{"CR_PTERABYTE",CR_PTERABYTE},
{"CR_DUSTDEVIL",CR_DUSTDEVIL},
// Ring weapons (ringweapons_t)
// Useful for A_GiveWeapon
@ -9484,6 +9696,9 @@ struct {
{"SF_FASTEDGE",SF_FASTEDGE},
{"SF_MULTIABILITY",SF_MULTIABILITY},
{"SF_NONIGHTSROTATION",SF_NONIGHTSROTATION},
{"SF_NONIGHTSSUPER",SF_NONIGHTSSUPER},
{"SF_NOSUPERSPRITES",SF_NOSUPERSPRITES},
{"SF_NOSUPERJUMPBOOST",SF_NOSUPERJUMPBOOST},
// Dashmode constants
{"DASHMODE_THRESHOLD",DASHMODE_THRESHOLD},
@ -9531,7 +9746,6 @@ struct {
{"ME_ULTIMATE",ME_ULTIMATE},
{"ME_PERFECT",ME_PERFECT},
#ifdef HAVE_BLUA
// p_local.h constants
{"FLOATSPEED",FLOATSPEED},
{"MAXSTEPMOVE",MAXSTEPMOVE},
@ -9666,11 +9880,11 @@ struct {
{"FF_CUTEXTRA",FF_CUTEXTRA}, ///< Cuts out hidden translucent pixels.
{"FF_CUTLEVEL",FF_CUTLEVEL}, ///< Cuts out all hidden pixels.
{"FF_CUTSPRITES",FF_CUTSPRITES}, ///< Final step in making 3D water.
{"FF_BOTHPLANES",FF_BOTHPLANES}, ///< Renders both planes all the time.
{"FF_BOTHPLANES",FF_BOTHPLANES}, ///< Render inside and outside planes.
{"FF_EXTRA",FF_EXTRA}, ///< Gets cut by ::FF_CUTEXTRA.
{"FF_TRANSLUCENT",FF_TRANSLUCENT}, ///< See through!
{"FF_FOG",FF_FOG}, ///< Fog "brush."
{"FF_INVERTPLANES",FF_INVERTPLANES}, ///< Reverse the plane visibility rules.
{"FF_INVERTPLANES",FF_INVERTPLANES}, ///< Only render inside planes.
{"FF_ALLSIDES",FF_ALLSIDES}, ///< Render inside and outside sides.
{"FF_INVERTSIDES",FF_INVERTSIDES}, ///< Only render inside sides.
{"FF_DOUBLESHADOW",FF_DOUBLESHADOW}, ///< Make two lightlist entries to reset light?
@ -9696,11 +9910,10 @@ struct {
// Node flags
{"NF_SUBSECTOR",NF_SUBSECTOR}, // Indicate a leaf.
#endif
#ifdef ESLOPE
// Slope flags
{"SL_NOPHYSICS",SL_NOPHYSICS},
{"SL_DYNAMIC",SL_DYNAMIC},
#endif
// Angles
{"ANG1",ANG1},
@ -9756,7 +9969,7 @@ struct {
{"BT_WEAPONNEXT",BT_WEAPONNEXT},
{"BT_WEAPONPREV",BT_WEAPONPREV},
{"BT_ATTACK",BT_ATTACK}, // shoot rings
{"BT_USE",BT_USE}, // spin
{"BT_SPIN",BT_SPIN},
{"BT_CAMLEFT",BT_CAMLEFT}, // turn camera left
{"BT_CAMRIGHT",BT_CAMRIGHT}, // turn camera right
{"BT_TOSSFLAG",BT_TOSSFLAG},
@ -9864,7 +10077,12 @@ struct {
{"TC_RAINBOW",TC_RAINBOW},
{"TC_BLINK",TC_BLINK},
{"TC_DASHMODE",TC_DASHMODE},
#endif
// marathonmode flags
{"MA_INIT",MA_INIT},
{"MA_RUNNING",MA_RUNNING},
{"MA_NOCUTSCENES",MA_NOCUTSCENES},
{"MA_INGAME",MA_INGAME},
{NULL,0}
};
@ -9909,6 +10127,26 @@ static statenum_t get_state(const char *word)
return S_NULL;
}
skincolornum_t get_skincolor(const char *word)
{ // Returns the value of SKINCOLOR_ enumerations
skincolornum_t i;
if (*word >= '0' && *word <= '9')
return atoi(word);
if (fastncmp("SKINCOLOR_",word,10))
word += 10; // take off the SKINCOLOR_
for (i = 0; i < NUMCOLORFREESLOTS; i++) {
if (!FREE_SKINCOLORS[i])
break;
if (fastcmp(word, FREE_SKINCOLORS[i]))
return SKINCOLOR_FIRSTFREESLOT+i;
}
for (i = 0; i < SKINCOLOR_FIRSTFREESLOT; i++)
if (fastcmp(word, COLOR_ENUMS[i]))
return i;
deh_warning("Couldn't find skincolor named 'SKINCOLOR_%s'",word);
return SKINCOLOR_GREEN;
}
static spritenum_t get_sprite(const char *word)
{ // Returns the value of SPR_ enumerations
spritenum_t i;
@ -10021,8 +10259,7 @@ static menutype_t get_menutype(const char *word)
return MN_NONE;
}
#ifndef HAVE_BLUA
static INT16 get_gametype(const char *word)
/*static INT16 get_gametype(const char *word)
{ // Returns the value of GT_ enumerations
INT16 i;
if (*word >= '0' && *word <= '9')
@ -10048,7 +10285,7 @@ static powertype_t get_power(const char *word)
return i;
deh_warning("Couldn't find power named 'pw_%s'",word);
return pw_invulnerability;
}
}*/
/// \todo Make ANY of this completely over-the-top math craziness obey the order of operations.
static fixed_t op_mul(fixed_t a, fixed_t b) { return a*b; }
@ -10076,7 +10313,7 @@ struct {
};
// Returns the full word, cut at the first symbol or whitespace
static char *read_word(const char *line)
/*static char *read_word(const char *line)
{
// Part 1: You got the start of the word, now find the end.
const char *p;
@ -10204,6 +10441,11 @@ static fixed_t find_const(const char **rword)
free(word);
return r;
}
else if (fastncmp("SKINCOLOR_",word,10)) {
r = get_skincolor(word);
free(word);
return r;
}
else if (fastncmp("MT_",word,3)) {
r = get_mobjtype(word);
free(word);
@ -10272,17 +10514,6 @@ static fixed_t find_const(const char **rword)
free(word);
return r;
}
else if (fastncmp("SKINCOLOR_",word,10)) {
char *p = word+10;
for (i = 0; i < MAXTRANSLATIONS; i++)
if (fastcmp(p, COLOR_ENUMS[i])) {
free(word);
return i;
}
const_warning("color",word);
free(word);
return 0;
}
else if (fastncmp("GRADE_",word,6))
{
char *p = word+6;
@ -10306,16 +10537,14 @@ static fixed_t find_const(const char **rword)
const_warning("constant",word);
free(word);
return 0;
}
#endif
}*/
// Loops through every constant and operation in word and performs its calculations, returning the final value.
fixed_t get_number(const char *word)
{
#ifdef HAVE_BLUA
return LUA_EvalMath(word);
#else
// DESPERATELY NEEDED: Order of operations support! :x
/*// DESPERATELY NEEDED: Order of operations support! :x
fixed_t i = find_const(&word);
INT32 o;
while(*word) {
@ -10325,8 +10554,7 @@ fixed_t get_number(const char *word)
else
break;
}
return i;
#endif
return i;*/
}
void DEH_Check(void)
@ -10346,12 +10574,11 @@ void DEH_Check(void)
if (dehpowers != NUMPOWERS)
I_Error("You forgot to update the Dehacked powers list, you dolt!\n(%d powers defined, versus %s in the Dehacked list)\n", NUMPOWERS, sizeu1(dehpowers));
if (dehcolors != MAXTRANSLATIONS)
I_Error("You forgot to update the Dehacked colors list, you dolt!\n(%d colors defined, versus %s in the Dehacked list)\n", MAXTRANSLATIONS, sizeu1(dehcolors));
if (dehcolors != SKINCOLOR_FIRSTFREESLOT)
I_Error("You forgot to update the Dehacked colors list, you dolt!\n(%d colors defined, versus %s in the Dehacked list)\n", SKINCOLOR_FIRSTFREESLOT, sizeu1(dehcolors));
#endif
}
#ifdef HAVE_BLUA
#include "lua_script.h"
#include "lua_libs.h"
@ -10434,7 +10661,7 @@ static inline int lib_freeslot(lua_State *L)
CONS_Printf("State S_%s allocated.\n",word);
FREE_STATES[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL);
strcpy(FREE_STATES[i],word);
lua_pushinteger(L, i);
lua_pushinteger(L, S_FIRSTFREESLOT + i);
r++;
break;
}
@ -10449,13 +10676,29 @@ static inline int lib_freeslot(lua_State *L)
CONS_Printf("MobjType MT_%s allocated.\n",word);
FREE_MOBJS[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL);
strcpy(FREE_MOBJS[i],word);
lua_pushinteger(L, i);
lua_pushinteger(L, MT_FIRSTFREESLOT + i);
r++;
break;
}
if (i == NUMMOBJFREESLOTS)
CONS_Alert(CONS_WARNING, "Ran out of free MobjType slots!\n");
}
else if (fastcmp(type, "SKINCOLOR"))
{
skincolornum_t i;
for (i = 0; i < NUMCOLORFREESLOTS; i++)
if (!FREE_SKINCOLORS[i]) {
CONS_Printf("Skincolor SKINCOLOR_%s allocated.\n",word);
FREE_SKINCOLORS[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL);
strcpy(FREE_SKINCOLORS[i],word);
M_AddMenuColor(numskincolors++);
lua_pushinteger(L, SKINCOLOR_FIRSTFREESLOT + i);
r++;
break;
}
if (i == NUMCOLORFREESLOTS)
CONS_Alert(CONS_WARNING, "Ran out of free skincolor slots!\n");
}
else if (fastcmp(type, "SPR2"))
{
// Search if we already have an SPR2 by that name...
@ -10470,11 +10713,12 @@ static inline int lib_freeslot(lua_State *L)
CONS_Printf("Sprite SPR2_%s allocated.\n",word);
strncpy(spr2names[free_spr2],word,4);
spr2defaults[free_spr2] = 0;
lua_pushinteger(L, free_spr2);
r++;
spr2names[free_spr2++][4] = 0;
} else
CONS_Alert(CONS_WARNING, "Ran out of free SPR2 slots!\n");
}
r++;
}
else if (fastcmp(type, "TOL"))
{
@ -10598,6 +10842,12 @@ static inline int lib_getenum(lua_State *L)
lua_pushinteger(L, (lua_Integer)PF_FULLSTASIS);
return 1;
}
else if (fastcmp(p, "USEDOWN")) // Remove case when 2.3 nears release...
{
LUA_Deprecated(L, "PF_USEDOWN", "PF_SPINDOWN");
lua_pushinteger(L, (lua_Integer)PF_SPINDOWN);
return 1;
}
if (mathlib) return luaL_error(L, "playerflag '%s' could not be found.\n", word);
return 0;
}
@ -10787,13 +11037,20 @@ static inline int lib_getenum(lua_State *L)
}
else if (fastncmp("SKINCOLOR_",word,10)) {
p = word+10;
for (i = 0; i < MAXTRANSLATIONS; i++)
for (i = 0; i < NUMCOLORFREESLOTS; i++) {
if (!FREE_SKINCOLORS[i])
break;
if (fastcmp(p, FREE_SKINCOLORS[i])) {
lua_pushinteger(L, SKINCOLOR_FIRSTFREESLOT+i);
return 1;
}
}
for (i = 0; i < SKINCOLOR_FIRSTFREESLOT; i++)
if (fastcmp(p, COLOR_ENUMS[i])) {
lua_pushinteger(L, i);
return 1;
}
if (mathlib) return luaL_error(L, "skincolor '%s' could not be found.\n", word);
return 0;
return luaL_error(L, "skincolor '%s' could not be found.\n", word);
}
else if (fastncmp("GRADE_",word,6))
{
@ -10857,6 +11114,13 @@ static inline int lib_getenum(lua_State *L)
return 0;
}
if (fastcmp(word, "BT_USE")) // Remove case when 2.3 nears release...
{
LUA_Deprecated(L, "BT_USE", "BT_SPIN");
lua_pushinteger(L, (lua_Integer)BT_SPIN);
return 1;
}
for (i = 0; INT_CONST[i].n; i++)
if (fastcmp(word,INT_CONST[i].n)) {
lua_pushinteger(L, INT_CONST[i].v);
@ -10977,5 +11241,3 @@ void LUA_SetActionByName(void *state, const char *actiontocompare)
}
}
}
#endif // HAVE_BLUA

View file

@ -34,11 +34,9 @@ void DEH_Check(void);
fixed_t get_number(const char *word);
#ifdef HAVE_BLUA
boolean LUA_SetLuaAction(void *state, const char *actiontocompare);
const char *LUA_GetActionName(void *action);
void LUA_SetActionByName(void *state, const char *actiontocompare);
#endif
extern boolean deh_loaded;

View file

@ -1,48 +0,0 @@
#
# djgppdos/makefile.cfg for SRB2/DOS
#
#
#now for the DOS stuff, go DOS!
#
# options
OPTS=-DPC_DOS
WFLAGS+=-Wno-cast-qual
NOHW=1
NOHS=1
PNG_CFLAGS=
PNG_LDFLAGS=-lpng -lz
ifdef WATTCP
OPTS+=-DWATTCP
NOOBJDUMP=1
endif
#ifdef DEBUGMODE
LIBS=-lalld
#else
# LIBS=-lalleg
#endif
ifndef NONET
ifdef WATTCP
LIBS+=-lwatt
else
LIBS+=-lsocket
endif
endif
ifdef RDB
LIBS+=-lgdbst -ldzcom
OPTS+=-DREMOTE_DEBUGGING
endif
OBJS=$(OBJDIR)/i_video.o $(OBJDIR)/vid_vesa.o
# name of the exefile
ifdef WATTCP
EXENAME?=srb2dos.exe
else
EXENAME?=srb2w16.exe
endif

View file

@ -1,755 +0,0 @@
/* bcd.c -- Brennan's CD-ROM Audio Playing Library
by Brennan Underwood, http://brennan.home.ml.org/ */
#include <dos.h>
#include <dpmi.h>
#include <go32.h>
#include <fcntl.h>
#include <stdio.h>
#include <malloc.h>
#include <unistd.h>
#include <strings.h>
#ifdef STANDALONE
#include <conio.h> /* for getch() */
#endif
#include "bcd.h"
typedef struct {
int is_audio;
int start, end, len;
} Track;
static int mscdex_version;
static int first_drive;
static int num_tracks;
static int lowest_track, highest_track;
static int audio_length;
#ifdef STATIC_TRACKS
static Track tracks[99];
#else
static Track *tracks;
#endif
static int dos_mem_segment, dos_mem_selector = -1;
int _status, _error, _error_code;
const char *_bcd_error = NULL;
#define RESET_ERROR (_error = _error_code = 0)
#define ERROR_BIT (1 << 15)
#define BUSY_BIT (1 << 9)
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
#pragma pack(1)
/* I know 'typedef struct {} bleh' is a bad habit, but... */
typedef struct {
unsigned char len;
unsigned char unit;
unsigned char command;
unsigned short status;
unsigned char reserved[8];
} ATTRPACK RequestHeader;
typedef struct {
RequestHeader request_header;
unsigned char descriptor;
unsigned long address;
unsigned short len;
unsigned short secnum;
unsigned long ptr;
} ATTRPACK IOCTLI;
typedef struct {
unsigned char control;
unsigned char lowest;
unsigned char highest;
char total[4];
} ATTRPACK DiskInfo;
typedef struct {
unsigned char control;
unsigned char track_number;
char start[4];
unsigned char info;
} ATTRPACK TrackInfo;
typedef struct {
RequestHeader request;
unsigned char mode;
unsigned long start;
unsigned long len;
} ATTRPACK PlayRequest;
typedef struct {
RequestHeader request;
} ATTRPACK StopRequest;
typedef struct {
RequestHeader request;
} ATTRPACK ResumeRequest;
typedef struct {
unsigned char control;
unsigned char input0;
unsigned char volume0;
unsigned char input1;
unsigned char volume1;
unsigned char input2;
unsigned char volume2;
unsigned char input3;
unsigned char volume3;
} ATTRPACK VolumeRequest;
typedef struct {
unsigned char control;
unsigned char fn;
} ATTRPACK LockRequest;
typedef struct {
unsigned char control;
unsigned char mbyte;
} ATTRPACK MediaChangedRequest;
typedef struct {
unsigned char control;
unsigned long status;
} ATTRPACK StatusRequest;
typedef struct {
unsigned char control;
unsigned char mode;
unsigned long loc;
} ATTRPACK PositionRequest;
#pragma pack()
#ifdef __cplusplus
extern "C" {
#endif
const char *bcd_error(void) {
static char retstr[132];
const char *errorcodes[] = {
"Write-protect violation",
"Unknown unit",
"Drive not ready",
"Unknown command",
"CRC error",
"Bad drive request structure length",
"Seek error",
"Unknown media",
"Sector not found",
"Printer out of paper: world coming to an end",/* I mean really, on a CD? */
"Write fault",
"Read fault",
"General failure",
"Reserved",
"Reserved",
"Invalid disk change"
};
*retstr = 0;
if (_error != 0) {
strcat(retstr, "Device error: ");
if (_error_code < 0 || _error_code > 0xf)
strcat(retstr, "Invalid error");
else
strcat(retstr, errorcodes[_error_code]);
strcat(retstr, " ");
}
if (_bcd_error != NULL) {
if (*retstr) strcat(retstr, ", ");
strcat(retstr, "BCD error: ");
strcat(retstr, _bcd_error);
}
return retstr;
}
/* DOS IOCTL w/ command block */
static void bcd_ioctl(IOCTLI *ioctli, void *command, int len) {
int ioctli_len = sizeof (IOCTLI);
unsigned long command_address = dos_mem_segment << 4;
__dpmi_regs regs;
memset(&regs, 0, sizeof regs);
regs.x.es = (__tb >> 4) & 0xffff;
regs.x.ax = 0x1510;
regs.x.bx = __tb & 0xf;
regs.x.cx = first_drive;
ioctli->address = dos_mem_segment << 16;
ioctli->len = len;
dosmemput(ioctli, ioctli_len, __tb); /* put ioctl into dos area */
dosmemput(command, len, command_address); /* and command too */
if (__dpmi_int(0x2f, &regs) == -1) {
_bcd_error = "__dpmi_int() failed";
return;
}
dosmemget(__tb, ioctli_len, ioctli); /* retrieve results */
dosmemget(command_address, len, command);
_status = ioctli->request_header.status;
if (_status & ERROR_BIT) {
_error = TRUE;
_error_code = _status & 0xff;
} else {
_error = FALSE;
_error_code = 0;
}
}
/* no command block */
FUNCINLINE static ATTRINLINE void bcd_ioctl2(void *cmd, int len) {
__dpmi_regs regs;
memset(&regs, 0, sizeof regs);
regs.x.es = (__tb >> 4) & 0xffff;
regs.x.ax = 0x1510;
regs.x.bx = __tb & 0xf;
regs.x.cx = first_drive;
dosmemput(cmd, len, __tb); /* put ioctl block in dos arena */
if (__dpmi_int(0x2f, &regs) == -1) {
_bcd_error = "__dpmi_int() failed";
return;
}
/* I hate to have no error capability for ioctl2 but the command block
doesn't necessarily have a status field */
RESET_ERROR;
}
FUNCINLINE static ATTRINLINE int red2hsg(char *r) {
return r[0] + r[1]*75 + r[2]*4500 - 150;
}
int bcd_now_playing(void) {
int i, loc = bcd_audio_position();
_bcd_error = NULL;
if (!bcd_audio_busy()) {
_bcd_error = "Audio not playing";
return 0;
}
if (
#ifndef STATIC_TRACKS
tracks == NULL &&
#endif
!bcd_get_audio_info())
return 0;
for (i = lowest_track; i <= highest_track; i++) {
if (loc >= tracks[i].start && loc <= tracks[i].end) return i;
}
/* some bizarre location? */
_bcd_error = "Head outside of bounds";
return 0;
}
/* handles the setup for CD-ROM audio interface */
int bcd_open(void) {
__dpmi_regs regs;
_bcd_error = NULL;
/* disk I/O wouldn't work anyway if you set sizeof tb this low, but... */
if (_go32_info_block.size_of_transfer_buffer < 4096) {
_bcd_error = "Transfer buffer too small";
return 0;
}
memset(&regs, 0, sizeof regs);
regs.x.ax = 0x1500;
regs.x.bx = 0x0;
__dpmi_int(0x2f, &regs);
if (regs.x.bx == 0) { /* abba no longer lives */
_bcd_error = "MSCDEX not found";
return 0;
}
first_drive = regs.x.cx; /* use the first drive */
/* check for mscdex at least 2.0 */
memset(&regs, 0, sizeof regs);
regs.x.ax = 0x150C;
__dpmi_int(0x2f, &regs);
if (regs.x.bx == 0) {
_bcd_error = "MSCDEX version < 2.0";
return 0;
}
mscdex_version = regs.x.bx;
/* allocate 256 bytes of dos memory for the command blocks */
if ((dos_mem_segment = __dpmi_allocate_dos_memory(16, &dos_mem_selector))<0) {
_bcd_error = "Could not allocate 256 bytes of DOS memory";
return 0;
}
return mscdex_version;
}
/* Shuts down CD-ROM audio interface */
int bcd_close(void) {
_bcd_error = NULL;
if (dos_mem_selector != -1) {
__dpmi_free_dos_memory(dos_mem_selector);
dos_mem_selector = -1;
}
#ifndef STATIC_TRACKS
if (tracks) free(tracks);
tracks = NULL;
#endif
RESET_ERROR;
return 1;
}
int bcd_open_door(void) {
IOCTLI ioctli;
char eject = 0;
_bcd_error = NULL;
memset(&ioctli, 0, sizeof ioctli);
ioctli.request_header.len = sizeof ioctli;
ioctli.request_header.command = 12;
ioctli.len = 1;
bcd_ioctl(&ioctli, &eject, sizeof eject);
if (_error) return 0;
return 1;
}
int bcd_close_door(void) {
IOCTLI ioctli;
char closeit = 5;
_bcd_error = NULL;
memset(&ioctli, 0, sizeof ioctli);
ioctli.request_header.len = sizeof ioctli;
ioctli.request_header.command = 12;
ioctli.len = 1;
bcd_ioctl(&ioctli, &closeit, sizeof closeit);
if (_error) return 0;
return 1;
}
int bcd_lock(int fn) {
IOCTLI ioctli;
LockRequest req;
_bcd_error = NULL;
memset(&ioctli, 0, sizeof ioctli);
memset(&req, 0, sizeof req);
ioctli.request_header.len = sizeof ioctli;
ioctli.request_header.command = 12;
ioctli.len = sizeof req;
req.control = 1;
req.fn = fn ? 1 : 0;
bcd_ioctl(&ioctli, &req, sizeof req);
if (_error) return 0;
return 1;
}
int bcd_disc_changed(void) {
IOCTLI ioctli;
MediaChangedRequest req;
_bcd_error = NULL;
memset(&ioctli, 0, sizeof ioctli);
memset(&req, 0, sizeof req);
ioctli.request_header.len = sizeof ioctli;
ioctli.request_header.command = 3;
ioctli.len = sizeof req;
req.control = 9;
bcd_ioctl(&ioctli, &req, sizeof req);
return req.mbyte;
}
int bcd_reset(void) {
IOCTLI ioctli;
char reset = 2;
_bcd_error = NULL;
memset(&ioctli, 0, sizeof ioctli);
ioctli.request_header.len = sizeof ioctli;
ioctli.request_header.command = 12;
ioctli.len = 1;
bcd_ioctl(&ioctli, &reset, sizeof reset);
if (_error) return 0;
return 1;
}
int bcd_device_status(void) {
IOCTLI ioctli;
StatusRequest req;
_bcd_error = NULL;
memset(&ioctli, 0, sizeof ioctli);
memset(&req, 0, sizeof req);
ioctli.request_header.len = sizeof ioctli; // ok
ioctli.request_header.command = 3;
ioctli.len = sizeof req;
req.control = 6;
bcd_ioctl(&ioctli, &req, sizeof req);
return req.status;
}
static inline int bcd_get_status_word(void) {
IOCTLI ioctli;
DiskInfo disk_info;
/* get cd info as an excuse to get a look at the status word */
memset(&disk_info, 0, sizeof disk_info);
memset(&ioctli, 0, sizeof ioctli);
ioctli.request_header.len = 26;
ioctli.request_header.command = 3;
ioctli.len = 7;
disk_info.control = 10;
bcd_ioctl(&ioctli, &disk_info, sizeof disk_info);
return _status;
}
int bcd_audio_busy(void) {
_bcd_error = NULL;
/* If the door is open, then the head is busy, and so the busy bit is
on. It is not, however, playing audio. */
if (bcd_device_status() & BCD_DOOR_OPEN)
return 0;
bcd_get_status_word();
if (_error) return -1;
return (_status & BUSY_BIT) ? 1 : 0;
}
int bcd_audio_position(void) {
IOCTLI ioctli;
PositionRequest req;
_bcd_error = NULL;
memset(&ioctli, 0, sizeof ioctli);
memset(&req, 0, sizeof req);
ioctli.request_header.len = sizeof ioctli;
ioctli.request_header.command = 3;
ioctli.len = sizeof req;
req.control = 1;
bcd_ioctl(&ioctli, &req, sizeof req);
return req.loc;
}
/* Internal function to get track info */
static inline void bcd_get_track_info(int n, Track *t) {
IOCTLI ioctli;
TrackInfo info;
memset(&ioctli, 0, sizeof ioctli);
memset(&info, 0, sizeof info);
ioctli.request_header.len = sizeof ioctli;
ioctli.request_header.command = 3;
info.control = 11;
info.track_number = n;
bcd_ioctl(&ioctli, &info, sizeof info);
t->start = red2hsg(info.start);
if (info.info & 64)
t->is_audio = 0;
else
t->is_audio = 1;
}
int bcd_get_audio_info(void) {
IOCTLI ioctli;
DiskInfo disk_info;
int i;
_bcd_error = NULL;
#ifndef STATIC_TRACKS
if (tracks) free(tracks);
tracks = NULL;
#endif
memset(&disk_info, 0, sizeof disk_info);
memset(&ioctli, 0, sizeof ioctli);
ioctli.request_header.len = 26;
ioctli.request_header.command = 3;
ioctli.len = 7;
disk_info.control = 10;
bcd_ioctl(&ioctli, &disk_info, sizeof disk_info);
if (_error) return 0;
lowest_track = disk_info.lowest;
highest_track = disk_info.highest;
num_tracks = disk_info.highest - disk_info.lowest + 1;
#ifndef STATIC_TRACKS
//tracks = calloc(num_tracks, sizeof (Track));
/* alloc max space in order to attempt to avoid possible overrun bug */
tracks = calloc(highest_track+1, sizeof (Track));
if (tracks == NULL) {
_bcd_error = "Out of memory allocating tracks\n";
return 0;
}
#endif
/* get track starts */
for (i = lowest_track; i <= highest_track; i++)
bcd_get_track_info(i, tracks+i);
/* figure out track ends */
for (i = lowest_track; i < highest_track; i++)
tracks[i].end = tracks[i+1].start-1;
audio_length = red2hsg(disk_info.total);
tracks[i].end = audio_length;
for (i = lowest_track; i <= highest_track; i++)
tracks[i].len = tracks[i].end - tracks[i].start;
return num_tracks;
}
int bcd_get_track_address(int trackno, int *start, int *len) {
_bcd_error = NULL;
//if (trackno >= num_tracks+1 || trackno <= 0) {
if (trackno < lowest_track || trackno > highest_track) {
_bcd_error = "Track out of range";
*start = *len = 0;
return 0;
}
*start = tracks[trackno].start;
*len = tracks[trackno].len;
return 1;
}
int bcd_track_is_audio(int trackno) {
//if (trackno >= num_tracks+1 || trackno <= 0) {
if (trackno < lowest_track || trackno > highest_track) {
_bcd_error = "Track out of range";
return 0;
}
return tracks[trackno].is_audio;
}
int bcd_set_volume(int volume) {
IOCTLI ioctli;
VolumeRequest v;
_bcd_error = NULL;
if (volume > 255) volume = 255;
else if (volume < 0) volume = 0;
memset(&ioctli, 0, sizeof ioctli);
ioctli.request_header.len = sizeof ioctli;
ioctli.request_header.command = 12;
ioctli.len = sizeof v;
v.control = 3;
v.volume0 = volume;
v.input0 = 0;
v.volume1 = volume;
v.input1 = 1;
v.volume2 = volume;
v.input2 = 2;
v.volume3 = volume;
v.input3 = 3;
bcd_ioctl(&ioctli, &v, sizeof v);
if (_error) return 0;
return 1;
}
int bcd_play(int location, int frames) {
PlayRequest cmd;
memset(&cmd, 0, sizeof cmd);
_bcd_error = NULL;
/* the following should be in user code, but it'll fail otherwise */
if (bcd_audio_busy())
bcd_stop();
cmd.request.len = sizeof cmd;
cmd.request.command = 132;
cmd.start = location;
cmd.len = frames;
bcd_ioctl2(&cmd, sizeof cmd);
if (_error) return 0;
return 1;
}
int bcd_play_track(int trackno) {
_bcd_error = NULL;
if (!bcd_get_audio_info()) return 0;
if (trackno < lowest_track || trackno > highest_track) {
_bcd_error = "Track out of range";
return 0;
}
if (! tracks[trackno].is_audio) {
_bcd_error = "Not an audio track";
return 0;
}
return bcd_play(tracks[trackno].start, tracks[trackno].len);
}
int bcd_stop(void) {
StopRequest cmd;
_bcd_error = NULL;
memset(&cmd, 0, sizeof cmd);
cmd.request.len = sizeof cmd;
cmd.request.command = 133;
bcd_ioctl2(&cmd, sizeof cmd);
if (_error) return 0;
return 1;
}
int bcd_resume(void) {
ResumeRequest cmd;
_bcd_error = NULL;
memset(&cmd, 0, sizeof cmd);
cmd.request.len = sizeof cmd;
cmd.request.command = 136;
bcd_ioctl2(&cmd, sizeof cmd);
if (_error) return 0;
return 1;
}
#ifdef __cplusplus
}
#endif
#ifdef STANDALONE
static char *card(int c) {
return c == 1 ? "" : "s";
}
static void print_hsg(int hsg) {
int hours, minutes, seconds;
seconds = hsg / 75;
minutes = seconds / 60;
seconds %= 60;
hours = minutes / 60;
minutes %= 60;
printf("%2d:%02d:%02d", hours, minutes, seconds);
}
static void print_binary(int v, int len) {
for (;len;len--)
printf("%d", (v & (1 << len)) ? 1 : 0);
}
int main(int argc, char *argv[]) {
int i, n1, n2, t;
if (!bcd_open()) {
fprintf(stderr, "Couldn't open CD-ROM drive. %s\n", bcd_error());
exit(0);
}
for (i = 1; i < argc; i++) {
if (*argv[i] == '-') strcpy(argv[i], argv[i]+1);
if (!strcmp(argv[i], "open") || !strcmp(argv[i], "eject")) {
bcd_open_door();
} else if (!strcmp(argv[i], "close")) {
bcd_close_door();
} else if (!strcmp(argv[i], "sleep")) {
if (++i >= argc) break;
sleep(atoi(argv[i]));
} else if (!strcmp(argv[i], "list")) {
int nd = 0, na = 0, audio_time = 0;
if (!bcd_get_audio_info()) {
printf("Error getting audio info\n");
} else if (lowest_track == 0) {
printf("No audio tracks\n");
} else {
for (t = lowest_track; t <= highest_track; t++) {
printf("Track %2d: ", t);
print_hsg(tracks[t].start);
printf(" -> ");
print_hsg(tracks[t].end);
printf(" (");
print_hsg(tracks[t].len);
if (tracks[t].is_audio) {
na++;
printf(") audio");
audio_time += tracks[t].len;
} else {
nd++;
printf(") data ");
}
printf(" (HSG: %06d->%06d)\n", tracks[t].start, tracks[t].end);
}
printf("%d audio track%s, %d data track%s\n", na, card(na), nd, card(nd));
if (audio_time) {
printf("Audio time: ");
print_hsg(audio_time);
printf("\n");
}
}
} else if (!strcmp(argv[i], "lock")) {
bcd_lock(1);
} else if (!strcmp(argv[i], "pladdr")) {
if (++i >= argc) break;
n1 = atoi(argv[i]);
if (++i >= argc) break;
n2 = atoi(argv[i]);
printf("Playing frame %d to frame %d\n", n1, n2);
bcd_play(n1, n2-n1);
} else if (!strcmp(argv[i], "play")) {
if (++i >= argc) break;
if (bcd_audio_busy()) {
bcd_stop();
delay(1000);
}
n1 = atoi(argv[i]);
printf("Playing track %d\n", n1);
bcd_play_track(n1);
} else if (!strcmp(argv[i], "reset")) {
bcd_reset();
} else if (!strcmp(argv[i], "resume")) {
bcd_resume();
} else if (!strcmp(argv[i], "status")) {
int s;
s = bcd_device_status();
printf("MSCDEX version %d.%d\n", mscdex_version >> 8,
mscdex_version & 0xff);
printf("Device status word '");
print_binary(s, 16);
printf("'\nDoor is %sopen\n", s & BCD_DOOR_OPEN ? "" : "not ");
printf("Door is %slocked\n", s & BCD_DOOR_UNLOCKED ? "not " : "");
printf("Audio is %sbusy\n", bcd_audio_busy() ? "" : "not ");
s = bcd_disc_changed();
if (s == BCD_DISC_UNKNOWN) printf("Media change status unknown\n");
else printf("Media has %schanged\n",
(s == BCD_DISC_CHANGED) ? "" : "not ");
} else if (!strcmp(argv[i], "stop")) {
bcd_stop();
} else if (!strcmp(argv[i], "unlock")) {
bcd_lock(0);
} else if (!strcmp(argv[i], "volume")) {
bcd_set_volume(atoi(argv[++i]));
} else if (!strcmp(argv[i], "wait")) {
while (bcd_audio_busy()) {
int n = bcd_now_playing();
if (n == 0) break;
printf("%2d: ", n);
print_hsg(bcd_audio_position() - tracks[n].start);
printf("\r");
fflush(stdout);
delay(100);
if (kbhit() && getch() == 27) break;
}
printf("\n");
} else if (!strcmp(argv[i], "help") || !strcmp(argv[i], "usage")) {
printf("BCD version %x.%x\n" \
"Usage: BCD {commands}\n" \
"Valid commands:\n" \
"\tclose - close door/tray\n" \
"\tdelay {n} - delay {n} seconds\n" \
"\tlist - list track info\n" \
"\tlock - lock door/tray\n" \
"\topen - open door/tray\n" \
"\tpladdr {n1} {n2}- play frame {n1} to {n2}\n" \
"\tplay {n} - play track {n}\n" \
"\treset - reset the drive\n" \
"\tresume - resume from last stop\n" \
"\tstatus - show drive status\n" \
"\tstop - stop audio playback\n" \
"\tunlock - unlock door/tray\n" \
"\tvolume {n} - set volume to {n} where 0 <= {n} <= 255\n",
BCD_VERSION >> 8, BCD_VERSION & 0xff);
} else
printf("Unknown command '%s'\n", argv[i]);
if (_error || _bcd_error) printf("%s\n", bcd_error());
}
bcd_close();
exit(0);
}
#endif

View file

@ -1,90 +0,0 @@
/* bcd.h -- header file for BCD, a CD-ROM audio playing library for DJGPP
by Brennan Underwood, http://brennan.home.ml.org/ */
#ifndef _BCD_H
#define _BCD_H
#define BCD_VERSION 0x0103
/* Installation and setup functions */
/* Call this first! */
int bcd_open(void);
/* Call before exit. */
int bcd_close(void);
/* open door, unlocking first if necessary */
int bcd_open_door(void);
/* close door */
int bcd_close_door(void);
/* pass 1 to lock door, 0 to unlock */
int bcd_lock(int);
/* returns one of the following 3 #defined symbols */
int bcd_disc_changed(void);
#define BCD_DISC_CHANGED 0xff
#define BCD_DISC_NOT_CHANGED 1
#define BCD_DISC_UNKNOWN 0
/* perform a device reset */
int bcd_reset(void);
/* compare the returned status int to the following bits */
int bcd_device_status(void);
#define BCD_DOOR_OPEN 1
#define BCD_DOOR_UNLOCKED 2
#define BCD_SUPPORT_COOKED 4
#define BCD_READ_ONLY 8
#define BCD_DATA_READ_ONLY 16
#define BCD_SUPPORT_INTERLEAVE 32
/* returns 1 if audio is currently playing, 0 otherwise. -1 on error */
int bcd_audio_busy(void);
/* current head position in frames */
int bcd_audio_position(void);
/* convenience function, if audio busy, returns track# playing now */
int bcd_now_playing(void);
/* query MSCDEX for track list when disc changed or just starting up */
int bcd_get_audio_info(void);
/* get a particular track's info */
int bcd_get_track_address(int trackno, int *start, int *len);
/* check for track's audio/data status */
int bcd_track_is_audio(int trackno);
/* play a particular track from beginning to end */
int bcd_play_track(int tracknum);
/* play an arbitrary section of audio for an arbitrary length of time */
int bcd_play(int start, int len);
/* set the output volume. pass a parameter from 0-255 */
int bcd_set_volume(int);
/* stop and pause are equivalent */
int bcd_stop(void);
#define bcd_pause bcd_stop
int bcd_resume(void);
/* Troubleshooting */
/* Returns a human readable description of the last error encountered */
const char *bcd_error(void);
extern int _error_code;
/* If you are mad enough play the Rach 3, I mean parse _error_code yourself */
#define BCD_DE_WRITE_PROTECT 0
#define BCD_DE_UNKNOWN_UNIT 1
#define BCD_DE_DRIVE_NOT_READY 2
#define BCD_DE_UNKNOWN_COMMAND 3
#define BCD_DE_CRC_ERROR 4
#define BCD_DE_STRUCT_LEN 5
#define BCD_DE_SEEK_ERROR 6
#define BCD_DE_UNKNOWN_MEDIA 7
#define BCD_DE_SECTOR_NOT_FOUND 8
#define BCD_DE_OUT_OF_PAPER 9
#define BCD_DE_WRITE_FAULT 10
#define BCD_DE_READ_FAULT 11
#define BCD_DE_GENERAL_FAILURE 12
#define BCD_DE_INVALID_DISK_CHANGE 15
/* set by BCD itself, for stuff like "Out of memory" */
extern const char *_bcd_error;
/* uncomment this line to force BCD to use a statically allocated
Track array instead of using malloc */
#define STATIC_TRACKS
#endif

View file

@ -1,445 +0,0 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// Copyright (C) 1998-2000 by DooM Legacy Team.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//-----------------------------------------------------------------------------
/// \file
/// \brief cd music interface (uses bcd library)
// Alam_GBC: I hate you, Brennan Underwood :)
#include "../doomtype.h"
#include "bcd.c"
//#include "bcd.h" // CD-Audio library by Brennan Underwood
#include "../doomdef.h"
#include "../i_sound.h"
#include "../command.h"
#include "../i_system.h"
#include "../s_sound.h"
// ------
// protos
// ------
static void Command_Cd_f (void);
//======================================================================
// CD AUDIO MUSIC SUBSYSTEM
//======================================================================
UINT8 cdaudio_started=0; // for system startup/shutdown
#define MAX_CD_TRACKS 256
static boolean cdPlaying = false;
static int cdPlayTrack; // when cdPlaying is true
static boolean cdLooping = false;
static UINT8 cdRemap[MAX_CD_TRACKS];
static boolean cdEnabled=true; // cd info available
static boolean cdValid; // true when last cd audio info was ok
static boolean wasPlaying;
static int cdVolume=0; // current cd volume (0-31)
// 0-31 like Music & Sfx, though CD hardware volume is 0-255.
consvar_t cd_volume = {"cd_volume","18",CV_SAVE,soundvolume_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
// allow Update for next/loop track
// some crap cd drivers take up to
// a second for a simple 'busy' check..
// (on those Update can be disabled)
consvar_t cdUpdate = {"cd_update","1",CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
// hour,minutes,seconds
FUNCINLINE static ATTRINLINE char *hms(int hsg)
{
int hours, minutes, seconds;
static char s[9];
seconds = hsg / 75;
minutes = seconds / 60;
seconds %= 60;
hours = minutes / 60;
minutes %= 60;
if (hours>0)
sprintf (s, "%d:%02d:%02d", hours, minutes, seconds);
else
sprintf (s, "%2d:%02d", minutes, seconds);
return s;
}
static void Command_Cd_f (void)
{
const char * s;
int i,j;
if (!cdaudio_started)
return;
if (COM_Argc()<2)
{
CONS_Printf ("cd [on] [off] [remap] [reset] [open]\n"
" [info] [play <track>] [loop <track>]\n"
" [stop] [resume]\n");
return;
}
s = COM_Argv(1);
// activate cd music
if (!strncmp(s,"on",2))
{
cdEnabled = true;
return;
}
// stop/deactivate cd music
if (!strncmp(s,"off",3))
{
if (cdPlaying)
I_StopCD ();
cdEnabled = false;
return;
}
// remap tracks
if (!strncmp(s,"remap",5))
{
i = COM_Argc() - 2;
if (i <= 0)
{
CONS_Printf ("CD tracks remapped in that order :\n");
for (j = 1; j < MAX_CD_TRACKS; j++)
if (cdRemap[j] != j)
CONS_Printf (" %2d -> %2d\n", j, cdRemap[j]);
return;
}
for (j = 1; j <= i; j++)
cdRemap[j] = atoi (COM_Argv (j+1));
return;
}
// reset the CD driver, useful on some odd cd's
if (!strncmp(s,"reset",5))
{
cdEnabled = true;
if (cdPlaying)
I_StopCD ();
for (i = 0; i < MAX_CD_TRACKS; i++)
cdRemap[i] = i;
bcd_reset ();
cdValid = bcd_get_audio_info ();
return;
}
// any other command is not allowed until we could retrieve cd information
if (!cdValid)
{
CONS_Printf ("CD is not ready.\n");
return;
}
if (!strncmp(s,"open",4))
{
if (cdPlaying)
I_StopCD ();
bcd_open_door();
cdValid = false;
return;
}
if (!strncmp(s,"info",4))
{
int totaltime = 0;
if (!bcd_get_audio_info())
{
CONS_Printf ("Error getting audio info: %s\n",bcd_error());
cdValid = false;
return;
}
cdValid = true;
if (lowest_track == 0)
CONS_Printf ("No audio tracks\n");
else
{
// display list of tracks
// highlight current playing track
for (i=lowest_track; i <= highest_track; i++)
{
CONS_Printf ("%s%2d. %s %s\n",
cdPlaying && (cdPlayTrack == i) ? "\2 " : " ",
i, tracks[i].is_audio ? "audio" : "data ",
hms(tracks[i].len));
if (tracks[i].is_audio)
totaltime += tracks[i].len;
}
if (totaltime)
CONS_Printf ("\2Total time : %s\n", hms(totaltime));
}
if (cdPlaying)
{
CONS_Printf ("%s track : %d\n", cdLooping ? "looping" : "playing",
cdPlayTrack);
}
return;
}
if (!strncmp(s,"play",4))
{
I_PlayCD ((UINT8)atoi (COM_Argv (2)), false);
return;
}
if (!strncmp(s,"stop",4))
{
I_StopCD ();
return;
}
if (!strncmp(s,"loop",4))
{
I_PlayCD ((UINT8)atoi (COM_Argv (2)), true);
return;
}
if (!strncmp(s,"resume",4))
{
I_ResumeCD ();
return;
}
CONS_Printf ("cd command '%s' unknown\n", s);
}
// pause cd music
void I_StopCD (void)
{
if (!cdaudio_started || !cdEnabled)
return;
bcd_stop();
wasPlaying = cdPlaying;
cdPlaying = false;
}
// continue after a pause
void I_ResumeCD (void)
{
if (!cdaudio_started || !cdEnabled)
return;
if (!cdValid)
return;
if (!wasPlaying)
return;
bcd_resume ();
cdPlaying = true;
}
void I_ShutdownCD (void)
{
int rc;
if (!cdaudio_started)
return;
I_StopCD ();
rc = bcd_close ();
if (!rc)
CONS_Printf ("Error shuting down cd\n");
}
void I_InitCD (void)
{
int rc;
int i;
rc = bcd_open ();
if (rc>=0x200)
{
CONS_Printf ("MSCDEX version %d.%d\n", rc>>8, rc&255);
I_AddExitFunc (I_ShutdownCD);
cdaudio_started = true;
}
else
{
if (!rc)
CONS_Printf ("%s\n", bcd_error() );
cdaudio_started = false;
return;
}
// last saved in config.cfg
i = cd_volume.value;
I_SetVolumeCD (0); // initialize to 0 for some odd cd drivers
I_SetVolumeCD (i); // now set the last saved volume
for (i = 0; i < MAX_CD_TRACKS; i++)
cdRemap[i] = i;
if (!bcd_get_audio_info())
{
CONS_Printf("\2CD Init: No CD in player.\n");
cdEnabled = false;
cdValid = false;
}
else
{
cdEnabled = true;
cdValid = true;
}
COM_AddCommand ("cd", Command_Cd_f);
}
// loop/go to next track when track is finished (if cd_update var is true)
// update the volume when it has changed (from console/menu)
/// \todo check for cd change and restart music ?
void I_UpdateCD (void)
{
int newVolume;
int now;
static int last; //game tics (35th of second)
if (!cdaudio_started)
return;
now = I_GetTime ();
if ((now - last) < 10) // about 1/4 second
return;
last = now;
// update cd volume changed at console/menu
newVolume = cd_volume.value & 31;
if (cdVolume != newVolume)
I_SetVolumeCD (newVolume);
// slow drivers exit here
if (!cdUpdate.value)
return;
if (cdPlaying)
{
if (!bcd_audio_busy())
{
cdPlaying = false;
if (cdLooping)
I_PlayCD (cdPlayTrack, true);
else
{
// play the next cd track, or restart the first
cdPlayTrack++;
if (cdPlayTrack > highest_track)
cdPlayTrack = lowest_track;
while (!tracks[cdPlayTrack].is_audio && cdPlayTrack<highest_track)
cdPlayTrack++;
I_PlayCD (cdPlayTrack, true);
}
}
}
}
//
void I_PlayCD (UINT8 track, UINT8 looping)
{
if (!cdaudio_started || !cdEnabled)
return;
if (!cdValid)
return;
track = cdRemap[track];
if (cdPlaying)
{
if (cdPlayTrack == track)
return;
I_StopCD ();
}
if (track < lowest_track || track > highest_track)
{
//CONS_Printf ("\2CD Audio: wrong track number %d\n", track);
// suppose there are not enough tracks for game levels..
// then do a modulo so we always get something to hear
track = (track % (highest_track-lowest_track+1)) + 1;
//return;
}
cdPlayTrack = track;
if (!tracks[track].is_audio)
{
CONS_Printf ("\2CD Play: not an audio track\n");
return;
}
cdLooping = looping;
if (!bcd_play_track (track))
{
CONS_Printf ("CD Play: could not play track %d\n", track);
cdValid = false;
cdPlaying = false;
return;
}
cdPlaying = true;
}
// volume : logical cd audio volume 0-31 (hardware is 0-255)
boolean I_SetVolumeCD (INT32 volume)
{
int hardvol;
if (!cdaudio_started || !cdEnabled)
return false;
// translate to hardware volume
volume &= 31;
hardvol = ((volume+1)<<3)-1; //highest volume is 255
if (hardvol<=8)
hardvol=0; //lowest volume is ZERO
cdVolume = volume;
if (bcd_set_volume (hardvol))
{
CV_SetValue (&cd_volume, volume);
return true;
}
else
return false;
}

View file

@ -1,78 +0,0 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 1998-2000 by DooM Legacy Team.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//-----------------------------------------------------------------------------
/// \file
/// \brief Main program, simply calls D_SRB2Main high level loop.
#include "../doomdef.h"
#include "../m_argv.h"
#include "../d_main.h"
#include "../i_system.h"
#ifdef REMOTE_DEBUGGING
#include <i386-stub.h>
#include "rdb.h"
#endif
//### let's try with Allegro ###
#define alleg_mouse_unused
#define alleg_timer_unused
#define ALLEGRO_NO_KEY_DEFINES
#define alleg_keyboard_unused
#define alleg_joystick_unused
#define alleg_gfx_driver_unused
#define alleg_palette_unused
#define alleg_graphics_unused
#define alleg_vidmem_unused
#define alleg_flic_unused
#define alleg_sound_unused
#define alleg_file_unused
#define alleg_datafile_unused
#define alleg_math_unused
#define alleg_gui_unused
#include <allegro.h>
//### end of Allegro include ###
int main (int argc, char **argv)
{
myargc = argc;
myargv = argv;
{
//added:03-01-98:
// Setup signal handlers and other stuff BEFORE ANYTHING ELSE!
I_StartupSystem();
#ifdef REMOTE_DEBUGGING
/* Only setup if remote debugging is to be done, Muhahahaha!*/
gdb_serial_init(DEBUG_COM_PORT,DEBUG_COM_PORT_SPEED);
gdb_target_init();
breakpoint();
#endif
D_SRB2Main();
D_SRB2Loop();
}
//added:03-01-98:
// hmmm... it will never go here.
return 0;
}
#if ALLEGRO_VERSION == 4
END_OF_MAIN()
#endif

View file

@ -1,113 +0,0 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// Copyright (C) 1993-1996 by id Software, Inc.
// Portions Copyright (C) 1998-2000 by DooM Legacy Team.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//-----------------------------------------------------------------------------
/// \file
/// \brief doomcom network interface
#include <netinet/in.h>
#include <errno.h>
#include <unistd.h>
#include <go32.h>
#include <pc.h>
#include <dpmi.h>
#include <dos.h>
#include <sys/nearptr.h>
#include "../doomdef.h"
#include "../i_system.h"
#include "../d_event.h"
#include "../d_net.h"
#include "../m_argv.h"
#include "../doomstat.h"
#include "../z_zone.h"
#include "../i_net.h"
#include "../i_tcp.h"
//
// NETWORKING
//
typedef enum
{
CMD_SEND = 1,
CMD_GET = 2,
} command_t;
static void External_Driver_Get(void);
static void External_Driver_Send(void);
static void External_Driver_FreeNode(INT32 nodenum);
static inline boolean External_Driver_OpenSocket(void)
{
I_NetGet = External_Driver_Get;
I_NetSend = External_Driver_Send;
I_NetCloseSocket = NULL;
I_NetFreeNodenum = External_Driver_FreeNode;
return true;
}
//
// I_InitNetwork
//
boolean I_InitNetwork (void)
{
int netgamepar;
netgamepar = M_CheckParm ("-net");
if (!netgamepar)
return false;
// externals drivers specific
__djgpp_nearptr_enable();
// set up for network
doomcom=(doomcom_t *)(__djgpp_conventional_base+atoi(myargv[netgamepar+1]));
CONS_Printf("I_DosNet : Using int 0x%x for communication\n",doomcom->intnum);
server = (doomcom->consoleplayer == 0);
if (!server)
COM_BufAddText("connect any\n");
// ipx + time + 4 (padding)
packetheaderlength=30+4+4;
hardware_MAXPACKETLENGTH = 512;
I_NetOpenSocket = External_Driver_OpenSocket;
return true;
}
FUNCNORETURN static ATTRNORETURN void External_Driver_Get(void)
{
I_Error("External_Driver_Get not supported at this time");
}
FUNCNORETURN static ATTRNORETURN void External_Driver_Send(void)
{
I_Error("External_Driver_Send not supported at this time");
}
FUNCNORETURN static ATTRNORETURN void External_Driver_FreeNode(INT32 nodenum)
{
nodenum = 0;
I_Error("External_Driver_FreeNode not supported at this time");
}

View file

@ -1,620 +0,0 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// Copyright (C) 1993-1996 by id Software, Inc.
// Portions Copyright (C) 1998-2000 by DooM Legacy Team.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//-----------------------------------------------------------------------------
/// \file
/// \brief interface level code for sound
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <math.h>
#include "../doomdef.h"
#include "../doomstat.h"
#include "../i_system.h"
#include "../i_sound.h"
#include "../z_zone.h"
#include "../m_argv.h"
#include "../m_misc.h"
#include "../w_wad.h"
#include "../s_sound.h"
#include "../console.h"
//### let's try with Allegro ###
#define alleg_mouse_unused
#define alleg_timer_unused
#define ALLEGRO_NO_KEY_DEFINES
#define alleg_keyboard_unused
#define alleg_joystick_unused
#define alleg_gfx_driver_unused
#define alleg_palette_unused
#define alleg_graphics_unused
#define alleg_vidmem_unused
#define alleg_flic_unused
//#define alleg_sound_unused we use it
#define alleg_file_unused
#define alleg_datafile_unused
#define alleg_math_unused
#define alleg_gui_unused
#include <allegro.h>
//### end of Allegro include ###
//allegro has 256 virtual voices
// warning should by a power of 2
#define VIRTUAL_VOICES 256
#define VOICESSHIFT 8
// Needed for calling the actual sound output.
#define SAMPLECOUNT 512
//
// this function converts raw 11khz, 8-bit data to a SAMPLE* that allegro uses
// it is need cuz allegro only loads samples from wavs and vocs
//added:11-01-98: now reads the frequency from the rawdata header.
// dsdata points a 4 UINT16 header:
// +0 : value 3 what does it mean?
// +2 : sample rate, either 11025 or 22050.
// +4 : number of samples, each sample is a single byte since it's 8bit
// +6 : value 0
static inline SAMPLE *raw2SAMPLE(UINT8 *dsdata, size_t len)
{
SAMPLE *spl;
spl=Z_Malloc(sizeof (SAMPLE),PU_SOUND,NULL);
if (spl==NULL)
I_Error("Raw2Sample : no more free mem");
spl->bits = 8;
spl->stereo = 0;
spl->freq = *((UINT16 *)dsdata+1); //mostly 11025, but some at 22050.
spl->len = len-8;
spl->priority = 255; //priority;
spl->loop_start = 0;
spl->loop_end = len-8;
spl->param = -1;
spl->data=(void *)(dsdata+8); //skip the 8bytes header
return spl;
}
// This function loads the sound data from the WAD lump,
// for single sound.
//
void *I_GetSfx (sfxinfo_t * sfx)
{
UINT8 *dssfx;
if (sfx->lumpnum == LUMPERROR)
sfx->lumpnum = S_GetSfxLumpNum (sfx);
sfx->length = W_LumpLength (sfx->lumpnum);
dssfx = (UINT8 *) W_CacheLumpNum (sfx->lumpnum, PU_SOUND);
//_go32_dpmi_lock_data(dssfx,size);
// convert raw data and header from Doom sfx to a SAMPLE for Allegro
return (void *)raw2SAMPLE (dssfx, sfx->length);
}
void I_FreeSfx (sfxinfo_t *sfx)
{
if (sfx->lumpnum == LUMPERROR)
return;
// free sample data
if ( sfx->data )
Z_Free((UINT8 *) ((SAMPLE *)sfx->data)->data - 8);
Z_Free(sfx->data); // Allegro SAMPLE structure
sfx->data = NULL;
sfx->lumpnum = LUMPERROR;
}
FUNCINLINE static ATTRINLINE int Volset(int vol)
{
return (vol*255/31);
}
void I_SetSfxVolume(INT32 volume)
{
if (sound_disabled)
return;
set_volume (Volset(volume),-1);
}
//
// Starting a sound means adding it
// to the current list of active sounds
// in the internal channels.
// As the SFX info struct contains
// e.g. a pointer to the raw data,
// it is ignored.
// As our sound handling does not handle
// priority, it is ignored.
// Pitching (that is, increased speed of playback)
// is set, but currently not used by mixing.
//
INT32 I_StartSound ( sfxenum_t id,
INT32 vol,
INT32 sep,
INT32 pitch,
INT32 priority,
INT32 channel)
{
int voice;
(void)channel;
if (sound_disabled)
return 0;
// UNUSED
priority = 0;
pitch = (pitch-128)/2+128;
voice = play_sample(S_sfx[id].data,vol,sep,(pitch*1000)/128,0);
// Returns a handle
return (id<<VOICESSHIFT)+voice;
}
void I_StopSound (INT32 handle)
{
// You need the handle returned by StartSound.
// Would be looping all channels,
// tracking down the handle,
// an setting the channel to zero.
int voice=handle & (VIRTUAL_VOICES-1);
if (sound_disabled)
return;
if (voice_check(voice)==S_sfx[handle>>VOICESSHIFT].data)
deallocate_voice(voice);
}
INT32 I_SoundIsPlaying(INT32 handle)
{
if (sound_disabled)
return FALSE;
if (voice_check(handle & (VIRTUAL_VOICES-1))==S_sfx[handle>>VOICESSHIFT].data)
return TRUE;
return FALSE;
}
// cut and past from ALLEGRO he don't share it :(
static inline int absolute_freq(int freq, SAMPLE *spl)
{
if (freq == 1000)
return spl->freq;
else
return (spl->freq * freq) / 1000;
}
void I_UpdateSoundParams( INT32 handle,
INT32 vol,
INT32 sep,
INT32 pitch)
{
// I fail too see that this is used.
// Would be using the handle to identify
// on which channel the sound might be active,
// and resetting the channel parameters.
int voice=handle & (VIRTUAL_VOICES-1);
int numsfx=handle>>VOICESSHIFT;
if (sound_disabled)
return;
if (voice_check(voice)==S_sfx[numsfx].data)
{
voice_set_volume(voice, vol);
voice_set_pan(voice, sep);
voice_set_frequency(voice, absolute_freq(pitch*1000/128,
S_sfx[numsfx].data));
}
}
void I_ShutdownSound(void)
{
// Wait till all pending sounds are finished.
//added:03-01-98:
if ( !sound_started )
return;
//added:08-01-98: remove_sound() explicitly because we don't use
// Allegro's allegro_exit();
remove_sound();
sound_started = false;
}
static char soundheader[] = "sound";
#if ALLEGRO_VERSION == 3
static char soundvar[] = "sb_freq";
#else
static char soundvar[] = "sound_freq";
#endif
void I_StartupSound(void)
{
int sfxcard,midicard;
#if ALLEGRO_VERSION == 3
char err[255];
#endif
if (sound_disabled)
sfxcard=DIGI_NONE;
else
sfxcard=DIGI_AUTODETECT;
if (midi_disabled)
midicard=MIDI_NONE;
else
midicard=MIDI_AUTODETECT; //DetectMusicCard();
digital_disabled=true; //Alam: No OGG/MP3/IT/MOD support
// Secure and configure sound device first.
CONS_Printf("I_StartupSound: ");
//Fab:25-04-98:note:install_sound will check for sound settings
// in the sound.cfg or allegro.cfg, in the current directory,
// or the directory pointed by 'ALLEGRO' env var.
#if ALLEGRO_VERSION == 3
if (install_sound(sfxcard,midicard,NULL)!=0)
{
sprintf (err,"Sound init error : %s\n",allegro_error);
CONS_Error (err);
sound_disabled=true;
midi_disabled=true;
}
else
{
CONS_Printf(" configured audio device\n" );
}
//added:08-01-98:we use a similar startup/shutdown scheme as Allegro.
I_AddExitFunc(I_ShutdownSound);
#endif
sound_started = true;
CV_SetValue(&cv_samplerate,get_config_int(soundheader,soundvar,cv_samplerate.value));
}
//
// MUSIC API.
// Still no music done.
// Remains. Dummies.
//
static MIDI* currsong; //im assuming only 1 song will be played at once
static int islooping=0;
static int musicdies=-1;
UINT8 music_started=0;
boolean songpaused=false;
/// ------------------------
// MUSIC SYSTEM
/// ------------------------
/* load_midi_mem:
* Loads a standard MIDI file from memory, returning a pointer to
* a MIDI structure, * or NULL on error.
* It is the load_midi from Allegro modified to load it from memory
*/
static MIDI *load_midi_mem(char *mempointer,int *e)
{
int c = *e;
long data=0;
unsigned char *fp;
MIDI *midi;
int num_tracks=0;
fp = (void *)mempointer;
if (!fp)
return NULL;
midi = malloc(sizeof (MIDI)); /* get some memory */
if (!midi)
return NULL;
for (c=0; c<MIDI_TRACKS; c++)
{
midi->track[c].data = NULL;
midi->track[c].len = 0;
}
fp+=4+4; // header size + 'chunk' size
swab(fp,&data,2); // convert to intel-endian
fp+=2; /* MIDI file type */
if ((data != 0) && (data != 1)) // only type 0 and 1 are suported
return NULL;
swab(fp,&num_tracks,2); /* number of tracks */
fp+=2;
if ((num_tracks < 1) || (num_tracks > MIDI_TRACKS))
return NULL;
swab(fp,&data,2); /* beat divisions */
fp+=2;
midi->divisions = ABS(data);
for (c=0; c<num_tracks; c++)
{ /* read each track */
if (memcmp(fp, "MTrk", 4))
return NULL;
fp+=4;
//swab(fp,&data,4); don't work !!!!??
((char *)&data)[0]=fp[3];
((char *)&data)[1]=fp[2];
((char *)&data)[2]=fp[1];
((char *)&data)[3]=fp[0];
fp+=4;
midi->track[c].len = data;
midi->track[c].data = fp;
fp+=data;
}
lock_midi(midi);
return midi;
}
void I_InitMusic(void)
{
if (midi_disabled)
return;
I_AddExitFunc(I_ShutdownMusic);
music_started = true;
songpaused = false;
}
void I_ShutdownMusic(void)
{
if ( !music_started )
return;
I_StopSong();
music_started=false;
}
/// ------------------------
// MUSIC PROPERTIES
/// ------------------------
musictype_t I_SongType(void)
{
if (currsong)
return MU_MID;
else
return MU_NONE;
}
boolean I_SongPlaying()
{
return (boolean)currsong;
}
boolean I_SongPaused()
{
return songpaused;
}
/// ------------------------
// MUSIC EFFECTS
/// ------------------------
boolean I_SetSongSpeed(float speed)
{
(void)speed;
return false;
}
/// ------------------------
// MUSIC SEEKING
/// ------------------------
UINT32 I_GetSongLength(void)
{
return 0;
}
boolean I_SetSongLoopPoint(UINT32 looppoint)
{
(void)looppoint;
return false;
}
UINT32 I_GetSongLoopPoint(void)
{
return 0;
}
boolean I_SetSongPosition(UINT32 position)
{
(void)position;
return false;
}
UINT32 I_GetSongPosition(void)
{
return 0;
}
/// ------------------------
// MUSIC PLAYBACK
/// ------------------------
boolean I_LoadSong(char *data, size_t len)
{
int e = len; //Alam: For error
if (midi_disabled)
return 0;
if (memcmp(data,"MThd",4)==0) // support mid file in WAD !!!
{
currsong=load_midi_mem(data,&e);
}
else
{
CONS_Printf("Music Lump is not a MIDI lump\n");
return 0;
}
if (currsong==NULL)
{
CONS_Printf("Not a valid mid file : %d\n",e);
return 0;
}
return 1;
}
void I_UnloadSong(void)
{
handle = 0;
if (midi_disabled)
return;
//destroy_midi(currsong);
}
boolean I_PlaySong(boolean looping)
{
handle = 0;
if (midi_disabled)
return false;
islooping = looping;
musicdies = gametic + NEWTICRATE*30;
if (play_midi(currsong,looping)==0)
return true;
return false;
}
void I_StopSong(void)
{
handle = 0;
if (midi_disabled)
return;
islooping = 0;
musicdies = 0;
stop_midi();
songpaused = false;
}
void I_PauseSong (INT32 handle)
{
handle = 0;
if (midi_disabled)
return;
midi_pause();
songpaused = true;
}
void I_ResumeSong (INT32 handle)
{
handle = 0;
if (midi_disabled)
return;
midi_resume();
songpaused = false;
}
void I_SetMusicVolume(INT32 volume)
{
if (midi_disabled)
return;
// Now set volume on output device.
set_volume (-1, Volset(volume));
}
boolean I_SetSongTrack(INT32 track)
{
(void)track;
return false;
}
// Is the song playing?
#if 0
int I_QrySongPlaying(int handle)
{
if (midi_disabled)
return 0;
//return islooping || musicdies > gametic;
return (midi_pos==-1);
}
#endif
/// ------------------------
// MUSIC FADING
/// ------------------------
void I_SetInternalMusicVolume(UINT8 volume)
{
(void)volume;
}
void I_StopFadingSong(void)
{
}
boolean I_FadeSongFromVolume(UINT8 target_volume, UINT8 source_volume, UINT32 ms, void (*callback)(void));
{
(void)target_volume;
(void)source_volume;
(void)ms;
return false;
}
boolean I_FadeSong(UINT8 target_volume, UINT32 ms, void (*callback)(void));
{
(void)target_volume;
(void)ms;
return false;
}
boolean I_FadeOutStopSong(UINT32 ms)
{
(void)ms;
return false;
}
boolean I_FadeInPlaySong(UINT32 ms, boolean looping)
{
(void)ms;
(void)looping;
return false;
}

File diff suppressed because it is too large Load diff

View file

@ -1,345 +0,0 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// Copyright (C) 1993-1996 by id Software, Inc.
// Portions Copyright (C) 1998-2000 by DooM Legacy Team.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//-----------------------------------------------------------------------------
/// \file
/// \brief hardware and software level, screen and video i/o, refresh,
/// setup ... a big mess. Got to clean that up!
#include <stdlib.h>
#include <unistd.h>
#include <stdarg.h>
#include <sys/time.h>
#include <sys/types.h>
//#include <sys/socket.h>
#include <netinet/in.h>
//#include <errnos.h>
#include <signal.h>
#include <go32.h>
#include <pc.h>
#include <dpmi.h>
#include <dos.h>
#include <sys/nearptr.h>
#include "../doomdef.h"
#include "../i_system.h"
#include "../v_video.h"
#include "../m_argv.h"
#include "vid_vesa.h"
#include "../i_video.h"
//dosstuff -newly added
static unsigned long dascreen;
static int gfx_use_vesa1;
boolean highcolor;
#define SCREENDEPTH 1 // bytes per pixel, do NOT change.
rendermode_t rendermode=render_soft;
//
// I_OsPolling
//
void I_OsPolling(void)
{
I_GetEvent();
//i dont think i have to do anything else here
}
//
// I_UpdateNoBlit
//
void I_UpdateNoBlit (void)
{
// what is this?
}
//profile stuff ---------------------------------------------------------
//added:16-01-98:wanted to profile the VID_BlitLinearScreen() asm code.
//#define TIMING //uncomment this to enable profiling
#ifdef TIMING
#include "../p5prof.h"
static INT64 mycount;
static INT64 mytotal = 0;
static unsigned long nombre = NEWTICRATE*10;
//static char runtest[10][80];
#endif
//profile stuff ---------------------------------------------------------
//
// I_FinishUpdate
//
static void I_BlitScreenVesa1(void); //see later
void I_FinishUpdate (void)
{
// draw captions if enabled
if (cv_closedcaptioning.value)
SCR_ClosedCaptions();
// draw FPS if enabled
if (cv_ticrate.value)
SCR_DisplayTicRate();
if (cv_showping.value && netgame && consoleplayer != serverplayer)
SCR_DisplayLocalPing();
//blast it to the screen
// this code sucks
//memcpy(dascreen,screens[0],screenwidth*screenheight);
//added:03-01-98: I tried to I_WaitVBL(1) here, but it slows down
// the game when the view becomes complicated, it looses ticks
if (cv_vidwait.value)
I_WaitVBL(1);
//added:16-01-98:profile screen blit.
#ifdef TIMING
ProfZeroTimer();
#endif
//added:08-01-98: support vesa1 bank change, without Allegro's BITMAP screen.
if ( gfx_use_vesa1 )
{
I_Error("Banked screen update not finished for dynamic res\n");
I_BlitScreenVesa1(); //blast virtual to physical screen.
}
else
{
//added:16-01-98:use quickie asm routine, last 2 args are
// src and dest rowbytes
// (memcpy is as fast as this one...)
VID_BlitLinearScreen(screens[0], vid.direct,
vid.width*vid.bpp, vid.height,
vid.width*vid.bpp, vid.rowbytes );
}
#ifdef TIMING
RDMSR(0x10,&mycount);
mytotal += mycount; //64bit add
if (nombre--==0)
I_Error("ScreenBlit CPU Spy reports: 0x%d %d\n", *((int *)&mytotal+1),
(int)mytotal );
#endif
}
//
// I_UpdateNoVsync
//
void I_UpdateNoVsync(void)
{
int real_vidwait = cv_vidwait.value;
cv_vidwait.value = 0;
I_FinishUpdate();
cv_vidwait.value = real_vidwait;
}
//
// I_ReadScreen
//
void I_ReadScreen (UINT8 *scr)
{
VID_BlitLinearScreen(screens[0], scr,
vid.width*vid.bpp, vid.height,
vid.width*vid.bpp, vid.rowbytes );
}
void I_SetPalette (RGBA_t *palette)
{
int i;
outportb(0x3c8,0);
for (i=0;i<256;i++,palette++)
{
outportb(0x3c9,palette->s.red>>2);
outportb(0x3c9,palette->s.green>>2);
outportb(0x3c9,palette->s.blue>>2);
}
}
//added 29-12-1997
/*==========================================================================*/
// I_BlastScreen : copy the virtual screen buffer to the physical screen mem
// using bank switching if needed.
/*==========================================================================*/
static void I_BlitScreenVesa1(void)
{
#define VIDBANKSIZE (1<<16)
#define VIDBANKSIZEMASK (VIDBANKSIZE-1) // defines ahoy!
__dpmi_regs r;
UINT8 *p_src;
long i;
long virtualsize;
// virtual screen buffer size
virtualsize = vid.rowbytes * vid.height * SCREENDEPTH;
p_src = screens[0];
for (i=0; virtualsize > 0; i++ )
{
r.x.ax = 0x4f05;
r.x.bx = 0x0;
r.x.cx = 0x0;
r.x.dx = i;
__dpmi_int(0x10,&r); //set bank
M_Memcpy((UINT8 *)dascreen,p_src,(virtualsize < VIDBANKSIZE) ? virtualsize : VIDBANKSIZE );
p_src += VIDBANKSIZE;
virtualsize -= VIDBANKSIZE;
}
}
//added:08-01-98: now we use Allegro's set_gfx_mode, but we want to
// restore the exact text mode that was before.
static INT16 myOldVideoMode;
static inline void I_SaveOldVideoMode(void)
{
__dpmi_regs r;
r.x.ax = 0x4f03; // Return current video mode
__dpmi_int(0x10,&r);
if ( r.x.ax != 0x4f )
myOldVideoMode = -1;
else
myOldVideoMode = r.x.bx;
}
//
// Close the screen, restore previous video mode.
//
void I_ShutdownGraphics (void)
{
__dpmi_regs r;
rendermode = render_none;
if ( !graphics_started )
return;
// free the last video mode screen buffers
if (vid.buffer)
free (vid.buffer);
/* Restore old video mode */
if (myOldVideoMode!=-1)
{
/* Restore old video mode */
r.x.ax = 0x4f02; // Set Super VGA video mode
r.x.bx = myOldVideoMode;
__dpmi_int(0x10,&r);
// Boris: my s3 don't do a cls because "win95" :<
clrscr();
}
else // no vesa put the normal video mode
{
r.x.ax = 0x03;
__dpmi_int(0x10,&r);
}
graphics_started = false;
}
//added:08-01-98:
// Set VESA1 video mode, coz Allegro set_gfx_mode a larger screenwidth...
//
#if 0
int set_vesa1_mode( int width, int height )
{
__dpmi_regs r;
// setup video mode.
r.x.ax = 0x4f02;
if ( ( width==320 )&&( height==200 ) && ( SCREENDEPTH==1 ) )
r.x.bx = 0x13; // 320x 200x1 (256 colors)
else
if ( ( width==320 )&&( height==240 ) && ( SCREENDEPTH==1 ) )
r.x.bx = 0x154; // 320x 240x1 (256 colors)
else
if ( ( width==320 )&&( height==400 ) && ( SCREENDEPTH==1 ) )
r.x.bx = 0x155; // 320x 400x1 (256 colors)
else
if ( ( width==640 )&&( height==400 ) && ( SCREENDEPTH==1 ) )
r.x.bx = 0x100; // 640x 400x1 (256 colors)
else
if ( ( width==640 )&&( height==480 ) && ( SCREENDEPTH==1 ) )
r.x.bx = 0x101; // 640x 480x1 (256 colors)
else
if ( ( width==800 )&&( height==600 ) && ( SCREENDEPTH==1 ) )
r.x.bx = 0x103; // 800x 600x1 (256 colors)
else
if ( ( width==1024)&&( height==768 ) && ( SCREENDEPTH==1 ) )
r.x.bx = 0x105; //1024x 768x1 (256 colors)
else
I_Error("I_SetVesa1Mode: video mode not supported.");
// enter graphics mode.
__dpmi_int(0x10,&r);
if ( r.x.ax != 0x4f )
I_Error("I_SetVesa1Mode: init video mode failed !");
return 0;
}
#endif
//added:08-01-98: now uses Allegro to setup Linear Frame Buffer video modes.
//
// Initialize video mode, setup dynamic screen size variables,
// and allocate screens.
//
void I_StartupGraphics(void)
{
//added:26-01-98: VID_Init() must be done only once,
// use VID_SetMode() to change vid mode while in the game.
if ( graphics_started )
return;
// remember the exact screen mode we were...
I_SaveOldVideoMode();
CONS_Printf("Vid_Init...");
// 0 for 256 color, else use highcolor modes
highcolor = M_CheckParm ("-highcolor");
VID_Init();
//gfx_use_vesa1 = false;
//added:03-01-98: register exit code for graphics
I_AddExitFunc(I_ShutdownGraphics);
graphics_started = true;
}
void I_StartupHardwareGraphics(void)
{
// oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo y
}

View file

@ -1,773 +0,0 @@
/* ______ ___ ___
* /\ _ \ /\_ \ /\_ \
* \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
* \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
* \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
* \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
* \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
* /\____/
* \_/__/
*
* Some definitions for internal use by the library code.
* This should not be included by user programs.
*
* By Shawn Hargreaves.
*
* See readme.txt for copyright information.
*/
#ifndef INTERNAL_H
#define INTERNAL_H
#include "allegro.h"
/* ______ ___ ___
* /\ _ \ /\_ \ /\_ \
* \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
* \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
* \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
* \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
* \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
* /\____/
* \_/__/
*
* Some definitions for internal use by the library code.
* This should not be included by user programs.
*
* By Shawn Hargreaves.
*
* See readme.txt for copyright information.
*/
#ifndef INTERNDJ_H
#define INTERNDJ_H
#ifndef DJGPP
#error This file should only be used by the djgpp version of Allegro
#endif
#include <dos.h>
/* file access macros */
#define FILE_OPEN(filename, handle) handle = open(filename, O_RDONLY | O_BINARY, S_IRUSR | S_IWUSR)
#define FILE_CREATE(filename, handle) handle = open(filename, O_WRONLY | O_BINARY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)
#define FILE_CLOSE(handle) close(handle)
#define FILE_READ(handle, buf, size, sz) sz = read(handle, buf, size)
#define FILE_WRITE(handle, buf, size, sz) sz = write(handle, buf, size)
#define FILE_SEARCH_STRUCT struct ffblk
#define FILE_FINDFIRST(filename, attrib, dta) findfirst(filename, dta, attrib)
#define FILE_FINDNEXT(dta) findnext(dta)
#define FILE_ATTRIB ff_attrib
#define FILE_SIZE ff_fsize
#define FILE_NAME ff_name
#define FILE_TIME ff_ftime
#define FILE_DATE ff_fdate
/* macros to enable and disable interrupts */
#define DISABLE() asm volatile ("cli")
#define ENABLE() asm volatile ("sti")
__INLINE__ void enter_critical(void)
{
if (windows_version >= 3) {
__dpmi_regs r;
r.x.ax = 0x1681;
__dpmi_int(0x2F, &r);
}
DISABLE();
}
__INLINE__ void exit_critical(void)
{
if (windows_version >= 3) {
__dpmi_regs r;
r.x.ax = 0x1682;
__dpmi_int(0x2F, &r);
}
ENABLE();
}
/* interrupt hander stuff */
#define _map_irq(irq) (((irq)>7) ? ((irq)+104) : ((irq)+8))
int _install_irq(int num, int (*handler)(void));
void _remove_irq(int num);
void _restore_irq(int irq);
void _enable_irq(int irq);
void _disable_irq(int irq);
#define _eoi(irq) { outportb(0x20, 0x20); if ((irq)>7) outportb(0xA0, 0x20); }
typedef struct _IRQ_HANDLER
{
int (*handler)(void); /* our C handler */
int number; /* irq number */
__dpmi_paddr old_vector; /* original protected mode vector */
} _IRQ_HANDLER;
/* DPMI memory mapping routines */
int _create_physical_mapping(unsigned long *linear, int *segment, unsigned long physaddr, int size);
void _remove_physical_mapping(unsigned long *linear, int *segment);
int _create_linear_mapping(unsigned long *linear, unsigned long physaddr, int size);
void _remove_linear_mapping(unsigned long *linear);
int _create_selector(int *segment, unsigned long linear, int size);
void _remove_selector(int *segment);
void _unlock_dpmi_data(void *addr, int size);
/* bank switching routines */
void _accel_bank_stub(void);
void _accel_bank_stub_end(void);
void _accel_bank_switch (void);
void _accel_bank_switch_end(void);
void _vesa_window_1(void);
void _vesa_window_1_end(void);
void _vesa_window_2(void);
void _vesa_window_2_end(void);
void _vesa_pm_window_1(void);
void _vesa_pm_window_1_end(void);
void _vesa_pm_window_2(void);
void _vesa_pm_window_2_end(void);
void _vesa_pm_es_window_1(void);
void _vesa_pm_es_window_1_end(void);
void _vesa_pm_es_window_2(void);
void _vesa_pm_es_window_2_end(void);
/* stuff for the VESA and VBE/AF drivers */
extern __dpmi_regs _dpmi_reg;
extern int _window_2_offset;
extern void (*_pm_vesa_switcher)(void);
extern void (*_pm_vesa_scroller)(void);
extern void (*_pm_vesa_pallete)(void);
extern int _mmio_segment;
extern void *_accel_driver;
extern int _accel_active;
extern void *_accel_set_bank;
extern void *_accel_idle;
void _fill_vbeaf_libc_exports(void *ptr);
void _fill_vbeaf_pmode_exports(void *ptr);
/* sound lib stuff */
extern int _fm_port;
extern int _mpu_port;
extern int _mpu_irq;
extern int _sb_freq;
extern int _sb_port;
extern int _sb_dma;
extern int _sb_irq;
int _sb_read_dsp_version(void);
int _sb_reset_dsp(int data);
void _sb_voice(int state);
int _sb_set_mixer(int digi_volume, int midi_volume);
void _mpu_poll(void);
int _dma_allocate_mem(int bytes, int *sel, unsigned long *phys);
void _dma_start(int channel, unsigned long addr, int size, int auto_init, int input);
void _dma_stop(int channel);
unsigned long _dma_todo(int channel);
void _dma_lock_mem(void);
#endif /* ifndef INTERNDJ_H */
/* flag for how many times we have been initialised */
extern int _allegro_count;
/* some Allegro functions need a block of scratch memory */
extern void *_scratch_mem;
extern int _scratch_mem_size;
__INLINE__ void _grow_scratch_mem(int size)
{
if (size > _scratch_mem_size) {
size = (size+1023) & 0xFFFFFC00;
_scratch_mem = realloc(_scratch_mem, size);
_scratch_mem_size = size;
}
}
/* list of functions to call at program cleanup */
void _add_exit_func(void (*func)(void));
void _remove_exit_func(void (*func)(void));
/* reads a translation file into memory */
void _load_config_text(void);
/* various bits of mouse stuff */
void _set_mouse_range(void);
extern BITMAP *_mouse_screen;
extern BITMAP *_mouse_sprite, *_mouse_pointer;
extern int _mouse_x_focus, _mouse_y_focus;
extern int _mouse_width, _mouse_height;
/* various bits of timer stuff */
extern int _timer_use_retrace;
extern volatile int _retrace_hpp_value;
/* caches and tables for svga bank switching */
extern int _last_bank_1, _last_bank_2;
extern int *_gfx_bank;
/* bank switching routines */
void _stub_bank_switch (void);
void _stub_bank_switch_end(void);
/* stuff for setting up bitmaps */
void _check_gfx_virginity(void);
BITMAP *_make_bitmap(int w, int h, unsigned long addr, GFX_DRIVER *driver, int color_depth, int bpl);
void _sort_out_virtual_width(int *width, GFX_DRIVER *driver);
GFX_VTABLE *_get_vtable(int color_depth);
extern GFX_VTABLE _screen_vtable;
extern int _sub_bitmap_id_count;
extern int _textmode;
#define BYTES_PER_PIXEL(bpp) (((int)(bpp) + 7) / 8)
int _color_load_depth(int depth);
extern int _color_conv;
BITMAP *_fixup_loaded_bitmap(BITMAP *bmp, PALETTE pal, int bpp);
/* VGA register access routines */
void _vga_vsync(void);
void _vga_set_pallete_range(PALLETE p, int from, int to, int vsync);
extern int _crtc;
/* _read_vga_register:
* Reads the contents of a VGA register.
*/
__INLINE__ int _read_vga_register(int port, int index)
{
if (port==0x3C0)
inportb(_crtc+6);
outportb(port, index);
return inportb(port+1);
}
/* _write_vga_register:
* Writes a byte to a VGA register.
*/
__INLINE__ void _write_vga_register(int port, int index, int v)
{
if (port==0x3C0) {
inportb(_crtc+6);
outportb(port, index);
outportb(port, v);
}
else {
outportb(port, index);
outportb(port+1, v);
}
}
/* _alter_vga_register:
* Alters specific bits of a VGA register.
*/
__INLINE__ void _alter_vga_register(int port, int index, int mask, int v)
{
int temp;
temp = _read_vga_register(port, index);
temp &= (~mask);
temp |= (v & mask);
_write_vga_register(port, index, temp);
}
/* _vsync_out_h:
* Waits until the VGA is not in either a vertical or horizontal retrace.
*/
__INLINE__ void _vsync_out_h(void)
{
do {
} while (inportb(0x3DA) & 1);
}
/* _vsync_out_v:
* Waits until the VGA is not in a vertical retrace.
*/
__INLINE__ void _vsync_out_v(void)
{
do {
} while (inportb(0x3DA) & 8);
}
/* _vsync_in:
* Waits until the VGA is in the vertical retrace period.
*/
__INLINE__ void _vsync_in(void)
{
if (_timer_use_retrace) {
int t = retrace_count;
do {
} while (t == retrace_count);
}
else {
do {
} while (!(inportb(0x3DA) & 8));
}
}
/* _write_hpp:
* Writes to the VGA pelpan register.
*/
__INLINE__ void _write_hpp(int value)
{
if (_timer_use_retrace) {
_retrace_hpp_value = value;
do {
} while (_retrace_hpp_value == value);
}
else {
do {
} while (!(inportb(0x3DA) & 8));
_write_vga_register(0x3C0, 0x33, value);
}
}
void _set_vga_virtual_width(int old_width, int new_width);
/* current drawing mode */
extern int _drawing_mode;
extern BITMAP *_drawing_pattern;
extern int _drawing_x_anchor;
extern int _drawing_y_anchor;
extern unsigned int _drawing_x_mask;
extern unsigned int _drawing_y_mask;
/* graphics drawing routines */
void _normal_line(BITMAP *bmp, int x1, int y1, int x2, int y2, int color);
void _normal_rectfill(BITMAP *bmp, int x1, int y1, int x2, int y2, int color);
int _linear_getpixel8(struct BITMAP *bmp, int x, int y);
void _linear_putpixel8(struct BITMAP *bmp, int x, int y, int color);
void _linear_vline8(struct BITMAP *bmp, int x, int y1, int y2, int color);
void _linear_hline8(struct BITMAP *bmp, int x1, int y, int x2, int color);
void _linear_draw_sprite8(struct BITMAP *bmp, struct BITMAP *sprite, int x, int y);
void _linear_draw_sprite_v_flip8(struct BITMAP *bmp, struct BITMAP *sprite, int x, int y);
void _linear_draw_sprite_h_flip8(struct BITMAP *bmp, struct BITMAP *sprite, int x, int y);
void _linear_draw_sprite_vh_flip8(struct BITMAP *bmp, struct BITMAP *sprite, int x, int y);
void _linear_draw_trans_sprite8(struct BITMAP *bmp, struct BITMAP *sprite, int x, int y);
void _linear_draw_lit_sprite8(struct BITMAP *bmp, struct BITMAP *sprite, int x, int y, int color);
void _linear_draw_rle_sprite8(struct BITMAP *bmp, struct RLE_SPRITE *sprite, int x, int y);
void _linear_draw_trans_rle_sprite8(struct BITMAP *bmp, struct RLE_SPRITE *sprite, int x, int y);
void _linear_draw_lit_rle_sprite8(struct BITMAP *bmp, struct RLE_SPRITE *sprite, int x, int y, int color);
void _linear_draw_character8(struct BITMAP *bmp, struct BITMAP *sprite, int x, int y, int color);
void _linear_textout_fixed8(struct BITMAP *bmp, void *f, int h, unsigned char *str, int x, int y, int color);
void _linear_blit8(struct BITMAP *source, struct BITMAP *dest, int source_x, int source_y, int dest_x, int dest_y, int width, int height);
void _linear_blit_backward8(struct BITMAP *source, struct BITMAP *dest, int source_x, int source_y, int dest_x, int dest_y, int width, int height);
void _linear_masked_blit8(struct BITMAP *source, struct BITMAP *dest, int source_x, int source_y, int dest_x, int dest_y, int width, int height);
void _linear_clear_to_color8(struct BITMAP *bitmap, int color);
#ifdef ALLEGRO_COLOR16
void _linear_putpixel15(struct BITMAP *bmp, int x, int y, int color);
void _linear_vline15(struct BITMAP *bmp, int x, int y1, int y2, int color);
void _linear_hline15(struct BITMAP *bmp, int x1, int y, int x2, int color);
void _linear_draw_trans_sprite15(struct BITMAP *bmp, struct BITMAP *sprite, int x, int y);
void _linear_draw_lit_sprite15(struct BITMAP *bmp, struct BITMAP *sprite, int x, int y, int color);
void _linear_draw_rle_sprite15(struct BITMAP *bmp, struct RLE_SPRITE *sprite, int x, int y);
void _linear_draw_trans_rle_sprite15(struct BITMAP *bmp, struct RLE_SPRITE *sprite, int x, int y);
void _linear_draw_lit_rle_sprite15(struct BITMAP *bmp, struct RLE_SPRITE *sprite, int x, int y, int color);
int _linear_getpixel16(struct BITMAP *bmp, int x, int y);
void _linear_putpixel16(struct BITMAP *bmp, int x, int y, int color);
void _linear_vline16(struct BITMAP *bmp, int x, int y1, int y2, int color);
void _linear_hline16(struct BITMAP *bmp, int x1, int y, int x2, int color);
void _linear_draw_sprite16(struct BITMAP *bmp, struct BITMAP *sprite, int x, int y);
void _linear_draw_256_sprite16(struct BITMAP *bmp, struct BITMAP *sprite, int x, int y);
void _linear_draw_sprite_v_flip16(struct BITMAP *bmp, struct BITMAP *sprite, int x, int y);
void _linear_draw_sprite_h_flip16(struct BITMAP *bmp, struct BITMAP *sprite, int x, int y);
void _linear_draw_sprite_vh_flip16(struct BITMAP *bmp, struct BITMAP *sprite, int x, int y);
void _linear_draw_trans_sprite16(struct BITMAP *bmp, struct BITMAP *sprite, int x, int y);
void _linear_draw_lit_sprite16(struct BITMAP *bmp, struct BITMAP *sprite, int x, int y, int color);
void _linear_draw_rle_sprite16(struct BITMAP *bmp, struct RLE_SPRITE *sprite, int x, int y);
void _linear_draw_trans_rle_sprite16(struct BITMAP *bmp, struct RLE_SPRITE *sprite, int x, int y);
void _linear_draw_lit_rle_sprite16(struct BITMAP *bmp, struct RLE_SPRITE *sprite, int x, int y, int color);
void _linear_draw_character16(struct BITMAP *bmp, struct BITMAP *sprite, int x, int y, int color);
void _linear_textout_fixed16(struct BITMAP *bmp, void *f, int h, unsigned char *str, int x, int y, int color);
void _linear_blit16(struct BITMAP *source, struct BITMAP *dest, int source_x, int source_y, int dest_x, int dest_y, int width, int height);
void _linear_blit_backward16(struct BITMAP *source, struct BITMAP *dest, int source_x, int source_y, int dest_x, int dest_y, int width, int height);
void _linear_masked_blit16(struct BITMAP *source, struct BITMAP *dest, int source_x, int source_y, int dest_x, int dest_y, int width, int height);
void _linear_clear_to_color16(struct BITMAP *bitmap, int color);
#endif
#ifdef ALLEGRO_COLOR24
int _linear_getpixel24(struct BITMAP *bmp, int x, int y);
void _linear_putpixel24(struct BITMAP *bmp, int x, int y, int color);
void _linear_vline24(struct BITMAP *bmp, int x, int y1, int y2, int color);
void _linear_hline24(struct BITMAP *bmp, int x1, int y, int x2, int color);
void _linear_draw_sprite24(struct BITMAP *bmp, struct BITMAP *sprite, int x, int y);
void _linear_draw_256_sprite24(struct BITMAP *bmp, struct BITMAP *sprite, int x, int y);
void _linear_draw_sprite_v_flip24(struct BITMAP *bmp, struct BITMAP *sprite, int x, int y);
void _linear_draw_sprite_h_flip24(struct BITMAP *bmp, struct BITMAP *sprite, int x, int y);
void _linear_draw_sprite_vh_flip24(struct BITMAP *bmp, struct BITMAP *sprite, int x, int y);
void _linear_draw_trans_sprite24(struct BITMAP *bmp, struct BITMAP *sprite, int x, int y);
void _linear_draw_lit_sprite24(struct BITMAP *bmp, struct BITMAP *sprite, int x, int y, int color);
void _linear_draw_rle_sprite24(struct BITMAP *bmp, struct RLE_SPRITE *sprite, int x, int y);
void _linear_draw_trans_rle_sprite24(struct BITMAP *bmp, struct RLE_SPRITE *sprite, int x, int y);
void _linear_draw_lit_rle_sprite24(struct BITMAP *bmp, struct RLE_SPRITE *sprite, int x, int y, int color);
void _linear_draw_character24(struct BITMAP *bmp, struct BITMAP *sprite, int x, int y, int color);
void _linear_textout_fixed24(struct BITMAP *bmp, void *f, int h, unsigned char *str, int x, int y, int color);
void _linear_blit24(struct BITMAP *source, struct BITMAP *dest, int source_x, int source_y, int dest_x, int dest_y, int width, int height);
void _linear_blit_backward24(struct BITMAP *source, struct BITMAP *dest, int source_x, int source_y, int dest_x, int dest_y, int width, int height);
void _linear_masked_blit24(struct BITMAP *source, struct BITMAP *dest, int source_x, int source_y, int dest_x, int dest_y, int width, int height);
void _linear_clear_to_color24(struct BITMAP *bitmap, int color);
#endif
#ifdef ALLEGRO_COLOR32
int _linear_getpixel32(struct BITMAP *bmp, int x, int y);
void _linear_putpixel32(struct BITMAP *bmp, int x, int y, int color);
void _linear_vline32(struct BITMAP *bmp, int x, int y1, int y2, int color);
void _linear_hline32(struct BITMAP *bmp, int x1, int y, int x2, int color);
void _linear_draw_sprite32(struct BITMAP *bmp, struct BITMAP *sprite, int x, int y);
void _linear_draw_256_sprite32(struct BITMAP *bmp, struct BITMAP *sprite, int x, int y);
void _linear_draw_sprite_v_flip32(struct BITMAP *bmp, struct BITMAP *sprite, int x, int y);
void _linear_draw_sprite_h_flip32(struct BITMAP *bmp, struct BITMAP *sprite, int x, int y);
void _linear_draw_sprite_vh_flip32(struct BITMAP *bmp, struct BITMAP *sprite, int x, int y);
void _linear_draw_trans_sprite32(struct BITMAP *bmp, struct BITMAP *sprite, int x, int y);
void _linear_draw_lit_sprite32(struct BITMAP *bmp, struct BITMAP *sprite, int x, int y, int color);
void _linear_draw_rle_sprite32(struct BITMAP *bmp, struct RLE_SPRITE *sprite, int x, int y);
void _linear_draw_trans_rle_sprite32(struct BITMAP *bmp, struct RLE_SPRITE *sprite, int x, int y);
void _linear_draw_lit_rle_sprite32(struct BITMAP *bmp, struct RLE_SPRITE *sprite, int x, int y, int color);
void _linear_draw_character32(struct BITMAP *bmp, struct BITMAP *sprite, int x, int y, int color);
void _linear_textout_fixed32(struct BITMAP *bmp, void *f, int h, unsigned char *str, int x, int y, int color);
void _linear_blit32(struct BITMAP *source, struct BITMAP *dest, int source_x, int source_y, int dest_x, int dest_y, int width, int height);
void _linear_blit_backward32(struct BITMAP *source, struct BITMAP *dest, int source_x, int source_y, int dest_x, int dest_y, int width, int height);
void _linear_masked_blit32(struct BITMAP *source, struct BITMAP *dest, int source_x, int source_y, int dest_x, int dest_y, int width, int height);
void _linear_clear_to_color32(struct BITMAP *bitmap, int color);
#endif
int _x_getpixel(struct BITMAP *bmp, int x, int y);
void _x_putpixel(struct BITMAP *bmp, int x, int y, int color);
void _x_vline(struct BITMAP *bmp, int x, int y1, int y2, int color);
void _x_hline(struct BITMAP *bmp, int x1, int y, int x2, int color);
void _x_draw_sprite(struct BITMAP *bmp, struct BITMAP *sprite, int x, int y);
void _x_draw_sprite_v_flip(struct BITMAP *bmp, struct BITMAP *sprite, int x, int y);
void _x_draw_sprite_h_flip(struct BITMAP *bmp, struct BITMAP *sprite, int x, int y);
void _x_draw_sprite_vh_flip(struct BITMAP *bmp, struct BITMAP *sprite, int x, int y);
void _x_draw_trans_sprite(struct BITMAP *bmp, struct BITMAP *sprite, int x, int y);
void _x_draw_lit_sprite(struct BITMAP *bmp, struct BITMAP *sprite, int x, int y, int color);
void _x_draw_rle_sprite(struct BITMAP *bmp, struct RLE_SPRITE *sprite, int x, int y);
void _x_draw_trans_rle_sprite(struct BITMAP *bmp, struct RLE_SPRITE *sprite, int x, int y);
void _x_draw_lit_rle_sprite(struct BITMAP *bmp, struct RLE_SPRITE *sprite, int x, int y, int color);
void _x_draw_character(struct BITMAP *bmp, struct BITMAP *sprite, int x, int y, int color);
void _x_textout_fixed(struct BITMAP *bmp, void *f, int h, unsigned char *str, int x, int y, int color);
void _x_blit_from_memory(struct BITMAP *source, struct BITMAP *dest, int source_x, int source_y, int dest_x, int dest_y, int width, int height);
void _x_blit_to_memory(struct BITMAP *source, struct BITMAP *dest, int source_x, int source_y, int dest_x, int dest_y, int width, int height);
void _x_blit(struct BITMAP *source, struct BITMAP *dest, int source_x, int source_y, int dest_x, int dest_y, int width, int height);
void _x_blit_forward(struct BITMAP *source, struct BITMAP *dest, int source_x, int source_y, int dest_x, int dest_y, int width, int height);
void _x_blit_backward(struct BITMAP *source, struct BITMAP *dest, int source_x, int source_y, int dest_x, int dest_y, int width, int height);
void _x_masked_blit(struct BITMAP *source, struct BITMAP *dest, int source_x, int source_y, int dest_x, int dest_y, int width, int height);
void _x_clear_to_color(struct BITMAP *bitmap, int color);
/* asm helper for stretch_blit() */
void _do_stretch(BITMAP *source, BITMAP *dest, void *drawer, int sx, fixed sy, fixed syd, int dx, int dy, int dh, int color_depth);
/* number of fractional bits used by the polygon rasteriser */
#define POLYGON_FIX_SHIFT 18
/* bitfield specifying which polygon attributes need interpolating */
#define INTERP_FLAT 1
#define INTERP_1COL 2
#define INTERP_3COL 4
#define INTERP_FIX_UV 8
#define INTERP_Z 16
#define INTERP_FLOAT_UV 32
#define OPT_FLOAT_UV_TO_FIX 64
#define COLOR_TO_RGB 128
/* information for polygon scanline fillers */
typedef struct POLYGON_SEGMENT
{
fixed u, v, du, dv; /* fixed point u/v coordinates */
fixed c, dc; /* single color gouraud shade values */
fixed r, g, b, dr, dg, db; /* RGB gouraud shade values */
float z, dz; /* polygon depth (1/z) */
float fu, fv, dfu, dfv; /* floating point u/v coordinates */
unsigned char *texture; /* the texture map */
int umask, vmask, vshift; /* texture map size information */
int seg; /* destination bitmap selector */
} POLYGON_SEGMENT;
/* an active polygon edge */
typedef struct POLYGON_EDGE
{
int top; /* top y position */
int bottom; /* bottom y position */
fixed x, dx; /* fixed point x position and gradient */
fixed w; /* width of line segment */
POLYGON_SEGMENT dat; /* texture/gouraud information */
struct POLYGON_EDGE *prev; /* doubly linked list */
struct POLYGON_EDGE *next;
} POLYGON_EDGE;
/* prototype for the scanline filler functions */
typedef void (*SCANLINE_FILLER)(unsigned long addr, int w, POLYGON_SEGMENT *info);
/* polygon helper functions */
extern SCANLINE_FILLER _optim_alternative_drawer;
POLYGON_EDGE *_add_edge(POLYGON_EDGE *list, POLYGON_EDGE *edge, int sort_by_x);
POLYGON_EDGE *_remove_edge(POLYGON_EDGE *list, POLYGON_EDGE *edge);
void _fill_3d_edge_structure(POLYGON_EDGE *edge, V3D *v1, V3D *v2, int flags, BITMAP *bmp);
void _fill_3d_edge_structure_f(POLYGON_EDGE *edge, V3D_f *v1, V3D_f *v2, int flags, BITMAP *bmp);
SCANLINE_FILLER _get_scanline_filler(int type, int *flags, POLYGON_SEGMENT *info, BITMAP *texture, BITMAP *bmp);
void _clip_polygon_segment(POLYGON_SEGMENT *info, int gap, int flags);
/* polygon scanline filler functions */
void _poly_scanline_gcol8(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_grgb8(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_atex8(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_ptex8(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_atex_mask8(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_ptex_mask8(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_atex_lit8(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_ptex_lit8(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_atex_mask_lit8(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_ptex_mask_lit8(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_grgb8x(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_grgb15(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_atex_mask15(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_ptex_mask15(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_atex_lit15(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_ptex_lit15(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_atex_mask_lit15(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_ptex_mask_lit15(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_grgb15x(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_atex_lit15x(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_ptex_lit15x(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_atex_mask_lit15x(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_ptex_mask_lit15x(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_ptex_lit15d(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_ptex_mask_lit15d(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_grgb16(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_atex16(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_ptex16(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_atex_mask16(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_ptex_mask16(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_atex_lit16(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_ptex_lit16(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_atex_mask_lit16(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_ptex_mask_lit16(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_grgb16x(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_atex_lit16x(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_ptex_lit16x(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_atex_mask_lit16x(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_ptex_mask_lit16x(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_ptex_lit16d(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_ptex_mask_lit16d(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_grgb24(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_atex24(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_ptex24(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_atex_mask24(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_ptex_mask24(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_atex_lit24(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_ptex_lit24(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_atex_mask_lit24(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_ptex_mask_lit24(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_grgb24x(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_atex_lit24x(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_ptex_lit24x(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_atex_mask_lit24x(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_ptex_mask_lit24x(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_ptex_lit24d(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_ptex_mask_lit24d(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_grgb32(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_atex32(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_ptex32(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_atex_mask32(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_ptex_mask32(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_atex_lit32(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_ptex_lit32(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_atex_mask_lit32(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_ptex_mask_lit32(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_grgb32x(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_atex_lit32x(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_ptex_lit32x(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_atex_mask_lit32x(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_ptex_mask_lit32x(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_ptex_lit32d(unsigned long addr, int w, POLYGON_SEGMENT *info);
void _poly_scanline_ptex_mask_lit32d(unsigned long addr, int w, POLYGON_SEGMENT *info);
/* sound lib stuff */
extern int _digi_volume;
extern int _midi_volume;
extern int _flip_pan;
extern int _sound_hq;
extern int (*_midi_init)(void);
extern void (*_midi_exit)(void);
int _midi_allocate_voice(int min, int max);
extern volatile long _midi_tick;
int _digmid_find_patches(char *dir, char *file);
#define VIRTUAL_VOICES 256
typedef struct /* a virtual (as seen by the user) soundcard voice */
{
SAMPLE *sample; /* which sample are we playing? (NULL = free) */
int num; /* physical voice number (-1 = been killed off) */
int autokill; /* set to free the voice when the sample finishes */
long time; /* when we were started (for voice allocation) */
int priority; /* how important are we? */
} VOICE;
extern VOICE _voice[VIRTUAL_VOICES];
typedef struct /* a physical (as used by hardware) soundcard voice */
{
int num; /* the virtual voice currently using me (-1 = free) */
int playmode; /* are we looping? */
int vol; /* current volume (fixed point .12) */
int dvol; /* volume delta, for ramping */
int target_vol; /* target volume, for ramping */
int pan; /* current pan (fixed point .12) */
int dpan; /* pan delta, for sweeps */
int target_pan; /* target pan, for sweeps */
int freq; /* current frequency (fixed point .12) */
int dfreq; /* frequency delta, for sweeps */
int target_freq; /* target frequency, for sweeps */
} PHYS_VOICE;
extern PHYS_VOICE _phys_voice[DIGI_VOICES];
#define MIXER_DEF_SFX 8
#define MIXER_MAX_SFX 64
int _mixer_init(int bufsize, int freq, int stereo, int is16bit, int *voices);
void _mixer_exit(void);
void _mix_some_samples(unsigned long buf, unsigned short seg, int issigned);
void _mixer_init_voice(int voice, SAMPLE *sample);
void _mixer_release_voice(int voice);
void _mixer_start_voice(int voice);
void _mixer_stop_voice(int voice);
void _mixer_loop_voice(int voice, int loopmode);
int _mixer_get_position(int voice);
void _mixer_set_position(int voice, int position);
int _mixer_get_volume(int voice);
void _mixer_set_volume(int voice, int volume);
void _mixer_ramp_volume(int voice, int time, int endvol);
void _mixer_stop_volume_ramp(int voice);
int _mixer_get_frequency(int voice);
void _mixer_set_frequency(int voice, int frequency);
void _mixer_sweep_frequency(int voice, int time, int endfreq);
void _mixer_stop_frequency_sweep(int voice);
int _mixer_get_pan(int voice);
void _mixer_set_pan(int voice, int pan);
void _mixer_sweep_pan(int voice, int time, int endpan);
void _mixer_stop_pan_sweep(int voice);
void _mixer_set_echo(int voice, int strength, int delay);
void _mixer_set_tremolo(int voice, int rate, int depth);
void _mixer_set_vibrato(int voice, int rate, int depth);
/* dummy functions for the NoSound drivers */
int _dummy_detect(int input);
int _dummy_init(int input, int voices);
void _dummy_exit(int input);
int _dummy_mixer_volume(int volume);
void _dummy_init_voice(int voice, SAMPLE *sample);
void _dummy_noop1(int p);
void _dummy_noop2(int p1, int p2);
void _dummy_noop3(int p1, int p2, int p3);
int _dummy_get_position(int voice);
int _dummy_get(int voice);
void _dummy_raw_midi(unsigned char data);
int _dummy_load_patches(char *patches, char *drums);
void _dummy_adjust_patches(char *patches, char *drums);
void _dummy_key_on(int inst, int note, int bend, int vol, int pan);
/* from djgpp's libc, needed to find which directory we were run from */
extern int __crt0_argc;
extern char **__crt0_argv;
#endif /* ifndef INTERNAL_H */

View file

@ -1,22 +0,0 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// Copyright (C) 2005-2020 by Sonic Team Junior.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//-----------------------------------------------------------------------------
/// \file
/// \brief Set Com port and speed for GDBStubs for DJGGP
///
/// copy and rename as rdb.h and set the defines below as needed
#define DEBUG_COM_PORT 2
#define DEBUG_COM_PORT_SPEED 9600

View file

@ -1,905 +0,0 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// Copyright (C) 1998-2000 by DooM Legacy Team.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//-----------------------------------------------------------------------------
/// \file
/// \brief extended vesa VESA2.0 video modes i/o
#include <stdlib.h>
#include "../i_system.h" //I_Error()
#include "vid_vesa.h"
#include "../doomdef.h" //MAXVIDWIDTH, MAXVIDHEIGHT
#include "../screen.h"
#include <dpmi.h>
#include <go32.h>
#include <sys/farptr.h>
#include <sys/movedata.h>
#include <sys/segments.h>
#include <sys/nearptr.h>
#include "../console.h"
#include "../command.h" //added:21-03-98: vid_xxx commands
#include "../i_video.h"
// PROTOS
static vmode_t *VID_GetModePtr (int modenum);
static int VID_VesaGetModeInfo (int modenum);
static void VID_VesaGetExtraModes (void);
static INT32 VID_VesaInitMode (viddef_t *lvid, vmode_t *pcurrentmode);
static void VID_Command_NumModes_f (void);
static void VID_Command_ModeInfo_f (void);
static void VID_Command_ModeList_f (void);
static void VID_Command_Mode_f (void);
consvar_t cv_vidwait = {"vid_wait", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
static consvar_t cv_stretch = {"stretch", "On", CV_SAVE|CV_NOSHOWHELP, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
#define VBEVERSION 2 // we need vesa2 or higher
// -----------------------------------------------------
#define MASK_LINEAR(addr) (addr & 0x000FFFFF)
#define RM_TO_LINEAR(addr) (((addr & 0xFFFF0000) >> 12) + (addr & 0xFFFF))
#define RM_OFFSET(addr) (addr & 0xF)
#define RM_SEGMENT(addr) ((addr >> 4) & 0xFFFF)
// -----------------------------------------------------
static int totalvidmem;
static vmode_t vesa_modes[MAX_VESA_MODES] = {{NULL, NULL, 0, 0, 0, 0, 0, 0, NULL, NULL, 0}};
static vesa_extra_t vesa_extra[MAX_VESA_MODES];
//this is the only supported non-vesa mode : standard 320x200x256c.
#define NUMVGAVIDMODES 1
static INT32 VGA_InitMode (viddef_t *lvid, vmode_t *pcurrentmode);
static char vgamode1[] ="320x200";
static vmode_t vgavidmodes[NUMVGAVIDMODES] = {
{
NULL,
vgamode1,
320, 200, //(200.0/320.0)*(320.0/240.0),
320, 1, // rowbytes, bytes per pixel
0, 1,
NULL,
VGA_InitMode, 0
}
};
static char names[MAX_VESA_MODES][10];
//----------------------------i_video.c------------------------------------
// these ones should go to i_video.c, but I prefer keep them away from the
// doom sources until the vesa stuff is ok.
static int numvidmodes; //total number of video modes, vga, vesa1, vesa2.
static vmode_t *pvidmodes; //start of videomodes list.
static vmode_t *pcurrentmode; // the current active videomode.
//----------------------------i_video.c------------------------------------
// table des modes videos.
// seul le mode 320x200x256c standard VGA est support sans le VESA.
// ce mode est le mode numro 0 dans la liste.
typedef struct
{
int modenum; // vesa vbe2.0 modenum
int mode_attributes;
int winasegment;
int winbsegment;
int bytes_per_scanline; // bytes per logical scanline (+16)
int win; // window number (A=0, B=1)
int win_size; // window size (+6)
int granularity; // how finely i can set the window in vid mem (+4)
int width, height; // displayed width and height (+18, +20)
int bits_per_pixel; // er, better be 8, 15, 16, 24, or 32 (+25)
int bytes_per_pixel; // er, better be 1, 2, or 4
int memory_model; // and better be 4 or 6, packed or direct color (+27)
int num_pages; // number of complete frame buffer pages (+29)
int red_width; // the # of bits in the red component (+31)
int red_pos; // the bit position of the red component (+32)
int green_width; // etc.. (+33)
int green_pos; // (+34)
int blue_width; // (+35)
int blue_pos; // (+36)
int pptr;
int pagesize;
int numpages;
} modeinfo_t;
static vbeinfoblock_t vesainfo;
static vesamodeinfo_t vesamodeinfo;
// ------------------------------------------------------------------------
// DOS stuff
// ------------------------------------------------------------------------
static unsigned long conventional_memory = (unsigned long)-1;
FUNCINLINE static ATTRINLINE void map_in_conventional_memory(void)
{
if (conventional_memory == (unsigned long)-1)
{
if (__djgpp_nearptr_enable())
{
conventional_memory = __djgpp_conventional_base;
}
}
}
// Converts a flat 32 bit ptr to a realmode 0x12345 type ptr (seg<<4 + offs)
#if 0
unsigned int ptr2real(void *ptr)
{
map_in_conventional_memory();
return (int)ptr - conventional_memory;
}
#endif
// Converts 0x12345 (seg<<4+offs) realmode ptr to a flat 32bit ptr
FUNCINLINE static ATTRINLINE void *real2ptr(unsigned int real)
{
map_in_conventional_memory();
return (void *) (real + conventional_memory);
}
// ------------------------------------------------------------------------
/* ======================================================================== */
// Add the standard VGA video modes (only one now) to the video modes list.
/* ======================================================================== */
static inline void VGA_Init(void)
{
vgavidmodes[NUMVGAVIDMODES-1].pnext = pvidmodes;
pvidmodes = &vgavidmodes[0];
numvidmodes += NUMVGAVIDMODES;
}
//added:30-01-98: return number of video modes in pvidmodes list
INT32 VID_NumModes(void)
{
return numvidmodes;
}
//added:21-03-98: return info on video mode
FUNCINLINE static ATTRINLINE const char *VID_ModeInfo (int modenum, char **ppheader)
{
static const char *badmodestr = "Bad video mode number\n";
vmode_t *pv;
pv = VID_GetModePtr (modenum);
if (!pv)
{
if (ppheader)
*ppheader = NULL;
return badmodestr;
}
else
{
//if (ppheader)
// *ppheader = pv->header;
return pv->name;
}
}
//added:03-02-98: return a video mode number from the dimensions
INT32 VID_GetModeForSize( INT32 w, INT32 h)
{
vmode_t *pv;
int modenum;
pv = pvidmodes;
for (modenum=0; pv!=NULL; pv=pv->pnext,modenum++ )
{
if ( pv->width==(unsigned)w && pv->height==(unsigned)h )
return modenum;
}
return 0;
}
/* ======================================================================== */
//
/* ======================================================================== */
void VID_Init (void)
{
COM_AddCommand ("vid_nummodes", VID_Command_NumModes_f);
COM_AddCommand ("vid_modeinfo", VID_Command_ModeInfo_f);
COM_AddCommand ("vid_modelist", VID_Command_ModeList_f);
COM_AddCommand ("vid_mode", VID_Command_Mode_f);
CV_RegisterVar (&cv_vidwait);
CV_RegisterVar (&cv_stretch);
//setup the videmodes list,
// note that mode 0 must always be VGA mode 0x13
pvidmodes = NULL;
pcurrentmode = NULL;
numvidmodes = 0;
// setup the vesa_modes list
VID_VesaGetExtraModes ();
// the game boots in 320x200 standard VGA, but
// we need a highcolor mode to run the game in highcolor
if (highcolor && numvidmodes==0)
I_Error ("No 15bit highcolor VESA2 video mode found, cannot run in highcolor.\n");
// add the vga modes at the start of the modes list
VGA_Init();
#ifdef DEBUG
CONS_Printf("VID_SetMode(%d)\n",vid.modenum);
#endif
VID_SetMode (0); //vid.modenum);
#ifdef DEBUG
CONS_Printf("after VID_SetMode\n");
CONS_Printf("vid.width %d\n",vid.width);
CONS_Printf("vid.height %d\n",vid.height);
CONS_Printf("vid.buffer %x\n",vid.buffer);
CONS_Printf("vid.rowbytes %d\n",vid.rowbytes);
CONS_Printf("vid.numpages %d\n",vid.numpages);
CONS_Printf("vid.recalc %d\n",vid.recalc);
CONS_Printf("vid.direct %x\n",vid.direct);
#endif
}
// ========================================================================
// Returns a vmode_t from the video modes list, given a video mode number.
// ========================================================================
vmode_t *VID_GetModePtr (int modenum)
{
vmode_t *pv;
pv = pvidmodes;
if (!pv)
I_Error ("VID_error 1\n");
while (modenum--)
{
pv = pv->pnext;
if (!pv)
I_Error ("VID_error 2\n");
}
return pv;
}
//added:30-01-98:return the name of a video mode
const char *VID_GetModeName (INT32 modenum)
{
return (VID_GetModePtr(modenum))->name;
}
// ========================================================================
// Sets a video mode
// ========================================================================
INT32 VID_SetMode (INT32 modenum) //, UINT8 *palette)
{
int vstat;
vmode_t *pnewmode, *poldmode;
if ((modenum >= numvidmodes) || (modenum < 0))
{
if (pcurrentmode == NULL)
{
modenum = 0; // mode hasn't been set yet, so initialize to base
// mode since they gave us an invalid initial mode
}
else
{
//nomodecheck = true;
I_Error ("Unknown video mode: %d\n", modenum);
//nomodecheck = false;
return 0;
}
}
pnewmode = VID_GetModePtr (modenum);
if (pnewmode == pcurrentmode)
return 1; // already in the desired mode
// initialize the new mode
poldmode = pcurrentmode;
pcurrentmode = pnewmode;
// initialize vidbuffer size for setmode
vid.width = pcurrentmode->width;
vid.height = pcurrentmode->height;
//vid.aspect = pcurrentmode->aspect;
vid.rowbytes = pcurrentmode->rowbytes;
vid.bpp = pcurrentmode->bytesperpixel;
//debug
//if (vid.rowbytes != vid.width)
// I_Error("vidrowbytes (%d) <> vidwidth(%d)\n",vid.rowbytes,vid.width);
vstat = (*pcurrentmode->setmode) (&vid, pcurrentmode);
if (vstat < 1)
{
if (vstat == 0)
{
// harware could not setup mode
//if (!VID_SetMode (vid.modenum))
// I_Error ("VID_SetMode: couldn't set video mode (hard failure)");
I_Error("Couldn't set video mode %d\n", modenum);
}
else
if (vstat == -1)
{
CONS_Printf ("Not enough mem for VID_SetMode...\n");
// not enough memory; just put things back the way they were
pcurrentmode = poldmode;
vid.width = pcurrentmode->width;
vid.height = pcurrentmode->height;
vid.rowbytes = pcurrentmode->rowbytes;
vid.bpp = pcurrentmode->bytesperpixel;
return 0;
}
}
vid.modenum = modenum;
//printf ("%s\n", VID_ModeInfo (vid.modenum, NULL));
//added:20-01-98: recalc all tables and realloc buffers based on
// vid values.
vid.recalc = 1;
if (!cv_stretch.value && (float)vid.width/vid.height != ((float)BASEVIDWIDTH/BASEVIDHEIGHT))
vid.height = (int)(vid.width * ((float)BASEVIDHEIGHT/BASEVIDWIDTH));// Adjust the height to match
return 1;
}
void VID_CheckRenderer(void)
{
// ..............
}
// converts a segm:offs 32bit pair to a 32bit flat ptr
#if 0
void *VID_ExtraFarToLinear (void *ptr)
{
int temp;
temp = (int)ptr;
return real2ptr (((temp & 0xFFFF0000) >> 12) + (temp & 0xFFFF));
}
#endif
// ========================================================================
// Helper function for VID_VesaGetExtraModes
// In: vesa mode number, from the vesa videomodenumbers list
// Out: false, if no info for given modenum
// ========================================================================
int VID_VesaGetModeInfo (int modenum)
{
int bytes_per_pixel;
unsigned int i;
__dpmi_regs regs;
for (i=0; i<sizeof (vesamodeinfo_t); i++)
_farpokeb(_dos_ds, MASK_LINEAR(__tb)+i, 0);
regs.x.ax = 0x4f01;
regs.x.di = RM_OFFSET(__tb);
regs.x.es = RM_SEGMENT(__tb);
regs.x.cx = modenum;
__dpmi_int(0x10, &regs);
if (regs.h.ah)
return false;
else
{
dosmemget (MASK_LINEAR(__tb), sizeof (vesamodeinfo_t), &vesamodeinfo);
bytes_per_pixel = (vesamodeinfo.BitsPerPixel+1)/8;
// we add either highcolor or lowcolor video modes, not the two
if (highcolor && (vesamodeinfo.BitsPerPixel != 15))
return false;
if (!highcolor && (vesamodeinfo.BitsPerPixel != 8))
return false;
if ((bytes_per_pixel > 2) ||
(vesamodeinfo.XResolution > MAXVIDWIDTH) ||
(vesamodeinfo.YResolution > MAXVIDHEIGHT))
{
return false;
}
// we only want color graphics modes that are supported by the hardware
if ((vesamodeinfo.ModeAttributes &
(MODE_SUPPORTED_IN_HW | COLOR_MODE | GRAPHICS_MODE) ) !=
(MODE_SUPPORTED_IN_HW | COLOR_MODE | GRAPHICS_MODE))
{
return false;
}
// we only work with linear frame buffers, except for 320x200,
// which is linear when banked at 0xA000
if (!(vesamodeinfo.ModeAttributes & LINEAR_FRAME_BUFFER))
{
if ((vesamodeinfo.XResolution != 320) ||
(vesamodeinfo.YResolution != 200))
{
return false;
}
}
// pagesize
if ((vesamodeinfo.BytesPerScanLine * vesamodeinfo.YResolution)
> totalvidmem)
{
return false;
}
vesamodeinfo.NumberOfImagePages = 1;
#ifdef DEBUG
CONS_Printf("VID: (VESA) info for mode 0x%x\n", modeinfo.modenum);
CONS_Printf(" mode attrib = 0x%0x\n", modeinfo.mode_attributes);
CONS_Printf(" win a attrib = 0x%0x\n", *(UINT8 *)(infobuf+2));
CONS_Printf(" win b attrib = 0x%0x\n", *(UINT8 *)(infobuf+3));
CONS_Printf(" win a seg 0x%0x\n", (int) modeinfo.winasegment);
CONS_Printf(" win b seg 0x%0x\n", (int) modeinfo.winbsegment);
CONS_Printf(" bytes per scanline = %d\n",
modeinfo.bytes_per_scanline);
CONS_Printf(" width = %d, height = %d\n", modeinfo.width,
modeinfo.height);
CONS_Printf(" win = %c\n", 'A' + modeinfo.win);
CONS_Printf(" win granularity = %d\n", modeinfo.granularity);
CONS_Printf(" win size = %d\n", modeinfo.win_size);
CONS_Printf(" bits per pixel = %d\n", modeinfo.bits_per_pixel);
CONS_Printf(" bytes per pixel = %d\n", modeinfo.bytes_per_pixel);
CONS_Printf(" memory model = 0x%x\n", modeinfo.memory_model);
CONS_Printf(" num pages = %d\n", modeinfo.num_pages);
CONS_Printf(" red width = %d\n", modeinfo.red_width);
CONS_Printf(" red pos = %d\n", modeinfo.red_pos);
CONS_Printf(" green width = %d\n", modeinfo.green_width);
CONS_Printf(" green pos = %d\n", modeinfo.green_pos);
CONS_Printf(" blue width = %d\n", modeinfo.blue_width);
CONS_Printf(" blue pos = %d\n", modeinfo.blue_pos);
CONS_Printf(" phys mem = %x\n", modeinfo.pptr);
#endif
}
return true;
}
// ========================================================================
// Get extended VESA modes information, keep the ones that we support,
// so they'll be available in the game Video menu.
// ========================================================================
#define MAXVESADESC 100
static char vesadesc[MAXVESADESC] = "";
void VID_VesaGetExtraModes (void)
{
unsigned int i;
unsigned long addr;
int nummodes;
__dpmi_meminfo phys_mem_info;
unsigned long mode_ptr;
__dpmi_regs regs;
// make a copy of the video modes list! else trash in __tb
UINT16 vmode[MAX_VESA_MODES+1];
int numvmodes;
UINT16 vesamode;
// new ugly stuff...
for (i=0; i<sizeof (vbeinfoblock_t); i++)
_farpokeb(_dos_ds, MASK_LINEAR(__tb)+i, 0);
dosmemput("VBE2", 4, MASK_LINEAR(__tb));
// see if VESA support is available
regs.x.ax = 0x4f00;
regs.x.di = RM_OFFSET(__tb);
regs.x.es = RM_SEGMENT(__tb);
__dpmi_int(0x10, &regs);
if (regs.h.ah)
goto no_vesa;
dosmemget(MASK_LINEAR(__tb), sizeof (vbeinfoblock_t), &vesainfo);
if (strncmp((void *)vesainfo.VESASignature, "VESA", 4) != 0)
{
no_vesa:
CONS_Printf ("No VESA driver\n");
return;
}
if (vesainfo.VESAVersion < (VBEVERSION<<8))
{
CONS_Printf ("VESA VBE %d.0 not available\n", VBEVERSION);
return;
}
//
// vesa version number
//
CONS_Printf ("%4.4s %d.%d (", vesainfo.VESASignature,
vesainfo.VESAVersion>>8,
vesainfo.VESAVersion&0xFF);
//
// vesa description string
//
i = 0;
addr = RM_TO_LINEAR(vesainfo.OemStringPtr);
_farsetsel(_dos_ds);
while (_farnspeekb(addr) != 0)
{
vesadesc[i++] = _farnspeekb(addr++);
if (i == MAXVESADESC-1)
break;
}
vesadesc[i]=0;
CONS_Printf ("%s)\n",vesadesc);
totalvidmem = vesainfo.TotalMemory << 16;
//
// find 8 bit modes
//
numvmodes = 0;
mode_ptr = RM_TO_LINEAR(vesainfo.VideoModePtr);
while ((vmode[numvmodes] = _farpeekw(_dos_ds, mode_ptr)) != 0xFFFF)
{
numvmodes++;
if ( numvmodes == MAX_VESA_MODES )
break;
mode_ptr += 2;
}
vmode[numvmodes] = 0xffff;
nummodes = 0; // number of video modes accepted for the game
numvmodes=0; // go again through vmodes table
while ( ((vesamode=vmode[numvmodes++]) != 0xFFFF) && (nummodes < MAX_VESA_MODES) )
{
//fill the modeinfo struct.
if (VID_VesaGetModeInfo (vesamode))
{
vesa_modes[nummodes].pnext = &vesa_modes[nummodes+1];
if (vesamodeinfo.XResolution > 999)
{
if (vesamodeinfo.YResolution > 999)
{
sprintf (&names[nummodes][0], "%4dx%4d", vesamodeinfo.XResolution,
vesamodeinfo.YResolution);
names[nummodes][9] = 0;
}
else
{
sprintf (&names[nummodes][0], "%4dx%3d", vesamodeinfo.XResolution,
vesamodeinfo.YResolution);
names[nummodes][8] = 0;
}
}
else
{
if (vesamodeinfo.YResolution > 999)
{
sprintf (&names[nummodes][0], "%3dx%4d", vesamodeinfo.XResolution,
vesamodeinfo.YResolution);
names[nummodes][8] = 0;
}
else
{
sprintf (&names[nummodes][0], "%3dx%3d", vesamodeinfo.XResolution,
vesamodeinfo.YResolution);
names[nummodes][7] = 0;
}
}
vesa_modes[nummodes].name = &names[nummodes][0];
vesa_modes[nummodes].width = vesamodeinfo.XResolution;
vesa_modes[nummodes].height = vesamodeinfo.YResolution;
//added:20-01-98:aspect ratio to be implemented...
vesa_modes[nummodes].rowbytes = vesamodeinfo.BytesPerScanLine;
vesa_modes[nummodes].windowed = 0;
vesa_modes[nummodes].pextradata = &vesa_extra[nummodes];
vesa_modes[nummodes].setmode = VID_VesaInitMode;
if (vesamodeinfo.ModeAttributes & LINEAR_FRAME_BUFFER)
{
// add linear bit to mode for linear modes
vesa_extra[nummodes].vesamode = vesamode | LINEAR_MODE;
vesa_modes[nummodes].numpages = 1; //vesamodeinfo.NumberOfImagePages;
phys_mem_info.address = (int)vesamodeinfo.PhysBasePtr;
phys_mem_info.size = 0x400000;
// returns -1 on error
if (__dpmi_physical_address_mapping(&phys_mem_info))
{
//skip this mode, it doesnt work
continue;
}
// if physical mapping was ok... convert the selector:offset
vesa_extra[nummodes].plinearmem =
real2ptr (phys_mem_info.address);
// lock the region
__dpmi_lock_linear_region (&phys_mem_info);
}
else
{
// banked at 0xA0000
vesa_extra[nummodes].vesamode = vesamode;
//vesa_extra[nummodes].pages[0] = 0;
vesa_extra[nummodes].plinearmem =
real2ptr (vesamodeinfo.WinASegment<<4);
vesa_modes[nummodes].numpages = 1; //modeinfo.numpages;
}
vesa_modes[nummodes].bytesperpixel = (vesamodeinfo.BitsPerPixel+1)/8;
nummodes++;
}
}
// add the VESA modes at the start of the mode list (if there are any)
if (nummodes)
{
vesa_modes[nummodes-1].pnext = NULL; //pvidmodes;
pvidmodes = &vesa_modes[0];
numvidmodes += nummodes;
}
}
// ========================================================================
// Free the video buffer of the last video mode,
// allocate a new buffer for the video mode to set.
// ========================================================================
static boolean VID_FreeAndAllocVidbuffer (viddef_t *lvid)
{
int vidbuffersize;
vidbuffersize = (lvid->width * lvid->height * lvid->bpp * NUMSCREENS); //status bar
// free allocated buffer for previous video mode
if (lvid->buffer!=NULL)
{
free(lvid->buffer);
}
// allocate the new screen buffer
if ( (lvid->buffer = (UINT8 *) malloc(vidbuffersize))==NULL )
return false;
// initially clear the video buffer
memset (lvid->buffer, 0x00, vidbuffersize);
#ifdef DEBUG
CONS_Printf("VID_FreeAndAllocVidbuffer done, vidbuffersize: %x\n",vidbuffersize);
#endif
return true;
}
// ========================================================================
// Set video mode routine for STANDARD VGA MODES (NO HIGHCOLOR)
// Out: 1 ok,
// 0 hardware could not set mode,
// -1 no mem
// ========================================================================
static INT32 VGA_InitMode (viddef_t *lvid, vmode_t *currentmodep)
{
__dpmi_regs regs;
if (!VID_FreeAndAllocVidbuffer (lvid))
return -1; //no mem
//added:26-01-98: should clear video mem here
//set mode 0x13
regs.h.ah = 0;
regs.h.al = 0x13;
__dpmi_int(0x10, &regs);
// here it is the standard VGA 64k window, not an LFB
// (you could have 320x200x256c with LFB in the vesa modes)
lvid->direct = (UINT8 *) real2ptr (0xa0000);
lvid->u.numpages = 1;
lvid->bpp = currentmodep->bytesperpixel;
return 1;
}
// ========================================================================
// Set video mode routine for VESA video modes, see VID_SetMode()
// Out: 1 ok,
// 0 hardware could not set mode,
// -1 no mem
// ========================================================================
INT32 VID_VesaInitMode (viddef_t *lvid, vmode_t *currentmodep)
{
vesa_extra_t *pextra;
__dpmi_regs regs;
pextra = currentmodep->pextradata;
#ifdef DEBUG
CONS_Printf("VID_VesaInitMode...\n");
CONS_Printf(" currentmodep->name %s\n",currentmodep->name);
CONS_Printf(" width %d\n",currentmodep->width);
CONS_Printf(" height %d\n",currentmodep->height);
CONS_Printf(" rowbytes %d\n",currentmodep->rowbytes);
CONS_Printf(" windowed %d\n",currentmodep->windowed);
CONS_Printf(" numpages %d\n",currentmodep->numpages);
CONS_Printf(" currentmodep->pextradata :\n");
CONS_Printf(" ->vesamode %x\n",pextra->vesamode);
CONS_Printf(" ->plinearmem %x\n\n",pextra->plinearmem);
#endif
//added:20-01-98:no page flipping now... TO DO!!!
lvid->u.numpages = 1;
// clean up any old vid buffer lying around, alloc new if needed
if (!VID_FreeAndAllocVidbuffer (lvid))
return -1; //no mem
//added:20-01-98: should clear video mem here
// set the mode
regs.x.ax = 0x4f02;
regs.x.bx = pextra->vesamode;
__dpmi_int (0x10, &regs);
if (regs.x.ax != 0x4f)
return 0; // could not set mode
//added:20-01-98: should setup wait_vsync flag, currentpage here...
// plus check for display_enable bit
//added:20-01-98: here we should set the page if page flipping...
// points to LFB, or the start of VGA mem.
lvid->direct = pextra->plinearmem;
lvid->bpp = currentmodep->bytesperpixel;
return 1;
}
// ========================================================================
// VIDEO MODE CONSOLE COMMANDS
// ========================================================================
// vid_nummodes
//
//added:21-03-98:
void VID_Command_NumModes_f (void)
{
int nummodes;
nummodes = VID_NumModes ();
CONS_Printf ("%d video mode(s) available(s)\n", nummodes);
}
// vid_modeinfo <modenum>
//
void VID_Command_ModeInfo_f (void)
{
vmode_t *pv;
int modenum;
if (COM_Argc()!=2)
modenum = vid.modenum; // describe the current mode
else
modenum = atoi (COM_Argv(1)); // .. the given mode number
if (modenum >= VID_NumModes())
{
CONS_Printf ("No such video mode\n");
return;
}
pv = VID_GetModePtr (modenum);
CONS_Printf ("%s\n", VID_ModeInfo (modenum, NULL));
CONS_Printf ("width : %d\n"
"height: %d\n"
"bytes per scanline: %d\n"
"bytes per pixel: %d\n"
"numpages: %d\n",
pv->width,
pv->height,
pv->rowbytes,
pv->bytesperpixel,
pv->numpages );
}
// vid_modelist
//
void VID_Command_ModeList_f (void)
{
int i, nummodes;
const char *pinfo;
char *pheader;
vmode_t *pv;
boolean na;
na = false;
nummodes = VID_NumModes ();
for (i=0 ; i<nummodes ; i++)
{
pv = VID_GetModePtr (i);
pinfo = VID_ModeInfo (i, &pheader);
if (i==0 || pv->bytesperpixel==1)
CONS_Printf ("%d: %s\n", i, pinfo);
else
CONS_Printf ("%d: %s (hicolor)\n", i, pinfo);
}
}
// vid_mode <modenum>
//
void VID_Command_Mode_f (void)
{
int modenum;
if (COM_Argc()!=2)
{
CONS_Printf ("vid_mode <modenum> : set video mode\n");
return;
}
modenum = atoi(COM_Argv(1));
if (modenum >= VID_NumModes())
CONS_Printf ("No such video mode\n");
else
// request vid mode change
setmodeneeded = modenum+1;
}

View file

@ -1,109 +0,0 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// Copyright (C) 1998-2000 by DooM Legacy Team.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//-----------------------------------------------------------------------------
/// \file
/// \brief VESA extra modes.
#include "../doomdef.h"
#include "../screen.h"
#define MODE_SUPPORTED_IN_HW 0x0001
#define COLOR_MODE 0x0008
#define GRAPHICS_MODE 0x0010
#define VGA_INCOMPATIBLE 0x0020
#define LINEAR_FRAME_BUFFER 0x0080
#define LINEAR_MODE 0x4000
#define MAX_VESA_MODES 30 // we'll just take the first 30 if there
// VESA information block structure
typedef struct vbeinfoblock_s
{
UINT8 VESASignature[4];
UINT16 VESAVersion;
unsigned long OemStringPtr;
UINT8 Capabilities[4];
unsigned long VideoModePtr;
UINT16 TotalMemory;
UINT8 OemSoftwareRev[2];
UINT8 OemVendorNamePtr[4];
UINT8 OemProductNamePtr[4];
UINT8 OemProductRevPtr[4];
UINT8 Reserved[222];
UINT8 OemData[256];
} ATTRPACK vbeinfoblock_t;
// VESA information for a specific mode
typedef struct vesamodeinfo_s
{
UINT16 ModeAttributes;
UINT8 WinAAttributes;
UINT8 WinBAttributes;
UINT16 WinGranularity;
UINT16 WinSize;
UINT16 WinASegment;
UINT16 WinBSegment;
unsigned long WinFuncPtr;
UINT16 BytesPerScanLine;
UINT16 XResolution;
UINT16 YResolution;
UINT8 XCharSize;
UINT8 YCharSize;
UINT8 NumberOfPlanes;
UINT8 BitsPerPixel;
UINT8 NumberOfBanks;
UINT8 MemoryModel;
UINT8 BankSize;
UINT8 NumberOfImagePages;
UINT8 Reserved_page;
UINT8 RedMaskSize;
UINT8 RedMaskPos;
UINT8 GreenMaskSize;
UINT8 GreenMaskPos;
UINT8 BlueMaskSize;
UINT8 BlueMaskPos;
UINT8 ReservedMaskSize;
UINT8 ReservedMaskPos;
UINT8 DirectColorModeInfo;
/* VBE 2.0 extensions */
unsigned long PhysBasePtr;
unsigned long OffScreenMemOffset;
UINT16 OffScreenMemSize;
/* VBE 3.0 extensions */
UINT16 LinBytesPerScanLine;
UINT8 BnkNumberOfPages;
UINT8 LinNumberOfPages;
UINT8 LinRedMaskSize;
UINT8 LinRedFieldPos;
UINT8 LinGreenMaskSize;
UINT8 LinGreenFieldPos;
UINT8 LinBlueMaskSize;
UINT8 LinBlueFieldPos;
UINT8 LinRsvdMaskSize;
UINT8 LinRsvdFieldPos;
unsigned long MaxPixelClock;
UINT8 Reserved[190];
} ATTRPACK vesamodeinfo_t;
// setup standard VGA + VESA modes list, activate the default video mode.
void VID_Init (void);

View file

@ -23,6 +23,8 @@
// Some global defines, that configure the game.
#include "doomdef.h"
#include "m_fixed.h" // See the mapthing_t scale.
//
// Map level types.
// The following data structures define the persistent format
@ -193,25 +195,29 @@ typedef struct
#pragma pack()
#endif
#define NUMMAPTHINGARGS 6
#define NUMMAPTHINGSTRINGARGS 2
// Thing definition, position, orientation and type,
// plus visibility flags and attributes.
typedef struct
{
INT16 x, y;
INT16 angle;
INT16 angle, pitch, roll;
UINT16 type;
UINT16 options;
INT16 z;
UINT8 extrainfo;
fixed_t scale;
INT16 tag;
INT32 args[NUMMAPTHINGARGS];
char *stringargs[NUMMAPTHINGSTRINGARGS];
struct mobj_s *mobj;
} mapthing_t;
#define ZSHIFT 4
extern const UINT8 Color_Index[MAXTRANSLATIONS-1][16];
extern const char *Color_Names[MAXSKINCOLORS + NUMSUPERCOLORS];
extern const UINT8 Color_Opposite[MAXSKINCOLORS - 1][2];
#define NUMMAPS 1035
#endif // __DOOMDATA__

View file

@ -86,6 +86,7 @@
// warning C4213: nonstandard extension used : cast on l-value
#include "version.h"
#include "doomtype.h"
#include <stdarg.h>
@ -109,10 +110,6 @@
#include <io.h>
#endif
#ifdef PC_DOS
#include <conio.h>
#endif
//#define NOMD5
// Uncheck this to compile debugging code
@ -135,21 +132,20 @@ extern char logfilename[1024];
//#define DEVELOP // Disable this for release builds to remove excessive cheat commands and enable MD5 checking and stuff, all in one go. :3
#ifdef DEVELOP
#define VERSION 0 // Game version
#define SUBVERSION 0 // more precise version number
#define VERSIONSTRING "Development EXE"
#define VERSIONSTRINGW L"Development EXE"
// most interface strings are ignored in development mode.
// we use comprevision and compbranch instead.
#else
#define VERSION 202 // Game version
#define SUBVERSION 2 // more precise version number
#define VERSIONSTRING "v2.2.2"
#define VERSIONSTRINGW L"v2.2.2"
#define VERSIONSTRING "v"SRB2VERSION
// Hey! If you change this, add 1 to the MODVERSION below!
// Otherwise we can't force updates!
#endif
#define VERSIONSTRINGW WSTRING (VERSIONSTRING)
/* A custom URL protocol for server links. */
#define SERVER_URL_PROTOCOL "srb2://"
// Does this version require an added patch file?
// Comment or uncomment this as necessary.
#define USE_PATCH_DTA
@ -201,17 +197,6 @@ extern char logfilename[1024];
// Will always resemble the versionstring, 205 = 2.0.5, 210 = 2.1, etc.
#define CODEBASE 220
// The Modification ID; must be obtained from Rob ( https://mb.srb2.org/private.php?do=newpm&u=546 ).
// DO NOT try to set this otherwise, or your modification will be unplayable through the Master Server.
// "18" is the default mod ID for version 2.2
#define MODID 18
// The Modification Version, starting from 1. Do not follow your version string for this,
// it's only for detection of the version the player is using so the MS can alert them of an update.
// Only set it higher, not lower, obviously.
// Note that we use this to help keep internal testing in check; this is why v2.2.0 is not version "1".
#define MODVERSION 42
// To version config.cfg, MAJOREXECVERSION is set equal to MODVERSION automatically.
// Increment MINOREXECVERSION whenever a config change is needed that does not correspond
// to an increment in MODVERSION. This might never happen in practice.
@ -236,6 +221,20 @@ extern char logfilename[1024];
#define PLAYERSMASK (MAXPLAYERS-1)
#define MAXPLAYERNAME 21
#define COLORRAMPSIZE 16
#define MAXCOLORNAME 32
#define NUMCOLORFREESLOTS 1024
typedef struct skincolor_s
{
char name[MAXCOLORNAME+1]; // Skincolor name
UINT8 ramp[COLORRAMPSIZE]; // Colormap ramp
UINT16 invcolor; // Signpost color
UINT8 invshade; // Signpost color shade
UINT16 chatcolor; // Chat color
boolean accessible; // Accessible by the color command + setup menu
} skincolor_t;
typedef enum
{
SKINCOLOR_NONE = 0,
@ -314,12 +313,10 @@ typedef enum
SKINCOLOR_RASPBERRY,
SKINCOLOR_ROSY,
// SKINCOLOR_? - one left before we bump up against 0x39, which isn't a HARD limit anymore but would be excessive
MAXSKINCOLORS,
FIRSTSUPERCOLOR,
// Super special awesome Super flashing colors!
SKINCOLOR_SUPERSILVER1 = MAXSKINCOLORS,
SKINCOLOR_SUPERSILVER1 = FIRSTSUPERCOLOR,
SKINCOLOR_SUPERSILVER2,
SKINCOLOR_SUPERSILVER3,
SKINCOLOR_SUPERSILVER4,
@ -373,9 +370,17 @@ typedef enum
SKINCOLOR_SUPERTAN4,
SKINCOLOR_SUPERTAN5,
MAXTRANSLATIONS,
NUMSUPERCOLORS = ((MAXTRANSLATIONS - MAXSKINCOLORS)/5)
} skincolors_t;
SKINCOLOR_FIRSTFREESLOT,
SKINCOLOR_LASTFREESLOT = SKINCOLOR_FIRSTFREESLOT + NUMCOLORFREESLOTS - 1,
MAXSKINCOLORS,
NUMSUPERCOLORS = ((SKINCOLOR_FIRSTFREESLOT - FIRSTSUPERCOLOR)/5)
} skincolornum_t;
extern UINT16 numskincolors;
extern skincolor_t skincolors[MAXSKINCOLORS];
// State updates, number of tics / second.
// NOTE: used to setup the timer rate, see I_StartupTimer().
@ -455,7 +460,8 @@ void CONS_Debug(INT32 debugflags, const char *fmt, ...) FUNCDEBUG;
// Things that used to be in dstrings.h
#define SAVEGAMENAME "srb2sav"
char savegamename[256];
extern char savegamename[256];
extern char liveeventbackup[256];
// m_misc.h
#ifdef GETTEXT
@ -479,6 +485,8 @@ char *sizeu4(size_t num);
char *sizeu5(size_t num);
// d_main.c
extern int VERSION;
extern int SUBVERSION;
extern boolean devparm; // development mode (-debug)
// d_netcmd.c
extern INT32 cv_debug;
@ -546,8 +554,8 @@ INT32 I_GetKey(void);
#endif
// The character that separates pathnames. Forward slash on
// most systems, but reverse solidus (\) on Windows and DOS.
#if defined (PC_DOS) || defined (_WIN32)
// most systems, but reverse solidus (\) on Windows.
#if defined (_WIN32)
#define PATHSEP "\\"
#else
#define PATHSEP "/"
@ -562,15 +570,6 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
// None of these that are disabled in the normal build are guaranteed to work perfectly
// Compile them at your own risk!
/// Kalaron/Eternity Engine slope code (SRB2CB ported)
#define ESLOPE
#ifdef ESLOPE
/// Backwards compatibility with SRB2CB's slope linedef types.
/// \note A simple shim that prints a warning.
#define ESLOPE_TYPESHIM
#endif
/// Allows the use of devmode in multiplayer. AKA "fishcake"
//#define NETGAME_DEVMODE
@ -580,9 +579,6 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
/// Dumps the contents of a network save game upon consistency failure for debugging.
//#define DUMPCONSISTENCY
/// Polyobject fake flat code
#define POLYOBJECTS_PLANES
/// See name of player in your crosshair
#define SEENAMES
@ -605,11 +601,6 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
/// memory that never gets touched.
#define ALLOW_RESETDATA
#ifndef NONET
/// Display a connection screen on join attempts.
#define CLIENT_LOADINGSCREEN
#endif
/// Experimental tweaks to analog mode. (Needs a lot of work before it's ready for primetime.)
//#define REDSANALOG
@ -627,17 +618,13 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
/// SRB2CB itself ported this from PrBoom+
#define NEWCLIP
/// OpenGL shaders
#define GL_SHADERS
/// Handle touching sector specials in P_PlayerAfterThink instead of P_PlayerThink.
/// \note Required for proper collision with moving sloped surfaces that have sector specials on them.
#define SECTORSPECIALSAFTERTHINK
/// FINALLY some real clipping that doesn't make walls dissappear AND speeds the game up
/// (that was the original comment from SRB2CB, sadly it is a lie and actually slows game down)
/// on the bright side it fixes some weird issues with translucent walls
/// \note SRB2CB port.
/// SRB2CB itself ported this from PrBoom+
#define NEWCLIP
/// Cache patches in Lua in a way that renderer switching will work flawlessly.
//#define LUA_PATCH_SAFETY
@ -654,4 +641,7 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
/// Render flats on walls
#define WALLFLATS
/// Maintain compatibility with older 2.2 demos
#define OLD22DEMOCOMPAT
#endif // __DOOMDEF__

View file

@ -45,7 +45,19 @@ extern INT32 curWeather;
extern INT32 cursaveslot;
//extern INT16 lastmapsaved;
extern INT16 lastmaploaded;
extern boolean gamecomplete;
extern UINT8 gamecomplete;
// Extra abilities/settings for skins (combinable stuff)
typedef enum
{
MA_RUNNING = 1, // In action
MA_INIT = 1<<1, // Initialisation
MA_NOCUTSCENES = 1<<2, // No cutscenes
MA_INGAME = 1<<3 // Timer ignores loads
} marathonmode_t;
extern marathonmode_t marathonmode;
extern tic_t marathontime;
#define maxgameovers 13
extern UINT8 numgameovers;
@ -127,7 +139,7 @@ extern INT32 displayplayer;
extern INT32 secondarydisplayplayer; // for splitscreen
// Maps of special importance
extern INT16 spstage_start;
extern INT16 spstage_start, spmarathon_start;
extern INT16 sstage_start, sstage_end, smpstage_start, smpstage_end;
extern INT16 titlemap;
@ -145,7 +157,7 @@ extern INT32 tutorialanalog; // store cv_analog[0] user value
extern boolean looptitle;
// CTF colors.
extern UINT8 skincolor_redteam, skincolor_blueteam, skincolor_redring, skincolor_bluering;
extern UINT16 skincolor_redteam, skincolor_blueteam, skincolor_redring, skincolor_bluering;
extern tic_t countdowntimer;
extern boolean countdowntimeup;
@ -289,6 +301,7 @@ typedef struct
UINT8 actnum; ///< Act number or 0 for none.
UINT32 typeoflevel; ///< Combination of typeoflevel flags.
INT16 nextlevel; ///< Map number of next level, or 1100-1102 to end.
INT16 marathonnext; ///< See nextlevel, but for Marathon mode. Necessary to support hub worlds ala SUGOI.
char keywords[33]; ///< Keywords separated by space to search for. 32 characters.
char musname[7]; ///< Music track to play. "" for no music.
UINT16 mustrack; ///< Subsong to play. Only really relevant for music modules and specific formats supported by GME. 0 to ignore.
@ -319,6 +332,9 @@ typedef struct
char selectheading[22]; ///< Level select heading. Allows for controllable grouping.
UINT16 startrings; ///< Number of rings players start with.
INT32 sstimer; ///< Timer for special stages.
UINT32 ssspheres; ///< Sphere requirement in special stages.
fixed_t gravity; ///< Map-wide gravity.
// Title card.
char ltzzpatch[8]; ///< Zig zag patch.
@ -493,7 +509,6 @@ extern UINT16 emeralds;
#define EMERALD7 64
#define ALL7EMERALDS(v) ((v & (EMERALD1|EMERALD2|EMERALD3|EMERALD4|EMERALD5|EMERALD6|EMERALD7)) == (EMERALD1|EMERALD2|EMERALD3|EMERALD4|EMERALD5|EMERALD6|EMERALD7))
// yes, even in non HAVE_BLUA
#define NUM_LUABANKS 16 // please only make this number go up between versions, never down. you'll break saves otherwise. also, must fit in UINT8
extern INT32 luabanks[NUM_LUABANKS];
@ -543,7 +558,7 @@ extern recorddata_t *mainrecords[NUMMAPS];
extern UINT8 mapvisited[NUMMAPS];
// Temporary holding place for nights data for the current map
nightsdata_t ntemprecords;
extern nightsdata_t ntemprecords;
extern UINT32 token; ///< Number of tokens collected in a level
extern UINT32 tokenlist; ///< List of tokens collected
@ -573,9 +588,12 @@ extern UINT16 nightslinktics;
extern UINT8 introtoplay;
extern UINT8 creditscutscene;
extern UINT8 useBlackRock;
extern UINT8 use1upSound;
extern UINT8 maxXtraLife; // Max extra lives from rings
extern UINT8 useContinues;
#define continuesInSession (!multiplayer && (ultimatemode || (useContinues && !marathonmode) || (!modeattacking && !(cursaveslot > 0))))
extern mobj_t *hunt1, *hunt2, *hunt3; // Emerald hunt locations
@ -616,6 +634,19 @@ extern mapthing_t *playerstarts[MAXPLAYERS]; // Cooperative
extern mapthing_t *bluectfstarts[MAXPLAYERS]; // CTF
extern mapthing_t *redctfstarts[MAXPLAYERS]; // CTF
#define WAYPOINTSEQUENCESIZE 256
#define NUMWAYPOINTSEQUENCES 256
extern mobj_t *waypoints[NUMWAYPOINTSEQUENCES][WAYPOINTSEQUENCESIZE];
extern UINT16 numwaypoints[NUMWAYPOINTSEQUENCES];
void P_AddWaypoint(UINT8 sequence, UINT8 id, mobj_t *waypoint);
mobj_t *P_GetFirstWaypoint(UINT8 sequence);
mobj_t *P_GetLastWaypoint(UINT8 sequence);
mobj_t *P_GetPreviousWaypoint(mobj_t *current, boolean wrap);
mobj_t *P_GetNextWaypoint(mobj_t *current, boolean wrap);
mobj_t *P_GetClosestWaypoint(UINT8 sequence, mobj_t *mo);
boolean P_IsDegeneratedWaypointSequence(UINT8 sequence);
// =====================================
// Internal parameters, used for engine.
// =====================================

View file

@ -367,4 +367,8 @@ typedef UINT32 tic_t;
#define UINT2RGBA(a) (UINT32)((a&0xff)<<24)|((a&0xff00)<<8)|((a&0xff0000)>>8)|(((UINT32)a&0xff000000)>>24)
#endif
/* preprocessor dumb and needs second macro to expand input */
#define WSTRING2(s) L ## s
#define WSTRING(s) WSTRING2 (s)
#endif //__DOOMTYPE__

View file

@ -16,6 +16,11 @@ tic_t I_GetTime(void)
return 0;
}
int I_GetTimeMicros(void)
{
return 0;
}
void I_Sleep(void){}
void I_GetEvent(void){}

View file

@ -11,10 +11,10 @@ boolean allow_fullscreen = false;
consvar_t cv_vidwait = {"vid_wait", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
void I_StartupGraphics(void){}
void I_StartupHardwareGraphics(void){}
void I_ShutdownGraphics(void){}
void VID_StartupOpenGL(void){}
void I_SetPalette(RGBA_t *palette)
{
(void)palette;
@ -40,10 +40,8 @@ INT32 VID_SetMode(INT32 modenum)
return 0;
}
void VID_CheckRenderer(void)
{
// ..............
}
void VID_CheckRenderer(void) {}
void VID_CheckGLLoaded(rendermode_t oldrender) {}
const char *VID_GetModeName(INT32 modenum)
{

View file

@ -25,6 +25,7 @@
#include "w_wad.h"
#include "z_zone.h"
#include "i_system.h"
#include "i_threads.h"
#include "m_menu.h"
#include "dehacked.h"
#include "g_input.h"
@ -39,9 +40,7 @@
#include "fastcmp.h"
#include "console.h"
#ifdef HAVE_BLUA
#include "lua_hud.h"
#endif
// Stage of animation:
// 0 = text, 1 = art screen
@ -961,7 +960,13 @@ void F_IntroDrawer(void)
I_OsPolling();
I_UpdateNoBlit();
#ifdef HAVE_THREADS
I_lock_mutex(&m_menu_mutex);
#endif
M_Drawer(); // menu is drawn even on top of wipes
#ifdef HAVE_THREADS
I_unlock_mutex(m_menu_mutex);
#endif
I_FinishUpdate(); // Update the screen with the image Tails 06-19-2001
if (moviemode) // make sure we save frames for the white hold too
@ -1120,9 +1125,6 @@ static const char *credits[] = {
"\1Sonic Robo Blast II",
"\1Credits",
"",
"\1Producer",
"Rob Tisdell",
"",
"\1Game Design",
"Ben \"Mystic\" Geyer",
"\"SSNTails\"",
@ -1153,11 +1155,13 @@ static const char *credits[] = {
"",
"\1Programming",
"\1Assistance",
"Colette \"fickleheart\" Bordelon",
"\"chi.miru\"", // helped port slope drawing code from ZDoom
"Andrew \"orospakr\" Clunis",
"Sally \"TehRealSalt\" Cochenour",
"Gregor \"Oogaland\" Dick",
"Julio \"Chaos Zero 64\" Guir",
"\"Hannu_Hanhi\"", // For many OpenGL performance improvements!
"\"Kalaron\"", // Coded some of Sryder13's collection of OpenGL fixes, especially fog
"\"Lat'\"", // SRB2-CHAT, the chat window from Kart
"Matthew \"Shuffle\" Marsalko",
@ -1168,6 +1172,7 @@ static const char *credits[] = {
"Tasos \"tatokis\" Sahanidis", // Corrected C FixedMul, making 64-bit builds netplay compatible
"Wessel \"sphere\" Smit",
"Ben \"Cue\" Woodford",
"\"VelocitOni\"", // Wrote the original dashmode script
"Ikaro \"Tatsuru\" Vinhas",
// Git contributors with 5+ approved merges of substantive quality,
// or contributors with at least one groundbreaking merge, may be named.
@ -1176,6 +1181,7 @@ static const char *credits[] = {
"\1Art",
"Victor \"VAdaPEGA\" Ara\x1Fjo", // Araújo -- sorry for our limited font! D:
"Ryan \"Blaze Hedgehog\" Bloom",
"\"ChrispyPixels\"",
"Paul \"Boinciel\" Clempson",
"Sally \"TehRealSalt\" Cochenour",
"\"Dave Lite\"",
@ -1222,6 +1228,7 @@ static const char *credits[] = {
"\"SSNTails\"",
"",
"\1Level Design",
"Colette \"fickleheart\" Bordelon",
"Hank \"FuriousFox\" Brannock",
"Matthew \"Fawfulfan\" Chapman",
"Paul \"Boinciel\" Clempson",
@ -1257,6 +1264,7 @@ static const char *credits[] = {
"Johnny \"Sonikku\" Wallbank",
"",
"\1Testing",
"Discord Community Testers",
"Hank \"FuriousFox\" Brannock",
"Cody \"SRB2 Playah\" Koester",
"Skye \"OmegaVelocity\" Meredith",
@ -1332,10 +1340,6 @@ void F_StartCredits(void)
// Just in case they're open ... somehow
M_ClearMenus(true);
// Save the second we enter the credits
if ((!modifiedgame || savemoddata) && !(netgame || multiplayer) && cursaveslot > 0)
G_SaveGame((UINT32)cursaveslot);
if (creditscutscene)
{
F_StartCustomCutscene(creditscutscene - 1, false, false);
@ -1531,12 +1535,6 @@ void F_StartGameEvaluation(void)
// Just in case they're open ... somehow
M_ClearMenus(true);
// Save the second we enter the evaluation
// We need to do this again! Remember, it's possible a mod designed skipped
// the credits sequence!
if ((!modifiedgame || savemoddata) && !(netgame || multiplayer) && cursaveslot > 0)
G_SaveGame((UINT32)cursaveslot);
goodending = (ALL7EMERALDS(emeralds));
gameaction = ga_nothing;
@ -1553,13 +1551,20 @@ void F_GameEvaluationDrawer(void)
angle_t fa;
INT32 eemeralds_cur;
char patchname[7] = "CEMGx0";
const char* endingtext = (goodending ? "CONGRATULATIONS!" : "TRY AGAIN...");
const char* endingtext;
if (marathonmode)
endingtext = "THANKS FOR THE RUN!";
else if (goodending)
endingtext = "CONGRATULATIONS!";
else
endingtext = "TRY AGAIN...";
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
// Draw all the good crap here.
if (finalecount > 0)
if (finalecount > 0 && useBlackRock)
{
INT32 scale = FRACUNIT;
patch_t *rockpat;
@ -1676,6 +1681,18 @@ void F_GameEvaluationDrawer(void)
V_DrawString(8, 96, V_YELLOWMAP, "Modified games\ncan't unlock\nextras!");
}
#endif
if (marathonmode)
{
const char *rtatext, *cuttext;
rtatext = (marathonmode & MA_INGAME) ? "In-game timer" : "RTA timer";
cuttext = (marathonmode & MA_NOCUTSCENES) ? "" : " w/ cutscenes";
if (botskin)
endingtext = va("%s & %s, %s%s", skins[players[consoleplayer].skin].realname, skins[botskin-1].realname, rtatext, cuttext);
else
endingtext = va("%s, %s%s", skins[players[consoleplayer].skin].realname, rtatext, cuttext);
V_DrawCenteredString(BASEVIDWIDTH/2, 182, V_SNAPTOBOTTOM|(ultimatemode ? V_REDMAP : V_YELLOWMAP), endingtext);
}
}
void F_GameEvaluationTicker(void)
@ -1686,7 +1703,9 @@ void F_GameEvaluationTicker(void)
return;
}
if (!goodending)
if (!useBlackRock)
;
else if (!goodending)
{
if (sparklloop)
sparklloop--;
@ -1843,10 +1862,6 @@ void F_StartEnding(void)
// Just in case they're open ... somehow
M_ClearMenus(true);
// Save before the credits sequence.
if ((!modifiedgame || savemoddata) && !(netgame || multiplayer) && cursaveslot > 0)
G_SaveGame((UINT32)cursaveslot);
gameaction = ga_nothing;
paused = false;
CON_ToggleOff();
@ -2187,7 +2202,7 @@ void F_EndingDrawer(void)
for (i = 0; i < 7; ++i)
{
UINT8* colormap;
skincolors_t col = SKINCOLOR_GREEN;
skincolornum_t col = SKINCOLOR_GREEN;
switch (i)
{
case 1:
@ -2762,11 +2777,7 @@ void F_TitleScreenDrawer(void)
// rei|miru: use title pics?
hidepics = curhidepics;
if (hidepics)
#ifdef HAVE_BLUA
goto luahook;
#else
return;
#endif
switch(curttmode)
{
@ -3488,10 +3499,8 @@ void F_TitleScreenDrawer(void)
break;
}
#ifdef HAVE_BLUA
luahook:
LUAh_TitleHUD();
#endif
}
// separate animation timer for backgrounds, since we also count
@ -3626,7 +3635,7 @@ void F_StartContinue(void)
{
I_Assert(!netgame && !multiplayer);
if (players[consoleplayer].continues <= 0)
if (continuesInSession && players[consoleplayer].continues <= 0)
{
Command_ExitGame_f();
return;
@ -3733,7 +3742,9 @@ void F_ContinueDrawer(void)
}
// Draw the continue markers! Show continues.
if (ncontinues > 10)
if (!continuesInSession)
;
else if (ncontinues > 10)
{
if (!(continuetime & 1) || continuetime > 17)
V_DrawContinueIcon(x, 68, 0, players[consoleplayer].skin, players[consoleplayer].skincolor);
@ -3965,6 +3976,7 @@ static void F_AdvanceToNextScene(void)
animtimer = pictime = cutscenes[cutnum]->scene[scenenum].picduration[picnum];
}
// See also G_AfterIntermission, the only other place which handles intra-map/ending transitions
void F_EndCutScene(void)
{
cutsceneover = true; // do this first, just in case G_EndGame or something wants to turn it back false later
@ -4092,7 +4104,7 @@ void F_CutsceneTicker(void)
if (netgame && i != serverplayer && !IsPlayerAdmin(i))
continue;
if (players[i].cmd.buttons & BT_USE)
if (players[i].cmd.buttons & BT_SPIN)
{
keypressed = false;
cutscene_boostspeed = 1;
@ -4432,11 +4444,11 @@ static boolean F_GetTextPromptTutorialTag(char *tag, INT32 length)
else if (!strncmp(tag, "TAJ", 3)) // Jump
gcs = G_GetControlScheme(gamecontrol, gcl_jump, num_gcl_jump);
else if (!strncmp(tag, "TAS", 3)) // Spin
gcs = G_GetControlScheme(gamecontrol, gcl_use, num_gcl_use);
gcs = G_GetControlScheme(gamecontrol, gcl_spin, num_gcl_spin);
else if (!strncmp(tag, "TAA", 3)) // Char ability
gcs = G_GetControlScheme(gamecontrol, gcl_jump, num_gcl_jump);
else if (!strncmp(tag, "TAW", 3)) // Shield ability
gcs = G_GetControlScheme(gamecontrol, gcl_jump_use, num_gcl_jump_use);
gcs = G_GetControlScheme(gamecontrol, gcl_jump_spin, num_gcl_jump_spin);
else
gcs = G_GetControlScheme(gamecontrol, gcl_tutorial_used, num_gcl_tutorial_used);
@ -4693,7 +4705,7 @@ void F_TextPromptTicker(void)
else
continue;
if ((players[i].cmd.buttons & BT_USE) || (players[i].cmd.buttons & BT_JUMP))
if ((players[i].cmd.buttons & BT_SPIN) || (players[i].cmd.buttons & BT_JUMP))
{
if (timetonext > 1)
timetonext--;
@ -4716,7 +4728,7 @@ void F_TextPromptTicker(void)
}
keypressed = true; // prevent repeat events
}
else if (!(players[i].cmd.buttons & BT_USE) && !(players[i].cmd.buttons & BT_JUMP))
else if (!(players[i].cmd.buttons & BT_SPIN) && !(players[i].cmd.buttons & BT_JUMP))
keypressed = false;
if (!splitscreen)

View file

@ -162,7 +162,9 @@ extern wipestyleflags_t wipestyleflags;
// Even my function names are borderline
boolean F_ShouldColormapFade(void);
boolean F_TryColormapFade(UINT8 wipecolor);
#ifndef NOWIPE
void F_DecideWipeStyle(void);
#endif
#define FADECOLORMAPDIV 8
#define FADECOLORMAPROWS (256/FADECOLORMAPDIV)

View file

@ -16,6 +16,7 @@
#include "i_video.h"
#include "v_video.h"
#include "r_state.h" // fadecolormap
#include "r_draw.h" // transtable
#include "p_pspr.h" // tr_transxxx
#include "p_local.h"
@ -24,6 +25,7 @@
#include "z_zone.h"
#include "i_system.h"
#include "i_threads.h"
#include "m_menu.h"
#include "console.h"
#include "d_main.h"
@ -32,9 +34,7 @@
#include "doomstat.h"
#ifdef HAVE_BLUA
#include "lua_hud.h" // level title
#endif
#ifdef HWRENDER
#include "hardware/hw_main.h"
@ -465,6 +465,7 @@ void F_WipeEndScreen(void)
*/
boolean F_ShouldColormapFade(void)
{
#ifndef NOWIPE
if ((wipestyleflags & (WSF_FADEIN|WSF_FADEOUT)) // only if one of those wipestyleflags are actually set
&& !(wipestyleflags & WSF_CROSSFADE)) // and if not crossfading
{
@ -480,11 +481,13 @@ boolean F_ShouldColormapFade(void)
// Menus
|| gamestate == GS_TIMEATTACK);
}
#endif
return false;
}
/** Decides what wipe style to use.
*/
#ifndef NOWIPE
void F_DecideWipeStyle(void)
{
// Set default wipe style
@ -494,6 +497,7 @@ void F_DecideWipeStyle(void)
if (F_ShouldColormapFade())
wipestyle = WIPESTYLE_COLORMAP;
}
#endif
/** Attempt to run a colormap fade,
provided all the conditionals were properly met.
@ -502,6 +506,7 @@ void F_DecideWipeStyle(void)
*/
boolean F_TryColormapFade(UINT8 wipecolor)
{
#ifndef NOWIPE
if (F_ShouldColormapFade())
{
#ifdef HWRENDER
@ -511,6 +516,7 @@ boolean F_TryColormapFade(UINT8 wipecolor)
return true;
}
else
#endif
{
F_WipeColorFill(wipecolor);
return false;
@ -590,7 +596,15 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu)
I_UpdateNoBlit();
if (drawMenu)
{
#ifdef HAVE_THREADS
I_lock_mutex(&m_menu_mutex);
#endif
M_Drawer(); // menu is drawn even on top of wipes
#ifdef HAVE_THREADS
I_unlock_mutex(m_menu_mutex);
#endif
}
I_FinishUpdate(); // page flip or blit buffer
@ -609,6 +623,7 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu)
tic_t F_GetWipeLength(UINT8 wipetype)
{
#ifdef NOWIPE
(void)wipetype;
return 0;
#else
static char lumpname[10] = "FADEmmss";
@ -635,6 +650,7 @@ tic_t F_GetWipeLength(UINT8 wipetype)
boolean F_WipeExists(UINT8 wipetype)
{
#ifdef NOWIPE
(void)wipetype;
return false;
#else
static char lumpname[10] = "FADEmm00";

View file

@ -60,7 +60,7 @@ typedef enum
#endif
EXT_PK3,
EXT_SOC,
EXT_LUA, // allowed even if not HAVE_BLUA so that we can yell on load attempt
EXT_LUA,
NUM_EXT,
NUM_EXT_TABLE = NUM_EXT-EXT_START,
EXT_LOADED = 0x80

2541
src/g_demo.c Normal file

File diff suppressed because it is too large Load diff

86
src/g_demo.h Normal file
View file

@ -0,0 +1,86 @@
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2020 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file g_demo.h
/// \brief Demo recording and playback
#ifndef __G_DEMO__
#define __G_DEMO__
#include "doomdef.h"
#include "doomstat.h"
#include "d_event.h"
// ======================================
// DEMO playback/recording related stuff.
// ======================================
// demoplaying back and demo recording
extern boolean demoplayback, titledemo, demorecording, timingdemo;
extern tic_t demostarttime;
// Quit after playing a demo from cmdline.
extern boolean singledemo;
extern boolean demo_start;
extern boolean demosynced;
extern mobj_t *metalplayback;
// Only called by startup code.
void G_RecordDemo(const char *name);
void G_RecordMetal(void);
void G_BeginRecording(void);
void G_BeginMetal(void);
// Only called by shutdown code.
void G_SetDemoTime(UINT32 ptime, UINT32 pscore, UINT16 prings);
UINT8 G_CmpDemoTime(char *oldname, char *newname);
typedef enum
{
GHC_NORMAL = 0,
GHC_SUPER,
GHC_FIREFLOWER,
GHC_INVINCIBLE,
GHC_NIGHTSSKIN, // not actually a colour
GHC_RETURNSKIN // ditto
} ghostcolor_t;
// Record/playback tics
void G_ReadDemoTiccmd(ticcmd_t *cmd, INT32 playernum);
void G_WriteDemoTiccmd(ticcmd_t *cmd, INT32 playernum);
void G_GhostAddThok(void);
void G_GhostAddSpin(void);
void G_GhostAddRev(void);
void G_GhostAddColor(ghostcolor_t color);
void G_GhostAddFlip(void);
void G_GhostAddScale(fixed_t scale);
void G_GhostAddHit(mobj_t *victim);
void G_WriteGhostTic(mobj_t *ghost);
void G_ConsGhostTic(void);
void G_GhostTicker(void);
void G_ReadMetalTic(mobj_t *metal);
void G_WriteMetalTic(mobj_t *metal);
void G_SaveMetal(UINT8 **buffer);
void G_LoadMetal(UINT8 **buffer);
void G_DeferedPlayDemo(const char *demo);
void G_DoPlayDemo(char *defdemoname);
void G_TimeDemo(const char *name);
void G_AddGhost(char *defdemoname);
void G_FreeGhosts(void);
void G_DoPlayMetal(void);
void G_DoneLevelLoad(void);
void G_StopMetalDemo(void);
ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(boolean kill);
void G_StopDemo(void);
boolean G_CheckDemoStatus(void);
#endif // __G_DEMO__

File diff suppressed because it is too large Load diff

View file

@ -17,6 +17,7 @@
#include "doomdef.h"
#include "doomstat.h"
#include "d_event.h"
#include "g_demo.h"
extern char gamedatafilename[64];
extern char timeattackfolder[64];
@ -31,21 +32,6 @@ extern char player_names[MAXPLAYERS][MAXPLAYERNAME+1];
extern player_t players[MAXPLAYERS];
extern boolean playeringame[MAXPLAYERS];
// ======================================
// DEMO playback/recording related stuff.
// ======================================
// demoplaying back and demo recording
extern boolean demoplayback, titledemo, demorecording, timingdemo;
extern tic_t demostarttime;
// Quit after playing a demo from cmdline.
extern boolean singledemo;
extern boolean demo_start;
extern boolean demosynced;
extern mobj_t *metalplayback;
// gametic at level start
extern tic_t levelstarttic;
@ -107,6 +93,7 @@ typedef enum
// build an internal map name MAPxx from map number
const char *G_BuildMapName(INT32 map);
extern INT16 ticcmd_oldangleturn[2];
extern boolean ticcmd_centerviewdown[2]; // For simple controls, lock the camera behind the player
extern mobj_t *ticcmd_ztargetfocus[2]; // Locking onto an object?
void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer);
@ -173,65 +160,16 @@ void G_DoLoadLevel(boolean resetplayer);
void G_StartTitleCard(void);
void G_PreLevelTitleCard(void);
boolean G_IsTitleCardAvailable(void);
void G_DeferedPlayDemo(const char *demo);
// Can be called by the startup code or M_Responder, calls P_SetupLevel.
void G_LoadGame(UINT32 slot, INT16 mapoverride);
void G_SaveGameData(void);
void G_SaveGame(UINT32 slot);
void G_SaveGame(UINT32 slot, INT16 mapnum);
void G_SaveGameOver(UINT32 slot, boolean modifylives);
// Only called by startup code.
void G_RecordDemo(const char *name);
void G_RecordMetal(void);
void G_BeginRecording(void);
void G_BeginMetal(void);
// Only called by shutdown code.
void G_SetDemoTime(UINT32 ptime, UINT32 pscore, UINT16 prings);
UINT8 G_CmpDemoTime(char *oldname, char *newname);
typedef enum
{
GHC_NORMAL = 0,
GHC_SUPER,
GHC_FIREFLOWER,
GHC_INVINCIBLE,
GHC_NIGHTSSKIN, // not actually a colour
GHC_RETURNSKIN // ditto
} ghostcolor_t;
// Record/playback tics
void G_ReadDemoTiccmd(ticcmd_t *cmd, INT32 playernum);
void G_WriteDemoTiccmd(ticcmd_t *cmd, INT32 playernum);
void G_GhostAddThok(void);
void G_GhostAddSpin(void);
void G_GhostAddRev(void);
void G_GhostAddColor(ghostcolor_t color);
void G_GhostAddFlip(void);
void G_GhostAddScale(fixed_t scale);
void G_GhostAddHit(mobj_t *victim);
void G_WriteGhostTic(mobj_t *ghost);
void G_ConsGhostTic(void);
void G_GhostTicker(void);
void G_ReadMetalTic(mobj_t *metal);
void G_WriteMetalTic(mobj_t *metal);
void G_SaveMetal(UINT8 **buffer);
void G_LoadMetal(UINT8 **buffer);
void G_DoPlayDemo(char *defdemoname);
void G_TimeDemo(const char *name);
void G_AddGhost(char *defdemoname);
void G_DoPlayMetal(void);
void G_DoneLevelLoad(void);
void G_StopMetalDemo(void);
ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(boolean kill);
void G_StopDemo(void);
boolean G_CheckDemoStatus(void);
extern UINT32 gametypedefaultrules[NUMGAMETYPES];
extern UINT32 gametypetol[NUMGAMETYPES];
extern INT16 gametyperankings[NUMGAMETYPES];
@ -253,6 +191,7 @@ boolean G_GametypeHasTeams(void);
boolean G_GametypeHasSpectators(void);
boolean G_RingSlingerGametype(void);
boolean G_PlatformGametype(void);
boolean G_CoopGametype(void);
boolean G_TagGametype(void);
boolean G_CompetitionGametype(void);
boolean G_EnoughPlayersFinished(void);
@ -309,6 +248,6 @@ FUNCMATH INT32 G_TicsToCentiseconds(tic_t tics);
FUNCMATH INT32 G_TicsToMilliseconds(tic_t tics);
// Don't split up TOL handling
INT16 G_TOLFlag(INT32 pgametype);
UINT32 G_TOLFlag(INT32 pgametype);
#endif

View file

@ -57,13 +57,13 @@ const INT32 gcl_tutorial_check[num_gcl_tutorial_check] = {
const INT32 gcl_tutorial_used[num_gcl_tutorial_used] = {
gc_forward, gc_backward, gc_strafeleft, gc_straferight,
gc_turnleft, gc_turnright,
gc_jump, gc_use
gc_jump, gc_spin
};
const INT32 gcl_tutorial_full[num_gcl_tutorial_full] = {
gc_forward, gc_backward, gc_strafeleft, gc_straferight,
gc_lookup, gc_lookdown, gc_turnleft, gc_turnright, gc_centerview,
gc_jump, gc_use,
gc_jump, gc_spin,
gc_fire, gc_firenormal
};
@ -82,10 +82,10 @@ const INT32 gcl_movement_camera[num_gcl_movement_camera] = {
const INT32 gcl_jump[num_gcl_jump] = { gc_jump };
const INT32 gcl_use[num_gcl_use] = { gc_use };
const INT32 gcl_spin[num_gcl_spin] = { gc_spin };
const INT32 gcl_jump_use[num_gcl_jump_use] = {
gc_jump, gc_use
const INT32 gcl_jump_spin[num_gcl_jump_spin] = {
gc_jump, gc_spin
};
typedef struct
@ -583,7 +583,7 @@ static const char *gamecontrolname[num_gamecontrols] =
"fire",
"firenormal",
"tossflag",
"use",
"spin",
"camtoggle",
"camreset",
"lookup",
@ -692,7 +692,7 @@ void G_DefineDefaultControls(void)
gamecontroldefault[gcs_fps][gc_turnright ][0] = KEY_RIGHTARROW;
gamecontroldefault[gcs_fps][gc_centerview ][0] = KEY_END;
gamecontroldefault[gcs_fps][gc_jump ][0] = KEY_SPACE;
gamecontroldefault[gcs_fps][gc_use ][0] = KEY_LSHIFT;
gamecontroldefault[gcs_fps][gc_spin ][0] = KEY_LSHIFT;
gamecontroldefault[gcs_fps][gc_fire ][0] = KEY_RCTRL;
gamecontroldefault[gcs_fps][gc_fire ][1] = KEY_MOUSE1+0;
gamecontroldefault[gcs_fps][gc_firenormal ][0] = 'c';
@ -708,7 +708,7 @@ void G_DefineDefaultControls(void)
gamecontroldefault[gcs_platform][gc_turnright ][0] = KEY_RIGHTARROW;
gamecontroldefault[gcs_platform][gc_centerview ][0] = KEY_END;
gamecontroldefault[gcs_platform][gc_jump ][0] = KEY_SPACE;
gamecontroldefault[gcs_platform][gc_use ][0] = KEY_LSHIFT;
gamecontroldefault[gcs_platform][gc_spin ][0] = KEY_LSHIFT;
gamecontroldefault[gcs_platform][gc_fire ][0] = 's';
gamecontroldefault[gcs_platform][gc_fire ][1] = KEY_MOUSE1+0;
gamecontroldefault[gcs_platform][gc_firenormal ][0] = 'w';
@ -743,7 +743,7 @@ void G_DefineDefaultControls(void)
gamecontroldefault[i][gc_weaponnext ][1] = KEY_JOY1+1; // B
gamecontroldefault[i][gc_weaponprev ][1] = KEY_JOY1+2; // X
gamecontroldefault[i][gc_tossflag ][1] = KEY_JOY1+0; // A
gamecontroldefault[i][gc_use ][1] = KEY_JOY1+4; // LB
gamecontroldefault[i][gc_spin ][1] = KEY_JOY1+4; // LB
gamecontroldefault[i][gc_camtoggle ][1] = KEY_HAT1+0; // D-Pad Up
gamecontroldefault[i][gc_camreset ][1] = KEY_JOY1+3; // Y
gamecontroldefault[i][gc_centerview ][1] = KEY_JOY1+9; // Right Stick
@ -758,7 +758,7 @@ void G_DefineDefaultControls(void)
gamecontrolbisdefault[i][gc_weaponnext][0] = KEY_2JOY1+1; // B
gamecontrolbisdefault[i][gc_weaponprev][0] = KEY_2JOY1+2; // X
gamecontrolbisdefault[i][gc_tossflag ][0] = KEY_2JOY1+0; // A
gamecontrolbisdefault[i][gc_use ][0] = KEY_2JOY1+4; // LB
gamecontrolbisdefault[i][gc_spin ][0] = KEY_2JOY1+4; // LB
gamecontrolbisdefault[i][gc_camreset ][0] = KEY_2JOY1+3; // Y
gamecontrolbisdefault[i][gc_centerview][0] = KEY_2JOY1+9; // Right Stick
gamecontrolbisdefault[i][gc_jump ][0] = KEY_2JOY1+5; // RB
@ -890,7 +890,7 @@ static INT32 G_FilterKeyByVersion(INT32 numctrl, INT32 keyidx, INT32 player, INT
if (GETMAJOREXECVERSION(cv_execversion.value) < 27 && ( // v2.1.22
numctrl == gc_weaponnext || numctrl == gc_weaponprev || numctrl == gc_tossflag ||
numctrl == gc_use || numctrl == gc_camreset || numctrl == gc_jump ||
numctrl == gc_spin || numctrl == gc_camreset || numctrl == gc_jump ||
numctrl == gc_pause || numctrl == gc_systemmenu || numctrl == gc_camtoggle ||
numctrl == gc_screenshot || numctrl == gc_talkkey || numctrl == gc_scores ||
numctrl == gc_centerview
@ -996,7 +996,9 @@ static void setcontrol(INT32 (*gc)[2])
INT32 player = ((void*)gc == (void*)&gamecontrolbis ? 1 : 0);
boolean nestedoverride = false;
namectrl = COM_Argv(1);
// Update me for 2.3
namectrl = (stricmp(COM_Argv(1), "use")) ? COM_Argv(1) : "spin";
for (numctrl = 0; numctrl < num_gamecontrols && stricmp(namectrl, gamecontrolname[numctrl]);
numctrl++)
;

View file

@ -80,7 +80,7 @@ typedef enum
gc_fire,
gc_firenormal,
gc_tossflag,
gc_use,
gc_spin,
gc_camtoggle,
gc_camreset,
gc_lookup,
@ -141,8 +141,8 @@ extern INT32 gamecontrolbisdefault[num_gamecontrolschemes][num_gamecontrols][2];
#define num_gcl_camera 2
#define num_gcl_movement_camera 6
#define num_gcl_jump 1
#define num_gcl_use 1
#define num_gcl_jump_use 2
#define num_gcl_spin 1
#define num_gcl_jump_spin 2
extern const INT32 gcl_tutorial_check[num_gcl_tutorial_check];
extern const INT32 gcl_tutorial_used[num_gcl_tutorial_used];
@ -151,8 +151,8 @@ extern const INT32 gcl_movement[num_gcl_movement];
extern const INT32 gcl_camera[num_gcl_camera];
extern const INT32 gcl_movement_camera[num_gcl_movement_camera];
extern const INT32 gcl_jump[num_gcl_jump];
extern const INT32 gcl_use[num_gcl_use];
extern const INT32 gcl_jump_use[num_gcl_jump_use];
extern const INT32 gcl_spin[num_gcl_spin];
extern const INT32 gcl_jump_spin[num_gcl_jump_spin];
// peace to my little coder fingers!
// check a gamecontrol being active or not

View file

@ -57,6 +57,7 @@ extern UINT8 ultimatemode; // was sk_insane
extern gameaction_t gameaction;
extern boolean botingame;
extern UINT8 botskin, botcolor;
extern UINT8 botskin;
extern UINT16 botcolor;
#endif //__G_STATE__

View file

@ -1,20 +1,12 @@
// Emacs style mode select -*- C++ -*-
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
//
// Copyright (C) 2001 by DooM Legacy Team.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file
/// \file hw3dsdrv.h
/// \brief 3D sound import/export prototypes for low-level hardware interface
#ifndef __HW_3DS_DRV_H__

View file

@ -1,19 +1,12 @@
// Emacs style mode select -*- C++ -*-
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
//
// Copyright (C) 2001 by DooM Legacy Team.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file
/// \file hw3sound.c
/// \brief Hardware 3D sound general code
#include "../doomdef.h"
@ -28,7 +21,7 @@
#include "../tables.h"
#include "../sounds.h"
#include "../r_main.h"
#include "../r_things.h"
#include "../r_skins.h"
#include "../m_random.h"
#include "../p_local.h"
#include "hw3dsdrv.h"

View file

@ -1,20 +1,12 @@
// Emacs style mode select -*- C++ -*-
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
//
// Copyright (C) 2001 by DooM Legacy Team.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file
/// \file hw3sound.h
/// \brief High-level functions of hardware 3D sound
#ifndef __HW3_SOUND_H__

454
src/hardware/hw_batching.c Normal file
View file

@ -0,0 +1,454 @@
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2020 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file hw_batching.c
/// \brief Draw call batching and related things.
#ifdef HWRENDER
#include "hw_glob.h"
#include "hw_batching.h"
#include "../i_system.h"
// The texture for the next polygon given to HWR_ProcessPolygon.
// Set with HWR_SetCurrentTexture.
GLMipmap_t *current_texture = NULL;
boolean currently_batching = false;
FOutVector* finalVertexArray = NULL;// contains subset of sorted vertices and texture coordinates to be sent to gpu
UINT32* finalVertexIndexArray = NULL;// contains indexes for glDrawElements, taking into account fan->triangles conversion
// NOTE have this alloced as 3x finalVertexArray size
int finalVertexArrayAllocSize = 65536;
//GLubyte* colorArray = NULL;// contains color data to be sent to gpu, if needed
//int colorArrayAllocSize = 65536;
// not gonna use this for now, just sort by color and change state when it changes
// later maybe when using vertex attributes if it's needed
PolygonArrayEntry* polygonArray = NULL;// contains the polygon data from DrawPolygon, waiting to be processed
int polygonArraySize = 0;
UINT32* polygonIndexArray = NULL;// contains sorting pointers for polygonArray
int polygonArrayAllocSize = 65536;
FOutVector* unsortedVertexArray = NULL;// contains unsorted vertices and texture coordinates from DrawPolygon
int unsortedVertexArraySize = 0;
int unsortedVertexArrayAllocSize = 65536;
// Enables batching mode. HWR_ProcessPolygon will collect polygons instead of passing them directly to the rendering backend.
// Call HWR_RenderBatches to render all the collected geometry.
void HWR_StartBatching(void)
{
if (currently_batching)
I_Error("Repeat call to HWR_StartBatching without HWR_RenderBatches");
// init arrays if that has not been done yet
if (!finalVertexArray)
{
finalVertexArray = malloc(finalVertexArrayAllocSize * sizeof(FOutVector));
finalVertexIndexArray = malloc(finalVertexArrayAllocSize * 3 * sizeof(UINT32));
polygonArray = malloc(polygonArrayAllocSize * sizeof(PolygonArrayEntry));
polygonIndexArray = malloc(polygonArrayAllocSize * sizeof(UINT32));
unsortedVertexArray = malloc(unsortedVertexArrayAllocSize * sizeof(FOutVector));
}
currently_batching = true;
}
// This replaces the direct calls to pfnSetTexture in cases where batching is available.
// The texture selection is saved for the next HWR_ProcessPolygon call.
// Doing this was easier than getting a texture pointer to HWR_ProcessPolygon.
void HWR_SetCurrentTexture(GLMipmap_t *texture)
{
if (currently_batching)
{
current_texture = texture;
}
else
{
HWD.pfnSetTexture(texture);
}
}
// If batching is enabled, this function collects the polygon data and the chosen texture
// for later use in HWR_RenderBatches. Otherwise the rendering backend is used to
// render the polygon immediately.
void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags, int shader, boolean horizonSpecial)
{
if (currently_batching)
{
if (!pSurf)
I_Error("Got a null FSurfaceInfo in batching");// nulls should not come in the stuff that batching currently applies to
if (polygonArraySize == polygonArrayAllocSize)
{
PolygonArrayEntry* new_array;
// ran out of space, make new array double the size
polygonArrayAllocSize *= 2;
new_array = malloc(polygonArrayAllocSize * sizeof(PolygonArrayEntry));
memcpy(new_array, polygonArray, polygonArraySize * sizeof(PolygonArrayEntry));
free(polygonArray);
polygonArray = new_array;
// also need to redo the index array, dont need to copy it though
free(polygonIndexArray);
polygonIndexArray = malloc(polygonArrayAllocSize * sizeof(UINT32));
}
while (unsortedVertexArraySize + (int)iNumPts > unsortedVertexArrayAllocSize)
{
FOutVector* new_array;
// need more space for vertices in unsortedVertexArray
unsortedVertexArrayAllocSize *= 2;
new_array = malloc(unsortedVertexArrayAllocSize * sizeof(FOutVector));
memcpy(new_array, unsortedVertexArray, unsortedVertexArraySize * sizeof(FOutVector));
free(unsortedVertexArray);
unsortedVertexArray = new_array;
}
// add the polygon data to the arrays
polygonArray[polygonArraySize].surf = *pSurf;
polygonArray[polygonArraySize].vertsIndex = unsortedVertexArraySize;
polygonArray[polygonArraySize].numVerts = iNumPts;
polygonArray[polygonArraySize].polyFlags = PolyFlags;
polygonArray[polygonArraySize].texture = current_texture;
polygonArray[polygonArraySize].shader = shader;
polygonArray[polygonArraySize].horizonSpecial = horizonSpecial;
polygonArraySize++;
memcpy(&unsortedVertexArray[unsortedVertexArraySize], pOutVerts, iNumPts * sizeof(FOutVector));
unsortedVertexArraySize += iNumPts;
}
else
{
if (shader)
HWD.pfnSetShader(shader);
HWD.pfnDrawPolygon(pSurf, pOutVerts, iNumPts, PolyFlags);
}
}
static int comparePolygons(const void *p1, const void *p2)
{
unsigned int index1 = *(const unsigned int*)p1;
unsigned int index2 = *(const unsigned int*)p2;
PolygonArrayEntry* poly1 = &polygonArray[index1];
PolygonArrayEntry* poly2 = &polygonArray[index2];
int diff;
INT64 diff64;
int shader1 = poly1->shader;
int shader2 = poly2->shader;
// make skywalls and horizon lines first in order
if (poly1->polyFlags & PF_NoTexture || poly1->horizonSpecial)
shader1 = -1;
if (poly2->polyFlags & PF_NoTexture || poly2->horizonSpecial)
shader2 = -1;
diff = shader1 - shader2;
if (diff != 0) return diff;
// skywalls and horizon lines must retain their order for horizon lines to work
if (shader1 == -1 && shader2 == -1)
return index1 - index2;
diff64 = poly1->texture - poly2->texture;
if (diff64 != 0) return diff64;
diff = poly1->polyFlags - poly2->polyFlags;
if (diff != 0) return diff;
diff64 = poly1->surf.PolyColor.rgba - poly2->surf.PolyColor.rgba;
if (diff64 < 0) return -1; else if (diff64 > 0) return 1;
diff64 = poly1->surf.TintColor.rgba - poly2->surf.TintColor.rgba;
if (diff64 < 0) return -1; else if (diff64 > 0) return 1;
diff64 = poly1->surf.FadeColor.rgba - poly2->surf.FadeColor.rgba;
if (diff64 < 0) return -1; else if (diff64 > 0) return 1;
diff = poly1->surf.LightInfo.light_level - poly2->surf.LightInfo.light_level;
if (diff != 0) return diff;
diff = poly1->surf.LightInfo.fade_start - poly2->surf.LightInfo.fade_start;
if (diff != 0) return diff;
diff = poly1->surf.LightInfo.fade_end - poly2->surf.LightInfo.fade_end;
return diff;
}
static int comparePolygonsNoShaders(const void *p1, const void *p2)
{
unsigned int index1 = *(const unsigned int*)p1;
unsigned int index2 = *(const unsigned int*)p2;
PolygonArrayEntry* poly1 = &polygonArray[index1];
PolygonArrayEntry* poly2 = &polygonArray[index2];
int diff;
INT64 diff64;
GLMipmap_t *texture1 = poly1->texture;
GLMipmap_t *texture2 = poly2->texture;
if (poly1->polyFlags & PF_NoTexture || poly1->horizonSpecial)
texture1 = NULL;
if (poly2->polyFlags & PF_NoTexture || poly2->horizonSpecial)
texture2 = NULL;
diff64 = texture1 - texture2;
if (diff64 != 0) return diff64;
// skywalls and horizon lines must retain their order for horizon lines to work
if (texture1 == NULL && texture2 == NULL)
return index1 - index2;
diff = poly1->polyFlags - poly2->polyFlags;
if (diff != 0) return diff;
diff64 = poly1->surf.PolyColor.rgba - poly2->surf.PolyColor.rgba;
if (diff64 < 0) return -1; else if (diff64 > 0) return 1;
return 0;
}
// This function organizes the geometry collected by HWR_ProcessPolygon calls into batches and uses
// the rendering backend to draw them.
void HWR_RenderBatches(void)
{
int finalVertexWritePos = 0;// position in finalVertexArray
int finalIndexWritePos = 0;// position in finalVertexIndexArray
int polygonReadPos = 0;// position in polygonIndexArray
int currentShader;
int nextShader = 0;
GLMipmap_t *currentTexture;
GLMipmap_t *nextTexture = NULL;
FBITFIELD currentPolyFlags = 0;
FBITFIELD nextPolyFlags = 0;
FSurfaceInfo currentSurfaceInfo;
FSurfaceInfo nextSurfaceInfo;
int i;
if (!currently_batching)
I_Error("HWR_RenderBatches called without starting batching");
nextSurfaceInfo.LightInfo.fade_end = 0;
nextSurfaceInfo.LightInfo.fade_start = 0;
nextSurfaceInfo.LightInfo.light_level = 0;
currently_batching = false;// no longer collecting batches
if (!polygonArraySize)
{
rs_hw_numpolys = rs_hw_numcalls = rs_hw_numshaders = rs_hw_numtextures = rs_hw_numpolyflags = rs_hw_numcolors = 0;
return;// nothing to draw
}
// init stats vars
rs_hw_numpolys = polygonArraySize;
rs_hw_numcalls = rs_hw_numverts = 0;
rs_hw_numshaders = rs_hw_numtextures = rs_hw_numpolyflags = rs_hw_numcolors = 1;
// init polygonIndexArray
for (i = 0; i < polygonArraySize; i++)
{
polygonIndexArray[i] = i;
}
// sort polygons
rs_hw_batchsorttime = I_GetTimeMicros();
if (cv_glshaders.value && gl_shadersavailable)
qsort(polygonIndexArray, polygonArraySize, sizeof(unsigned int), comparePolygons);
else
qsort(polygonIndexArray, polygonArraySize, sizeof(unsigned int), comparePolygonsNoShaders);
rs_hw_batchsorttime = I_GetTimeMicros() - rs_hw_batchsorttime;
// sort order
// 1. shader
// 2. texture
// 3. polyflags
// 4. colors + light level
// not sure about what order of the last 2 should be, or if it even matters
rs_hw_batchdrawtime = I_GetTimeMicros();
currentShader = polygonArray[polygonIndexArray[0]].shader;
currentTexture = polygonArray[polygonIndexArray[0]].texture;
currentPolyFlags = polygonArray[polygonIndexArray[0]].polyFlags;
currentSurfaceInfo = polygonArray[polygonIndexArray[0]].surf;
// For now, will sort and track the colors. Vertex attributes could be used instead of uniforms
// and a color array could replace the color calls.
// set state for first batch
if (cv_glshaders.value && gl_shadersavailable)
{
HWD.pfnSetShader(currentShader);
}
if (currentPolyFlags & PF_NoTexture)
currentTexture = NULL;
else
HWD.pfnSetTexture(currentTexture);
while (1)// note: remember handling notexture polyflag as having texture number 0 (also in comparePolygons)
{
int firstIndex;
int lastIndex;
boolean stopFlag = false;
boolean changeState = false;
boolean changeShader = false;
boolean changeTexture = false;
boolean changePolyFlags = false;
boolean changeSurfaceInfo = false;
// steps:
// write vertices
// check for changes or end, otherwise go back to writing
// changes will affect the next vars and the change bools
// end could set flag for stopping
// execute draw call
// could check ending flag here
// change states according to next vars and change bools, updating the current vars and reseting the bools
// reset write pos
// repeat loop
int index = polygonIndexArray[polygonReadPos++];
int numVerts = polygonArray[index].numVerts;
// before writing, check if there is enough room
// using 'while' instead of 'if' here makes sure that there will *always* be enough room.
// probably never will this loop run more than once though
while (finalVertexWritePos + numVerts > finalVertexArrayAllocSize)
{
FOutVector* new_array;
unsigned int* new_index_array;
finalVertexArrayAllocSize *= 2;
new_array = malloc(finalVertexArrayAllocSize * sizeof(FOutVector));
memcpy(new_array, finalVertexArray, finalVertexWritePos * sizeof(FOutVector));
free(finalVertexArray);
finalVertexArray = new_array;
// also increase size of index array, 3x of vertex array since
// going from fans to triangles increases vertex count to 3x
new_index_array = malloc(finalVertexArrayAllocSize * 3 * sizeof(UINT32));
memcpy(new_index_array, finalVertexIndexArray, finalIndexWritePos * sizeof(UINT32));
free(finalVertexIndexArray);
finalVertexIndexArray = new_index_array;
}
// write the vertices of the polygon
memcpy(&finalVertexArray[finalVertexWritePos], &unsortedVertexArray[polygonArray[index].vertsIndex],
numVerts * sizeof(FOutVector));
// write the indexes, pointing to the fan vertexes but in triangles format
firstIndex = finalVertexWritePos;
lastIndex = finalVertexWritePos + numVerts;
finalVertexWritePos += 2;
while (finalVertexWritePos < lastIndex)
{
finalVertexIndexArray[finalIndexWritePos++] = firstIndex;
finalVertexIndexArray[finalIndexWritePos++] = finalVertexWritePos - 1;
finalVertexIndexArray[finalIndexWritePos++] = finalVertexWritePos++;
}
if (polygonReadPos >= polygonArraySize)
{
stopFlag = true;
}
else
{
// check if a state change is required, set the change bools and next vars
int nextIndex = polygonIndexArray[polygonReadPos];
nextShader = polygonArray[nextIndex].shader;
nextTexture = polygonArray[nextIndex].texture;
nextPolyFlags = polygonArray[nextIndex].polyFlags;
nextSurfaceInfo = polygonArray[nextIndex].surf;
if (nextPolyFlags & PF_NoTexture)
nextTexture = 0;
if (currentShader != nextShader && cv_glshaders.value && gl_shadersavailable)
{
changeState = true;
changeShader = true;
}
if (currentTexture != nextTexture)
{
changeState = true;
changeTexture = true;
}
if (currentPolyFlags != nextPolyFlags)
{
changeState = true;
changePolyFlags = true;
}
if (cv_glshaders.value && gl_shadersavailable)
{
if (currentSurfaceInfo.PolyColor.rgba != nextSurfaceInfo.PolyColor.rgba ||
currentSurfaceInfo.TintColor.rgba != nextSurfaceInfo.TintColor.rgba ||
currentSurfaceInfo.FadeColor.rgba != nextSurfaceInfo.FadeColor.rgba ||
currentSurfaceInfo.LightInfo.light_level != nextSurfaceInfo.LightInfo.light_level ||
currentSurfaceInfo.LightInfo.fade_start != nextSurfaceInfo.LightInfo.fade_start ||
currentSurfaceInfo.LightInfo.fade_end != nextSurfaceInfo.LightInfo.fade_end)
{
changeState = true;
changeSurfaceInfo = true;
}
}
else
{
if (currentSurfaceInfo.PolyColor.rgba != nextSurfaceInfo.PolyColor.rgba)
{
changeState = true;
changeSurfaceInfo = true;
}
}
}
if (changeState || stopFlag)
{
// execute draw call
HWD.pfnDrawIndexedTriangles(&currentSurfaceInfo, finalVertexArray, finalIndexWritePos, currentPolyFlags, finalVertexIndexArray);
// update stats
rs_hw_numcalls++;
rs_hw_numverts += finalIndexWritePos;
// reset write positions
finalVertexWritePos = 0;
finalIndexWritePos = 0;
}
else continue;
// if we're here then either its time to stop or time to change state
if (stopFlag) break;
// change state according to change bools and next vars, update current vars and reset bools
if (changeShader)
{
HWD.pfnSetShader(nextShader);
currentShader = nextShader;
changeShader = false;
rs_hw_numshaders++;
}
if (changeTexture)
{
// texture should be already ready for use from calls to SetTexture during batch collection
HWD.pfnSetTexture(nextTexture);
currentTexture = nextTexture;
changeTexture = false;
rs_hw_numtextures++;
}
if (changePolyFlags)
{
currentPolyFlags = nextPolyFlags;
changePolyFlags = false;
rs_hw_numpolyflags++;
}
if (changeSurfaceInfo)
{
currentSurfaceInfo = nextSurfaceInfo;
changeSurfaceInfo = false;
rs_hw_numcolors++;
}
// and that should be it?
}
// reset the arrays (set sizes to 0)
polygonArraySize = 0;
unsortedVertexArraySize = 0;
rs_hw_batchdrawtime = I_GetTimeMicros() - rs_hw_batchdrawtime;
}
#endif // HWRENDER

View file

@ -0,0 +1,37 @@
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2020 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file hw_batching.h
/// \brief Draw call batching and related things.
#ifndef __HWR_BATCHING_H__
#define __HWR_BATCHING_H__
#include "hw_defs.h"
#include "hw_data.h"
#include "hw_drv.h"
typedef struct
{
FSurfaceInfo surf;// surf also has its own polyflags for some reason, but it seems unused
unsigned int vertsIndex;// location of verts in unsortedVertexArray
FUINT numVerts;
FBITFIELD polyFlags;
GLMipmap_t *texture;
int shader;
// this tells batching that the plane belongs to a horizon line and must be drawn in correct order with the skywalls
boolean horizonSpecial;
} PolygonArrayEntry;
void HWR_StartBatching(void);
void HWR_SetCurrentTexture(GLMipmap_t *texture);
void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags, int shader, boolean horizonSpecial);
void HWR_RenderBatches(void);
#endif

Some files were not shown because too many files have changed in this diff Show more