Compare commits
91 Commits
Release_1.
...
Release_2.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e61bbd634c | ||
|
|
917b68d630 | ||
|
|
46d3ae324c | ||
|
|
d27740bd38 | ||
|
|
cfd30419c2 | ||
|
|
3ec96b84ad | ||
|
|
34cb964ea5 | ||
|
|
5789492021 | ||
|
|
38cf08e298 | ||
|
|
5cd01807b2 | ||
|
|
57af3af800 | ||
|
|
8e07b7fc3f | ||
|
|
0076f8947c | ||
|
|
43ce86571c | ||
|
|
4188cd3455 | ||
|
|
685dfe78c2 | ||
|
|
348d79ef38 | ||
|
|
9088c44b3e | ||
|
|
06b760e8dd | ||
|
|
d06aa1c736 | ||
|
|
787c623cfe | ||
|
|
b7bf1563e5 | ||
|
|
f56abf0596 | ||
|
|
a7e3503e2c | ||
|
|
2ee40560ee | ||
|
|
5682640e36 | ||
|
|
7ec2ab9a76 | ||
|
|
82d4d8719f | ||
|
|
f302687c7f | ||
|
|
fd973f049c | ||
|
|
5947727f80 | ||
|
|
69ecce88df | ||
|
|
43593b168d | ||
|
|
d80074b9b6 | ||
|
|
69027eca53 | ||
|
|
ac289c7f48 | ||
|
|
87e44b700b | ||
|
|
48721e5811 | ||
|
|
7ee508118c | ||
|
|
8c4f38c0af | ||
|
|
167a2c2bd1 | ||
|
|
f1c6c48b36 | ||
|
|
8d2745fc33 | ||
|
|
5e03978cd7 | ||
|
|
261457a959 | ||
|
|
93de90b680 | ||
|
|
dc5915b4f8 | ||
|
|
c3b6daefc9 | ||
|
|
81c2034a16 | ||
|
|
8a421a2623 | ||
|
|
a281000308 | ||
|
|
03deda2f9d | ||
|
|
ba5a0f3044 | ||
|
|
b37f5d6d76 | ||
|
|
593b4d161c | ||
|
|
7c29c05d64 | ||
|
|
89f4b6d535 | ||
|
|
373351c2ba | ||
|
|
65037e0e69 | ||
|
|
e2a2037a99 | ||
|
|
b843e9a6cb | ||
|
|
b4cb827d73 | ||
|
|
22ce8ac538 | ||
|
|
625a6e7498 | ||
|
|
fd9de493e6 | ||
|
|
4c196a9290 | ||
|
|
c63c6701ac | ||
|
|
8bae7a5b05 | ||
|
|
af5a70785e | ||
|
|
c5b7c0ad16 | ||
|
|
28e2417ef9 | ||
|
|
2fe6d6d33a | ||
|
|
e0638c598d | ||
|
|
9a10d72e1f | ||
|
|
a09ea75d80 | ||
|
|
10c83e8bf5 | ||
|
|
d5b44e44e1 | ||
|
|
dcd488c48c | ||
|
|
db08631ab9 | ||
|
|
bad55d49cf | ||
|
|
98f234fce3 | ||
|
|
55984fbb08 | ||
|
|
5c3e9fea4c | ||
|
|
debe52c1e0 | ||
|
|
1c5256a4c6 | ||
|
|
d594f5fdb7 | ||
|
|
49f6132d23 | ||
|
|
6ff457eb68 | ||
|
|
5b9a1ff95d | ||
|
|
232f24a2a2 | ||
|
|
efc56e82d9 |
13
.gitignore
vendored
13
.gitignore
vendored
@@ -21,6 +21,9 @@ bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
ARM/
|
||||
ARM64/
|
||||
win32/
|
||||
|
||||
# Visual Studio 2015 cache/options directory
|
||||
.vs/
|
||||
@@ -263,3 +266,13 @@ __pycache__/
|
||||
/Export
|
||||
/DrMem
|
||||
/Doc private
|
||||
# Windows local libraries
|
||||
/Libs
|
||||
|
||||
#CMake generated
|
||||
out/
|
||||
/cmake-build-debug
|
||||
|
||||
# Windows XP stuff
|
||||
DebugWinXp/
|
||||
ReleaseWinXp/
|
||||
|
||||
219
CMakeLists.txt
Normal file
219
CMakeLists.txt
Normal file
@@ -0,0 +1,219 @@
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
project(SpaceCadetPinball)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
|
||||
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/bin)
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMakeModules")
|
||||
|
||||
# On Windows, set paths to SDL-devel packages here
|
||||
if(WIN32)
|
||||
list(APPEND SDL2_PATH "${CMAKE_CURRENT_LIST_DIR}/Libs/SDL2")
|
||||
list(APPEND SDL2_MIXER_PATH "${CMAKE_CURRENT_LIST_DIR}/Libs/SDL2_mixer")
|
||||
endif()
|
||||
|
||||
# Link mingw libs static
|
||||
if(MINGW)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static")
|
||||
endif()
|
||||
|
||||
# SDL2main is not needed
|
||||
set(SDL2_BUILDING_LIBRARY ON)
|
||||
|
||||
find_package(SDL2 REQUIRED)
|
||||
FIND_PACKAGE(SDL2_mixer REQUIRED)
|
||||
|
||||
include_directories(${SDL2_INCLUDE_DIR} ${SDL2_MIXER_INCLUDE_DIR})
|
||||
get_property(dirs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES)
|
||||
foreach(dir ${dirs})
|
||||
message(STATUS "Include dir='${dir}'")
|
||||
endforeach()
|
||||
|
||||
|
||||
|
||||
set(SOURCE_FILES
|
||||
SpaceCadetPinball/control.cpp
|
||||
SpaceCadetPinball/control.h
|
||||
SpaceCadetPinball/EmbeddedData.cpp
|
||||
SpaceCadetPinball/EmbeddedData.h
|
||||
SpaceCadetPinball/fullscrn.cpp
|
||||
SpaceCadetPinball/fullscrn.h
|
||||
SpaceCadetPinball/gdrv.cpp
|
||||
SpaceCadetPinball/gdrv.h
|
||||
SpaceCadetPinball/GroupData.cpp
|
||||
SpaceCadetPinball/GroupData.h
|
||||
SpaceCadetPinball/high_score.cpp
|
||||
SpaceCadetPinball/high_score.h
|
||||
SpaceCadetPinball/loader.cpp
|
||||
SpaceCadetPinball/loader.h
|
||||
SpaceCadetPinball/maths.cpp
|
||||
SpaceCadetPinball/maths.h
|
||||
SpaceCadetPinball/midi.cpp
|
||||
SpaceCadetPinball/midi.h
|
||||
SpaceCadetPinball/nudge.cpp
|
||||
SpaceCadetPinball/nudge.h
|
||||
SpaceCadetPinball/options.cpp
|
||||
SpaceCadetPinball/options.h
|
||||
SpaceCadetPinball/partman.cpp
|
||||
SpaceCadetPinball/partman.h
|
||||
SpaceCadetPinball/pb.cpp
|
||||
SpaceCadetPinball/pb.h
|
||||
SpaceCadetPinball/pch.h
|
||||
SpaceCadetPinball/pinball.cpp
|
||||
SpaceCadetPinball/pinball.h
|
||||
SpaceCadetPinball/proj.cpp
|
||||
SpaceCadetPinball/proj.h
|
||||
SpaceCadetPinball/render.cpp
|
||||
SpaceCadetPinball/render.h
|
||||
SpaceCadetPinball/score.cpp
|
||||
SpaceCadetPinball/score.h
|
||||
SpaceCadetPinball/Sound.cpp
|
||||
SpaceCadetPinball/Sound.h
|
||||
SpaceCadetPinball/SpaceCadetPinball.cpp
|
||||
SpaceCadetPinball/TBall.cpp
|
||||
SpaceCadetPinball/TBall.h
|
||||
SpaceCadetPinball/TBlocker.cpp
|
||||
SpaceCadetPinball/TBlocker.h
|
||||
SpaceCadetPinball/TBumper.cpp
|
||||
SpaceCadetPinball/TBumper.h
|
||||
SpaceCadetPinball/TCircle.cpp
|
||||
SpaceCadetPinball/TCircle.h
|
||||
SpaceCadetPinball/TCollisionComponent.cpp
|
||||
SpaceCadetPinball/TCollisionComponent.h
|
||||
SpaceCadetPinball/TComponentGroup.cpp
|
||||
SpaceCadetPinball/TComponentGroup.h
|
||||
SpaceCadetPinball/TDemo.cpp
|
||||
SpaceCadetPinball/TDemo.h
|
||||
SpaceCadetPinball/TDrain.cpp
|
||||
SpaceCadetPinball/TDrain.h
|
||||
SpaceCadetPinball/TEdgeBox.h
|
||||
SpaceCadetPinball/TEdgeManager.cpp
|
||||
SpaceCadetPinball/TEdgeManager.h
|
||||
SpaceCadetPinball/TEdgeSegment.cpp
|
||||
SpaceCadetPinball/TEdgeSegment.h
|
||||
SpaceCadetPinball/TFlagSpinner.cpp
|
||||
SpaceCadetPinball/TFlagSpinner.h
|
||||
SpaceCadetPinball/TFlipper.cpp
|
||||
SpaceCadetPinball/TFlipper.h
|
||||
SpaceCadetPinball/TFlipperEdge.cpp
|
||||
SpaceCadetPinball/TFlipperEdge.h
|
||||
SpaceCadetPinball/TGate.cpp
|
||||
SpaceCadetPinball/TGate.h
|
||||
SpaceCadetPinball/THole.cpp
|
||||
SpaceCadetPinball/THole.h
|
||||
SpaceCadetPinball/timer.cpp
|
||||
SpaceCadetPinball/timer.h
|
||||
SpaceCadetPinball/TKickback.cpp
|
||||
SpaceCadetPinball/TKickback.h
|
||||
SpaceCadetPinball/TKickout.cpp
|
||||
SpaceCadetPinball/TKickout.h
|
||||
SpaceCadetPinball/TLight.cpp
|
||||
SpaceCadetPinball/TLight.h
|
||||
SpaceCadetPinball/TLightBargraph.cpp
|
||||
SpaceCadetPinball/TLightBargraph.h
|
||||
SpaceCadetPinball/TLightGroup.cpp
|
||||
SpaceCadetPinball/TLightGroup.h
|
||||
SpaceCadetPinball/TLightRollover.cpp
|
||||
SpaceCadetPinball/TLightRollover.h
|
||||
SpaceCadetPinball/TLine.cpp
|
||||
SpaceCadetPinball/TLine.h
|
||||
SpaceCadetPinball/TOneway.cpp
|
||||
SpaceCadetPinball/TOneway.h
|
||||
SpaceCadetPinball/TPinballComponent.cpp
|
||||
SpaceCadetPinball/TPinballComponent.h
|
||||
SpaceCadetPinball/TPinballTable.cpp
|
||||
SpaceCadetPinball/TPinballTable.h
|
||||
SpaceCadetPinball/TPlunger.cpp
|
||||
SpaceCadetPinball/TPlunger.h
|
||||
SpaceCadetPinball/TPopupTarget.cpp
|
||||
SpaceCadetPinball/TPopupTarget.h
|
||||
SpaceCadetPinball/TRamp.cpp
|
||||
SpaceCadetPinball/TRamp.h
|
||||
SpaceCadetPinball/TRollover.cpp
|
||||
SpaceCadetPinball/TRollover.h
|
||||
SpaceCadetPinball/TSink.cpp
|
||||
SpaceCadetPinball/TSink.h
|
||||
SpaceCadetPinball/TSoloTarget.cpp
|
||||
SpaceCadetPinball/TSoloTarget.h
|
||||
SpaceCadetPinball/TSound.cpp
|
||||
SpaceCadetPinball/TSound.h
|
||||
SpaceCadetPinball/TTableLayer.cpp
|
||||
SpaceCadetPinball/TTableLayer.h
|
||||
SpaceCadetPinball/TTextBox.cpp
|
||||
SpaceCadetPinball/TTextBox.h
|
||||
SpaceCadetPinball/TTextBoxMessage.cpp
|
||||
SpaceCadetPinball/TTextBoxMessage.h
|
||||
SpaceCadetPinball/TTimer.cpp
|
||||
SpaceCadetPinball/TTimer.h
|
||||
SpaceCadetPinball/TTripwire.cpp
|
||||
SpaceCadetPinball/TTripwire.h
|
||||
SpaceCadetPinball/TWall.cpp
|
||||
SpaceCadetPinball/TWall.h
|
||||
SpaceCadetPinball/winmain.cpp
|
||||
SpaceCadetPinball/winmain.h
|
||||
SpaceCadetPinball/zdrv.cpp
|
||||
SpaceCadetPinball/zdrv.h
|
||||
SpaceCadetPinball/imconfig.h
|
||||
SpaceCadetPinball/imgui_internal.h
|
||||
SpaceCadetPinball/imgui.cpp
|
||||
SpaceCadetPinball/imgui.h
|
||||
SpaceCadetPinball/imgui_sdl.cpp
|
||||
SpaceCadetPinball/imgui_sdl.h
|
||||
SpaceCadetPinball/imgui_draw.cpp
|
||||
SpaceCadetPinball/imgui_widgets.cpp
|
||||
SpaceCadetPinball/imgui_tables.cpp
|
||||
SpaceCadetPinball/imgui_demo.cpp
|
||||
SpaceCadetPinball/imgui_impl_sdl.cpp
|
||||
SpaceCadetPinball/imgui_impl_sdl.h
|
||||
SpaceCadetPinball/imstb_textedit.h
|
||||
SpaceCadetPinball/imstb_rectpack.h
|
||||
SpaceCadetPinball/imstb_truetype.h
|
||||
)
|
||||
|
||||
# On Windows, include resource file with the icon
|
||||
if(WIN32)
|
||||
set_source_files_properties(SpaceCadetPinball/SpaceCadetPinball.rc LANGUAGE RC)
|
||||
list(APPEND SOURCE_FILES SpaceCadetPinball/SpaceCadetPinball.rc)
|
||||
endif(WIN32)
|
||||
|
||||
add_executable(SpaceCadetPinball ${SOURCE_FILES})
|
||||
|
||||
# Skip pch on foreign code
|
||||
set_source_files_properties(
|
||||
SpaceCadetPinball/imgui.cpp
|
||||
SpaceCadetPinball/imgui_sdl.cpp
|
||||
SpaceCadetPinball/imgui_draw.cpp
|
||||
SpaceCadetPinball/imgui_widgets.cpp
|
||||
SpaceCadetPinball/imgui_tables.cpp
|
||||
SpaceCadetPinball/imgui_demo.cpp
|
||||
SpaceCadetPinball/imgui_impl_sdl.cpp
|
||||
PROPERTIES SKIP_PRECOMPILE_HEADERS 1
|
||||
)
|
||||
|
||||
if(${CMAKE_VERSION} VERSION_GREATER "3.16.0" OR ${CMAKE_VERSION} VERSION_EQUAL "3.16.0")
|
||||
target_precompile_headers(SpaceCadetPinball
|
||||
PUBLIC
|
||||
SpaceCadetPinball/pch.h
|
||||
)
|
||||
endif()
|
||||
|
||||
target_link_libraries(SpaceCadetPinball ${SDL2_LIBRARY} ${SDL2_MIXER_LIBRARY})
|
||||
|
||||
# On Windows, copy DLL to output
|
||||
if(WIN32)
|
||||
list(GET SDL2_LIBRARY -1 SDL2_DLL_PATH)
|
||||
list(GET SDL2_MIXER_LIBRARY -1 SDL2_MIXER_DLL_PATH)
|
||||
get_filename_component(SDL2_DLL_PATH ${SDL2_DLL_PATH} DIRECTORY)
|
||||
get_filename_component(SDL2_MIXER_DLL_PATH ${SDL2_MIXER_DLL_PATH} DIRECTORY)
|
||||
if(MINGW)
|
||||
string(REGEX REPLACE "lib$" "bin" SDL2_DLL_PATH ${SDL2_DLL_PATH})
|
||||
string(REGEX REPLACE "lib$" "bin" SDL2_MIXER_DLL_PATH ${SDL2_MIXER_DLL_PATH})
|
||||
endif()
|
||||
message(STATUS "copy paths='${SDL2_DLL_PATH}' '${SDL2_MIXER_DLL_PATH}'")
|
||||
add_custom_command(TARGET SpaceCadetPinball POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${SDL2_DLL_PATH}/SDL2.dll" $<TARGET_FILE_DIR:SpaceCadetPinball>
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${SDL2_MIXER_DLL_PATH}/SDL2_mixer.dll" $<TARGET_FILE_DIR:SpaceCadetPinball>
|
||||
)
|
||||
endif()
|
||||
173
CMakeModules/FindSDL2.cmake
Normal file
173
CMakeModules/FindSDL2.cmake
Normal file
@@ -0,0 +1,173 @@
|
||||
|
||||
# This module defines
|
||||
# SDL2_LIBRARY, the name of the library to link against
|
||||
# SDL2_FOUND, if false, do not try to link to SDL2
|
||||
# SDL2_INCLUDE_DIR, where to find SDL.h
|
||||
#
|
||||
# This module responds to the the flag:
|
||||
# SDL2_BUILDING_LIBRARY
|
||||
# If this is defined, then no SDL2main will be linked in because
|
||||
# only applications need main().
|
||||
# Otherwise, it is assumed you are building an application and this
|
||||
# module will attempt to locate and set the the proper link flags
|
||||
# as part of the returned SDL2_LIBRARY variable.
|
||||
#
|
||||
# Don't forget to include SDLmain.h and SDLmain.m your project for the
|
||||
# OS X framework based version. (Other versions link to -lSDL2main which
|
||||
# this module will try to find on your behalf.) Also for OS X, this
|
||||
# module will automatically add the -framework Cocoa on your behalf.
|
||||
#
|
||||
#
|
||||
# Additional Note: If you see an empty SDL2_LIBRARY_TEMP in your configuration
|
||||
# and no SDL2_LIBRARY, it means CMake did not find your SDL2 library
|
||||
# (SDL2.dll, libsdl2.so, SDL2.framework, etc).
|
||||
# Set SDL2_LIBRARY_TEMP to point to your SDL2 library, and configure again.
|
||||
# Similarly, if you see an empty SDL2MAIN_LIBRARY, you should set this value
|
||||
# as appropriate. These values are used to generate the final SDL2_LIBRARY
|
||||
# variable, but when these values are unset, SDL2_LIBRARY does not get created.
|
||||
#
|
||||
#
|
||||
# $SDL2DIR is an environment variable that would
|
||||
# correspond to the ./configure --prefix=$SDL2DIR
|
||||
# used in building SDL2.
|
||||
# l.e.galup 9-20-02
|
||||
#
|
||||
# Modified by Eric Wing.
|
||||
# Added code to assist with automated building by using environmental variables
|
||||
# and providing a more controlled/consistent search behavior.
|
||||
# Added new modifications to recognize OS X frameworks and
|
||||
# additional Unix paths (FreeBSD, etc).
|
||||
# Also corrected the header search path to follow "proper" SDL guidelines.
|
||||
# Added a search for SDL2main which is needed by some platforms.
|
||||
# Added a search for threads which is needed by some platforms.
|
||||
# Added needed compile switches for MinGW.
|
||||
#
|
||||
# On OSX, this will prefer the Framework version (if found) over others.
|
||||
# People will have to manually change the cache values of
|
||||
# SDL2_LIBRARY to override this selection or set the CMake environment
|
||||
# CMAKE_INCLUDE_PATH to modify the search paths.
|
||||
#
|
||||
# Note that the header path has changed from SDL2/SDL.h to just SDL.h
|
||||
# This needed to change because "proper" SDL convention
|
||||
# is #include "SDL.h", not <SDL2/SDL.h>. This is done for portability
|
||||
# reasons because not all systems place things in SDL2/ (see FreeBSD).
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2003-2009 Kitware, Inc.
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# (To distribute this file outside of CMake, substitute the full
|
||||
# License text for the above reference.)
|
||||
|
||||
# message("<FindSDL2.cmake>")
|
||||
|
||||
SET(SDL2_SEARCH_PATHS
|
||||
~/Library/Frameworks
|
||||
/Library/Frameworks
|
||||
/usr/local
|
||||
/usr
|
||||
/sw # Fink
|
||||
/opt/local # DarwinPorts
|
||||
/opt/csw # Blastwave
|
||||
/opt
|
||||
${SDL2_PATH}
|
||||
)
|
||||
|
||||
FIND_PATH(SDL2_INCLUDE_DIR SDL.h
|
||||
HINTS
|
||||
$ENV{SDL2DIR}
|
||||
PATH_SUFFIXES include/SDL2 include SDL2
|
||||
PATHS ${SDL2_SEARCH_PATHS}
|
||||
)
|
||||
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(PATH_SUFFIXES lib64 lib/x64 lib)
|
||||
else()
|
||||
set(PATH_SUFFIXES lib/x86 lib)
|
||||
endif()
|
||||
|
||||
FIND_LIBRARY(SDL2_LIBRARY_TEMP
|
||||
NAMES SDL2
|
||||
HINTS
|
||||
$ENV{SDL2DIR}
|
||||
PATH_SUFFIXES ${PATH_SUFFIXES}
|
||||
PATHS ${SDL2_SEARCH_PATHS}
|
||||
)
|
||||
|
||||
IF(NOT SDL2_BUILDING_LIBRARY)
|
||||
IF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework")
|
||||
# Non-OS X framework versions expect you to also dynamically link to
|
||||
# SDL2main. This is mainly for Windows and OS X. Other (Unix) platforms
|
||||
# seem to provide SDL2main for compatibility even though they don't
|
||||
# necessarily need it.
|
||||
FIND_LIBRARY(SDL2MAIN_LIBRARY
|
||||
NAMES SDL2main
|
||||
HINTS
|
||||
$ENV{SDL2DIR}
|
||||
PATH_SUFFIXES ${PATH_SUFFIXES}
|
||||
PATHS ${SDL2_SEARCH_PATHS}
|
||||
)
|
||||
ENDIF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework")
|
||||
ENDIF(NOT SDL2_BUILDING_LIBRARY)
|
||||
|
||||
# SDL2 may require threads on your system.
|
||||
# The Apple build may not need an explicit flag because one of the
|
||||
# frameworks may already provide it.
|
||||
# But for non-OSX systems, I will use the CMake Threads package.
|
||||
IF(NOT APPLE)
|
||||
FIND_PACKAGE(Threads)
|
||||
ENDIF(NOT APPLE)
|
||||
|
||||
# MinGW needs an additional link flag, -mwindows
|
||||
# It's total link flags should look like -lmingw32 -lSDL2main -lSDL2 -mwindows
|
||||
IF(MINGW)
|
||||
SET(MINGW32_LIBRARY mingw32 "-mwindows" CACHE STRING "mwindows for MinGW")
|
||||
ENDIF(MINGW)
|
||||
|
||||
IF(SDL2_LIBRARY_TEMP)
|
||||
# For SDL2main
|
||||
IF(NOT SDL2_BUILDING_LIBRARY)
|
||||
IF(SDL2MAIN_LIBRARY)
|
||||
SET(SDL2_LIBRARY_TEMP ${SDL2MAIN_LIBRARY} ${SDL2_LIBRARY_TEMP})
|
||||
ENDIF(SDL2MAIN_LIBRARY)
|
||||
ENDIF(NOT SDL2_BUILDING_LIBRARY)
|
||||
|
||||
# For OS X, SDL2 uses Cocoa as a backend so it must link to Cocoa.
|
||||
# CMake doesn't display the -framework Cocoa string in the UI even
|
||||
# though it actually is there if I modify a pre-used variable.
|
||||
# I think it has something to do with the CACHE STRING.
|
||||
# So I use a temporary variable until the end so I can set the
|
||||
# "real" variable in one-shot.
|
||||
IF(APPLE)
|
||||
SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} "-framework Cocoa")
|
||||
ENDIF(APPLE)
|
||||
|
||||
# For threads, as mentioned Apple doesn't need this.
|
||||
# In fact, there seems to be a problem if I used the Threads package
|
||||
# and try using this line, so I'm just skipping it entirely for OS X.
|
||||
IF(NOT APPLE)
|
||||
SET(SDL2_LIBRARY_TEMP ${CMAKE_THREAD_LIBS_INIT} ${SDL2_LIBRARY_TEMP})
|
||||
ENDIF(NOT APPLE)
|
||||
|
||||
# For MinGW library
|
||||
IF(MINGW)
|
||||
SET(SDL2_LIBRARY_TEMP ${MINGW32_LIBRARY} ${SDL2_LIBRARY_TEMP})
|
||||
ENDIF(MINGW)
|
||||
|
||||
# Set the final string here so the GUI reflects the final state.
|
||||
SET(SDL2_LIBRARY ${SDL2_LIBRARY_TEMP} CACHE STRING "Where the SDL2 Library can be found")
|
||||
# Set the temp variable to INTERNAL so it is not seen in the CMake GUI
|
||||
SET(SDL2_LIBRARY_TEMP "${SDL2_LIBRARY_TEMP}" CACHE INTERNAL "")
|
||||
ENDIF(SDL2_LIBRARY_TEMP)
|
||||
|
||||
# message("</FindSDL2.cmake>")
|
||||
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2 REQUIRED_VARS SDL2_LIBRARY SDL2_INCLUDE_DIR)
|
||||
100
CMakeModules/FindSDL2_mixer.cmake
Normal file
100
CMakeModules/FindSDL2_mixer.cmake
Normal file
@@ -0,0 +1,100 @@
|
||||
# Locate SDL_MIXER library
|
||||
#
|
||||
# This module defines:
|
||||
#
|
||||
# ::
|
||||
#
|
||||
# SDL2_MIXER_LIBRARIES, the name of the library to link against
|
||||
# SDL2_MIXER_INCLUDE_DIRS, where to find the headers
|
||||
# SDL2_MIXER_FOUND, if false, do not try to link against
|
||||
# SDL2_MIXER_VERSION_STRING - human-readable string containing the version of SDL_MIXER
|
||||
#
|
||||
#
|
||||
#
|
||||
# For backward compatibility the following variables are also set:
|
||||
#
|
||||
# ::
|
||||
#
|
||||
# SDLMIXER_LIBRARY (same value as SDL2_MIXER_LIBRARIES)
|
||||
# SDLMIXER_INCLUDE_DIR (same value as SDL2_MIXER_INCLUDE_DIRS)
|
||||
# SDLMIXER_FOUND (same value as SDL2_MIXER_FOUND)
|
||||
#
|
||||
#
|
||||
#
|
||||
# $SDLDIR is an environment variable that would correspond to the
|
||||
# ./configure --prefix=$SDLDIR used in building SDL.
|
||||
#
|
||||
# Created by Eric Wing. This was influenced by the FindSDL.cmake
|
||||
# module, but with modifications to recognize OS X frameworks and
|
||||
# additional Unix paths (FreeBSD, etc).
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2005-2009 Kitware, Inc.
|
||||
# Copyright 2012 Benjamin Eikel
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# (To distribute this file outside of CMake, substitute the full
|
||||
# License text for the above reference.)
|
||||
|
||||
find_path(SDL2_MIXER_INCLUDE_DIR SDL_mixer.h
|
||||
HINTS
|
||||
ENV SDL2MIXERDIR
|
||||
ENV SDL2DIR
|
||||
PATH_SUFFIXES SDL2
|
||||
# path suffixes to search inside ENV{SDLDIR}
|
||||
include/SDL2 include
|
||||
PATHS ${SDL2_MIXER_PATH}
|
||||
)
|
||||
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(VC_LIB_PATH_SUFFIX lib/x64)
|
||||
else()
|
||||
set(VC_LIB_PATH_SUFFIX lib/x86)
|
||||
endif()
|
||||
|
||||
find_library(SDL2_MIXER_LIBRARY
|
||||
NAMES SDL2_mixer
|
||||
HINTS
|
||||
ENV SDL2MIXERDIR
|
||||
ENV SDL2DIR
|
||||
PATH_SUFFIXES lib bin ${VC_LIB_PATH_SUFFIX}
|
||||
PATHS ${SDL2_MIXER_PATH}
|
||||
)
|
||||
|
||||
if(SDL2_MIXER_INCLUDE_DIR AND EXISTS "${SDL2_MIXER_INCLUDE_DIR}/SDL_mixer.h")
|
||||
file(STRINGS "${SDL2_MIXER_INCLUDE_DIR}/SDL_mixer.h" SDL2_MIXER_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SDL_MIXER_MAJOR_VERSION[ \t]+[0-9]+$")
|
||||
file(STRINGS "${SDL2_MIXER_INCLUDE_DIR}/SDL_mixer.h" SDL2_MIXER_VERSION_MINOR_LINE REGEX "^#define[ \t]+SDL_MIXER_MINOR_VERSION[ \t]+[0-9]+$")
|
||||
file(STRINGS "${SDL2_MIXER_INCLUDE_DIR}/SDL_mixer.h" SDL2_MIXER_VERSION_PATCH_LINE REGEX "^#define[ \t]+SDL_MIXER_PATCHLEVEL[ \t]+[0-9]+$")
|
||||
string(REGEX REPLACE "^#define[ \t]+SDL_MIXER_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_MIXER_VERSION_MAJOR "${SDL2_MIXER_VERSION_MAJOR_LINE}")
|
||||
string(REGEX REPLACE "^#define[ \t]+SDL_MIXER_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_MIXER_VERSION_MINOR "${SDL2_MIXER_VERSION_MINOR_LINE}")
|
||||
string(REGEX REPLACE "^#define[ \t]+SDL_MIXER_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL2_MIXER_VERSION_PATCH "${SDL2_MIXER_VERSION_PATCH_LINE}")
|
||||
set(SDL2_MIXER_VERSION_STRING ${SDL2_MIXER_VERSION_MAJOR}.${SDL2_MIXER_VERSION_MINOR}.${SDL2_MIXER_VERSION_PATCH})
|
||||
unset(SDL2_MIXER_VERSION_MAJOR_LINE)
|
||||
unset(SDL2_MIXER_VERSION_MINOR_LINE)
|
||||
unset(SDL2_MIXER_VERSION_PATCH_LINE)
|
||||
unset(SDL2_MIXER_VERSION_MAJOR)
|
||||
unset(SDL2_MIXER_VERSION_MINOR)
|
||||
unset(SDL2_MIXER_VERSION_PATCH)
|
||||
endif()
|
||||
|
||||
set(SDL2_MIXER_LIBRARIES ${SDL2_MIXER_LIBRARY})
|
||||
set(SDL2_MIXER_INCLUDE_DIRS ${SDL2_MIXER_INCLUDE_DIR})
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2_mixer
|
||||
REQUIRED_VARS SDL2_MIXER_LIBRARIES SDL2_MIXER_INCLUDE_DIRS
|
||||
VERSION_VAR SDL2_MIXER_VERSION_STRING)
|
||||
|
||||
# for backward compatibility
|
||||
set(SDLMIXER_LIBRARY ${SDL2_MIXER_LIBRARIES})
|
||||
set(SDLMIXER_INCLUDE_DIR ${SDL2_MIXER_INCLUDE_DIRS})
|
||||
set(SDLMIXER_FOUND ${SDL2_MIXER_FOUND})
|
||||
|
||||
mark_as_advanced(SDL2_MIXER_LIBRARY SDL2_MIXER_INCLUDE_DIR)
|
||||
59
CMakeSettings.json
Normal file
59
CMakeSettings.json
Normal file
@@ -0,0 +1,59 @@
|
||||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "x64-Debug",
|
||||
"generator": "Ninja",
|
||||
"configurationType": "Debug",
|
||||
"inheritEnvironments": [ "msvc_x64_x64" ],
|
||||
"buildRoot": "${projectDir}\\out\\build\\${name}",
|
||||
"installRoot": "${projectDir}\\out\\install\\${name}",
|
||||
"cmakeCommandArgs": "",
|
||||
"buildCommandArgs": "",
|
||||
"ctestCommandArgs": ""
|
||||
},
|
||||
{
|
||||
"name": "x86-Debug",
|
||||
"generator": "Ninja",
|
||||
"configurationType": "Debug",
|
||||
"buildRoot": "${projectDir}\\out\\build\\${name}",
|
||||
"installRoot": "${projectDir}\\out\\install\\${name}",
|
||||
"cmakeCommandArgs": "",
|
||||
"buildCommandArgs": "",
|
||||
"ctestCommandArgs": "",
|
||||
"inheritEnvironments": [ "msvc_x86" ]
|
||||
},
|
||||
{
|
||||
"name": "x86-Release",
|
||||
"generator": "Ninja",
|
||||
"configurationType": "Release",
|
||||
"buildRoot": "${projectDir}\\out\\build\\${name}",
|
||||
"installRoot": "${projectDir}\\out\\install\\${name}",
|
||||
"cmakeCommandArgs": "-DCMAKE_WIN32_EXECUTABLE:BOOL=1",
|
||||
"buildCommandArgs": "",
|
||||
"ctestCommandArgs": "",
|
||||
"inheritEnvironments": [ "msvc_x86" ]
|
||||
},
|
||||
{
|
||||
"name": "x64-Release",
|
||||
"generator": "Ninja",
|
||||
"configurationType": "Release",
|
||||
"buildRoot": "${projectDir}\\out\\build\\${name}",
|
||||
"installRoot": "${projectDir}\\out\\install\\${name}",
|
||||
"cmakeCommandArgs": "-DCMAKE_WIN32_EXECUTABLE:BOOL=1",
|
||||
"buildCommandArgs": "",
|
||||
"ctestCommandArgs": "",
|
||||
"inheritEnvironments": [ "msvc_x64_x64" ]
|
||||
},
|
||||
{
|
||||
"name": "x86-Release-WinXP",
|
||||
"generator": "Visual Studio 16 2019",
|
||||
"configurationType": "Release",
|
||||
"buildRoot": "${projectDir}\\out\\build\\${name}",
|
||||
"installRoot": "${projectDir}\\out\\install\\${name}",
|
||||
"cmakeCommandArgs": "-DCMAKE_WIN32_EXECUTABLE:BOOL=1 -T v141_xp",
|
||||
"buildCommandArgs": "",
|
||||
"ctestCommandArgs": "",
|
||||
"inheritEnvironments": [ "msvc_x86" ]
|
||||
}
|
||||
]
|
||||
}
|
||||
11
CONTRIBUTING.md
Normal file
11
CONTRIBUTING.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# Issues
|
||||
Don’t forget to mention game version, which release or branch it came from.\
|
||||
Source port issues are handled in their respective repositories.
|
||||
|
||||
# Pull request
|
||||
No source ports in main repository.\
|
||||
I have no way to test and maintain most of them.\
|
||||
The best I can do is to add a link.
|
||||
|
||||
There is no guaranty that any particular PR will be accepted.\
|
||||
If you are unsure, ask first, make PR second.
|
||||
@@ -1,3 +0,0 @@
|
||||
rc /Fo.\DrMem\SpaceCadetPinball.res ".\SpaceCadetPinball\SpaceCadetPinball.rc"
|
||||
|
||||
cl /Zi /MT /EHsc /O /Ob0 /cgthreads4 /Fo.\DrMem\ /Fe.\DrMem\myapp.exe ".\SpaceCadetPinball\*.cpp" Comctl32.lib Winmm.lib Htmlhelp.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ".\DrMem\SpaceCadetPinball.res"
|
||||
@@ -39,21 +39,21 @@ Type Meaning/comments
|
||||
9 String (content)
|
||||
10 Array of 16bits integer values
|
||||
11 Array of 32bits floating point values (collision box, ...)
|
||||
12 16 bpp bitmap (Heightmap?)
|
||||
12 16 bpp bitmap (zMap)
|
||||
|
||||
|
||||
//-- 8bpp bitmap data header --//
|
||||
+0: Unknown (0) BYTE
|
||||
+0: Resolution BYTE 0=640x480, 1=800x600, 2=1024x768, -1=Load in all resolutions
|
||||
+1: Width WORD
|
||||
+3: Height WORD
|
||||
+5: X position WORD
|
||||
+7 Y position WORD
|
||||
+9: Size of bitmap DWORD
|
||||
+13: Unknown (1) BYTE
|
||||
+13: Flags BYTE bit0=Raw bmp align; bit1=DibBitmap, raw when 0; bit2=Spliced bitmap (aka skipline), combines bmp and zMap in RLE-like way
|
||||
+14: Bitmap data BYTE*(DWORD@+9)
|
||||
|
||||
|
||||
//-- 16bpp bitmap data header --//
|
||||
//-- 16bpp zMap data header --//
|
||||
+0: Width WORD
|
||||
+2: Height WORD
|
||||
+4: Pitch/2 WORD
|
||||
@@ -62,6 +62,16 @@ Type Meaning/comments
|
||||
+12: Unknown (80) WORD
|
||||
+14: Bitmap data BYTE*(DWORD@+9)
|
||||
|
||||
//-- 16bpp zMap data header full tilt --//
|
||||
+0: Resolution BYTE 0=640x480, 1=800x600, 2=1024x768, -1=Load in all resolutions
|
||||
+1: Width WORD
|
||||
+3: Height WORD
|
||||
+5: Pitch/2 WORD
|
||||
+7: Unknown (0) DWORD
|
||||
+11: Unknown (0) WORD
|
||||
+13: Unknown (80) WORD
|
||||
+15: Bitmap data BYTE*(DWORD@+9)
|
||||
|
||||
|
||||
//-- Pinball 3D remarkable groups --//
|
||||
|
||||
|
||||
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020-2021 Andrey Muzychenko
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
91
README.md
Normal file
91
README.md
Normal file
@@ -0,0 +1,91 @@
|
||||
<!-- markdownlint-disable-file MD033 -->
|
||||
|
||||
# SpaceCadetPinball
|
||||
|
||||
## Summary
|
||||
|
||||
Reverse engineering of `3D Pinball for Windows – Space Cadet`, a game bundled with Windows.
|
||||
|
||||
## How to play
|
||||
|
||||
Place compiled executable into a folder containing original game resources (not included).\
|
||||
Supports data files from Windows and Full Tilt versions of the game.
|
||||
|
||||
## Known source ports
|
||||
|
||||
| Platform | Author | URL |
|
||||
| ------------------ | --------------- | ---------------------------------------------------------------------------------------------------------- |
|
||||
| PS Vita | Axiom | <https://github.com/suicvne/SpaceCadetPinball_Vita> |
|
||||
| Emscripten | alula | <https://github.com/alula/SpaceCadetPinball> <br> Play online: <https://alula.github.io/SpaceCadetPinball> |
|
||||
| Nintendo Switch | averne | <https://github.com/averne/SpaceCadetPinball-NX> |
|
||||
| webOS TV | mariotaku | <https://github.com/webosbrew/SpaceCadetPinball> |
|
||||
| Android (WIP) | Iscle | https://github.com/Iscle/SpaceCadetPinball |
|
||||
| Nintendo Wii | MaikelChan | https://github.com/MaikelChan/SpaceCadetPinball |
|
||||
| Nintendo 3DS | MaikelChan | https://github.com/MaikelChan/SpaceCadetPinball/tree/3ds |
|
||||
| Nintendo Wii U | IntriguingTiles | https://github.com/IntriguingTiles/SpaceCadetPinball-WiiU |
|
||||
|
||||
Platforms covered by this project: desktop Windows, Linux and macOS.
|
||||
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
|
||||
## Source
|
||||
|
||||
* `pinball.exe` from `Windows XP` (SHA-1 `2A5B525E0F631BB6107639E2A69DF15986FB0D05`) and its public PDB
|
||||
* `CADET.EXE` 32bit version from `Full Tilt! Pinball` (SHA-1 `3F7B5699074B83FD713657CD94671F2156DBEDC4`)
|
||||
|
||||
## Tools used
|
||||
|
||||
`Ghidra`, `Ida`, `Visual Studio`
|
||||
|
||||
## What was done
|
||||
|
||||
* All structures were populated, globals and locals named.
|
||||
* All subs were decompiled, C pseudo code was converted to compilable C++. Loose (namespace?) subs were assigned to classes.
|
||||
|
||||
## Compiling
|
||||
|
||||
Project uses `C++11` and depends on `SDL2` libs.
|
||||
|
||||
### On Windows
|
||||
|
||||
Download and unpack devel packages for `SDL2` and `SDL2_mixer`.\
|
||||
Set paths to them in `CMakeLists.txt`, see suggested placement in `/Libs`.\
|
||||
Compile with Visual Studio; tested with 2019.
|
||||
|
||||
### On Linux
|
||||
|
||||
Install devel packages for `SDL2` and `SDL2_mixer`.\
|
||||
Compile with CMake; tested with GCC 10, Clang 11.\
|
||||
To cross-compile for Windows, install a 64-bit version of mingw and its `SDL2` and `SDL2_mixer` distributions, then use the `mingwcc.cmake` toolchain.
|
||||
|
||||
### On macOS
|
||||
|
||||
* **Homebrew**: Install the `SDL2`, `SDL2_mixer` homebrew packages.
|
||||
* **MacPorts**: Install the `libSDL2`, `libSDL2_mixer` macports packages.
|
||||
|
||||
Compile with CMake. Ensure that `CMAKE_OSX_ARCHITECTURES` variable is set for either `x86_64` Apple Intel or `arm64` for Apple Silicon.
|
||||
|
||||
Tested with: macOS Big Sur (Intel) with Xcode 13 & macOS Montery Beta (Apple Silicon) with Xcode 13.
|
||||
|
||||
## Plans
|
||||
|
||||
* ~~Decompile original game~~
|
||||
* ~~Resizable window, scaled graphics~~
|
||||
* ~~Loader for high-res sprites from CADET.DAT~~
|
||||
* Misc features of Full Tilt: 3 music tracks, multiball, centered textboxes, etc.
|
||||
* Cross-platform port
|
||||
* Using SDL2, SDL2_mixer, ImGui
|
||||
* Maybe: Android port
|
||||
* Maybe x2: support for other two tables
|
||||
* Table specific BL (control interactions and missions) is hardcoded, othere parts might be also patched
|
||||
|
||||
## On 64-bit bug that killed the game
|
||||
|
||||
I did not find it, decompiled game worked in x64 mode on the first try.\
|
||||
It was either lost in decompilation or introduced in x64 port/not present in x86 build.\
|
||||
Based on public description of the bug (no ball collision), I guess that the bug was in `TEdgeManager::TestGridBox`
|
||||
@@ -1,31 +0,0 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.28307.705
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SpaceCadetPinball", "SpaceCadetPinball\SpaceCadetPinball.vcxproj", "{F7B78CC7-6984-4F79-9486-ABCF87DF9F06}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{F7B78CC7-6984-4F79-9486-ABCF87DF9F06}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{F7B78CC7-6984-4F79-9486-ABCF87DF9F06}.Debug|x64.Build.0 = Debug|x64
|
||||
{F7B78CC7-6984-4F79-9486-ABCF87DF9F06}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{F7B78CC7-6984-4F79-9486-ABCF87DF9F06}.Debug|x86.Build.0 = Debug|Win32
|
||||
{F7B78CC7-6984-4F79-9486-ABCF87DF9F06}.Release|x64.ActiveCfg = Release|x64
|
||||
{F7B78CC7-6984-4F79-9486-ABCF87DF9F06}.Release|x64.Build.0 = Release|x64
|
||||
{F7B78CC7-6984-4F79-9486-ABCF87DF9F06}.Release|x86.ActiveCfg = Release|Win32
|
||||
{F7B78CC7-6984-4F79-9486-ABCF87DF9F06}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {4B620E0B-FD42-4AEC-BC4A-261C1669A1B5}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
46
SpaceCadetPinball/EmbeddedData.cpp
Normal file
46
SpaceCadetPinball/EmbeddedData.cpp
Normal file
@@ -0,0 +1,46 @@
|
||||
#include "EmbeddedData.h"
|
||||
|
||||
#if 1
|
||||
// File: './PB_MSGFT.bin' (21702 bytes)
|
||||
// Exported using binary_to_compressed_c.cpp
|
||||
const char EmbeddedData::PB_MSGFT_bin_compressed_data_base85[5380 + 1] =
|
||||
"7])#######>s+cc'/###Y[fi'.Y`+V*KI@%CtjT%QRR8%D[eW$G$^m&MQ>3'QK#n&FnJm&Vp:0(SWPN'SgYn&E09q%`sYn&V9B6&Z#dn&Hnj5&8uhV$Q?p2'L0K6&;@@<$SA`.2EIes$"
|
||||
"RTp6&A.MZ#?@R8%]IN:-42$4CT5(a4`%5DN$rJfLe7^-#`cb*&]u#K262Q_/CR*a4qTjjMHug;-PgRfM-sJfL9#?9RqM>=-/WDa->?1I$[R/qLuqJfLxj/gLPCg;-r28r7H-ge$wKiWh"
|
||||
"vR.(8.C@lL/<T4MnLT_-VeJe?G-Cx9BEwcMYV$2Mbo4VMm4`;-#K5p%o-L&#*rE2C]x+@'aY.FRpjot7kXjJ2'CDiL)e./M^c'hM2s@/M):*NMt3*NM[i,aOcHLaP7?K4MI1$##0ucDN"
|
||||
")J7FN7^e*N4s(eMcPi+8VZKd4^dTd%_IAgWJCSrL>r&gL-0pKN?lgwL[BCTM5>UkL]`kgMw3US->aDY$,oF	&j-HA3nw'/%=2C:FW'8..w-$ae`n*a2Kwp:(t-$X<8w^V`w_/*TKs-"
|
||||
";c>]OW>pgLSHJ_%=0[GMZMFgMmZGhN>4ZtMsg&gL%o^wL)<N;-`2<r&6lNh#2dNgL8]&,Mdj/,MmM&jL5/K;-Na+p7*O(C&4*'a4exMQ(*k2b$k9Em8W.=2C.bIgj-e$AOZ$Qt$u-d,M"
|
||||
"]mC#8rKXk4^eFX(_4+X_xDe'&+rVF7o)I&#.@T(/D85gj;aIqe9[?29#RGf$ZG^;%(/lJ2A/#dM-,r]$m4qP8.biQj_A5W-m'14+m[(Rs6]f>e6#%'Qg@c(NAvYT%Lc68%WcU4+%pwTM"
|
||||
"3nf8RF:g1We=0W$c%q44SR%UM(nj-$_')B6-&R]4vlm*Mw7gV-1?=$g1cap9>;)6Ms=UkL8L)^%Q`1IN,Dn]-ICHh,flTq)s?[o#Ov1b91_ZGMW($a$Xl1s)?ESw.`EqS-n5TW&goD*8"
|
||||
"9[o?9r3R4$LjYI8n2?2CNT3hc)N:(&%6l'&fDxGMi1$##2j(/NMxGp79r*C9Y&o8Bdh8x0fbMmLkv^)&qwuND;t#hO?mxC%*vbJ2jlW*I2.=2C3[;dMtk?m%Z-'TR[u,JWj>Lh$'j#n8"
|
||||
"`=ujDCQ@J&GeJR9Dfd--eIi,i(]^@%71pauR?VIM)NiIMa6`;-2][N'=,HXCh4`/:lwLG'7i=k#C[-L,$oi/:XaAQ(por''<3,d;kRF&#,56vPnbR'M13oj%nSZEcXG:@-/g#pL;2669"
|
||||
"4WIvRsv]O&LwQHM3l_;-TD[V9R;5r)j4<?[Kc_x&7b4H;fVdX1FIuwTDTIgs<:#-M[lk0MGiF58<P(C&?/%*<[x7RNPrJ&#dOl63[bR5'U62HO&ANf%qvedMHdfZMdL?.'1>NE5:t4X8"
|
||||
"^/l3+Z#_K:7,G$IR.V^)E]JF%wY'q7o&Xt&mV(J;ptLQ(v>Y1'xwvq72F?T0EdRf&=$Rd=oNOg$&;mVQjQn?Gq['dk>IY)NJ27BO`<G-&$JZQ8jbGmU#/a+&vh-'v.xJk$C7+E<^V?hG"
|
||||
"dew$I?##@&3+G&#v5'q7jXFuDb7t?wctq)Z&'U4ZeMT2Vb8.M>r)aF749_4Y_-11jv7U-W&H9n7mL.iL;-o_)+O08)>&=]4^Z`K[r7t9#f$^t7j91r,QqSILQ89aTx9/p/hLX%co7"
|
||||
"rr;p&6*Mb%a,#?POJri%XKxI4A.Eu$ZArt8`97r72T):2X[x&=8GWX(l0^&=3SaJ2R6Q&#a;;6&*]iO9q;H*5?rMY$V)9O$<,Dh:trF_JNx&?>0dY,.h5*g$BC5v([3p6EJs#t&_DIu%"
|
||||
"l5A@':GuP8BD[`&V'/W-hs+^ZrT<j&AC1O+c3Ke=)pul&a)i#>2qF&#t`V^=mb3dXkx/W&WCCgLV8UM9ew4oh;#Bgh;Kas-#`?Q8]JeKul^]m8ctB6X%1fN^#qR<^LFPa*vp(?>?Lc'&"
|
||||
"?Swa<=Mc'&U2u`4w080:h%dm:draZ%U_%?P1_W3M#>w.%?Pm7$)N?@-`bPl$uQh'&]ZDA>fa(4Dq#1a)+a;i#I;[#>G27w%l0=S,=%h)&D=57*dR6@.[?kc%Ia(E<#kPFYb/3M2#D*F."
|
||||
"i<,UVYB<ia.(o(#iDbJ2%+/L,+m[&#[8=L3'_aNMms7jLn'j*OHi`k=k=Uk+rJbJ2)]=Z>oe)vS2.Kg%QRJ^?UbmC?c67l)rTjj&]1lgLNih`<Rbh&?S^3k<?&2Oblx^r9TXQhM.evhL"
|
||||
"rbxh<x;tB8EL]BH;':Q:h6IHF.r]K%CaKH=G8lwM&M9%%W>^q)[T%AOPFJZ$YMg58He`q2I6w:@,[F&#YJ7#:s8fdMM_%Z>]8M'S/8D_6.;jbMa.h1&`d8m8@C-tJ]6^w'6kv;]cdTD&"
|
||||
"gv7*P`Bbc%9*l8KZ@,6;n<nw'QqnP']22*<q>)F7K.4e;/6F2aYML@--;ZT%Z-DIm`KJ<-?22$Xp&Z7@AK@kX;-FQ85ohKaa.k<9wi4ed]XJQ(d@sv7f3i/<]gMeMk+V'F>]ZYo)kMB%"
|
||||
"P^mkie1Fp=Q]2U2i$a#P;.r.*QD>Q8?Wi[(fp.M$s$&(SdVJT@bq):i/2u-MQ;6L-TV,<-9K$n:glR0<,k<nL4%3JNRXr2%K25O4Vs]E-27Dt--D5LMup+x9[R=5r4uMV8-T_Lj,%$t&"
|
||||
"1N'q#Dju#[HMGp'2G2e#MB;*Qg1rAM:Mxp^Ws:o^Z'?/CWD;,`ZBMH-abHQ%@STBoJpaN3l)P*<T$l?KFeR5'+8>3B&ZaJ2fMhG;HY:_A9TAdM3qB#>B?C[I>Y2m&NIb#>[haJ2@5('O"
|
||||
"^o8V%qfQ^?FtjW;2,j;9RD&e@hg_$'e59U)b=;s%2Q_698exI.DM5Kji033&f]fEW5@a$>aV`sBWbm-NOg9[%u<Wm8HNR[@J$_g%eKan:#>%K;/c`'6)RC`N'AeA-ow,=&k_3TRfnxv$"
|
||||
"n()<-0klw$aeIjMB*;.&@&fJ.DUo,;H(6+Y9N[mfE^A0:^IRqL@PD6MxZN$'.21q7#<fR3`9<dMD+'k$FluDN7oto&J$s58,1?j<Bj8$&pVXmA?N,F>3NoIDf3l3+Q5#Q8erke#?2tHW"
|
||||
"9xMY$Qtr&OfkCX%nou#PV:8Z$i1dm8,%(@0n*7EH5=+nMk`rS@It$@'M9XCf(DSgWZf=k%dZ<aNj4XC,b(jL3BUu)N/K8_%9j#3%MUE1M[ks@<^f/w%@wYL%+Qv-$EdOam:DvP&Kf)F7"
|
||||
"f<0j(OX1=?V7EI-i,]mAUl>QqYTc<%Q4_$f`-<iM#=Sc;7W9XqO=_,M(BbP<;,.@'Q>1n85X?hGidK_mlK8f$Lt@KCDihv@C^Hn:dLDc##bp_-Q[J;gcdAh:8_2cYtoL/;=tq$'^XRvR"
|
||||
"@B`/9Lu%=BWKR3<:kRvRFbG-&BU+a<41bJ2e[SoUAjo?MX'-a&&R[k4C4A_8_RrS&t25394Xk,k(XDY&.Svj9176e4'8]u%&.(B@pM?.%,ABgLs[1]$$SF&#NfBdMmp$>+LqZdM.ih;-"
|
||||
"ba1Q*noHj<w8_@'eBDE)uMSi$v0t3MM/%4C(b1;0&VaBDth'HkAb,e)u^&4+M.^:^wrD''=Lh4++Qt[nS17Y'IGu58=v&EYlE<R%KW;R<'w:Z>R=iJs?0@Y)=%&3MHXWn891[w'@aop7"
|
||||
"JUx>._mko&:V6j9BY%`?=TA?&erCj9OTF&#xR7p&Il:Q8B>u`4]/g;-L=hRAS,=LsLISn&w1aZ@&*9,(lv]Gu)#)f;M4.`AK?`<?2cu/*H0e-7/OO[7aVA/&f%YKN]XV5FNCS8:2tV#&"
|
||||
"HkekL:VL;-t]`t%ax_N9F$w.O$$1<(okXQV?qll$oXwZPsa`a'<rLu]V9(X%BDfcZ+u4)'WNIM$8saH=JU^gLo3Wb$1x9HV-FRjP?hDG-MQ/f-Pr6<-6;c`%-b'9Rtj*CO>i>9'KZ_h#"
|
||||
"^96>DuNT@-1XurCV<@`&oe6N;n##?-eGVD&ftt?0=4vV%^>WAJF%3q%k>k(7Q+x4ARL:a4auH6Mg3%4CGo5mACC$=12^0^#DOUV-8)xZgO=1eZ2e+d;J6G]:lRpX'=)I6TBV+@(Q2r,;"
|
||||
"bwgtoAeYd&TrtGM2T6i$dn;m8:[o(m+?B4&bnsG;DT^_I-l9n$.^d7+_^wGMrnXo&0D]gUfQGNA4`FaIZ>wIf#.q0Ii&i1s`FCAR]ea+h`(x#%#AL'U=R;<t7/97Y^=W<6pgm?33&"
|
||||
"EN[v>B=Wac>bpg%'I49R=,.78DdN)Y1D[A-cCULM&<;Y&qs<NBdmuR_(7emL9*-M;7CYn*eNU`-%sd&''>Rg:@6q=8e(sP:YG,iLf,jlJh&s22](6=*bX]a<UuO&#V.g:CFq<<:_DT;'"
|
||||
"E%dgL`3.s-2mZo@>Fu`4jmlsHvJ]c5,kAY'hgE&OEpvw&A@^B'%;Xk#=3`2;0n`=g/K(w'Zok,M82^m@`:bH=>6r`$p.0QJ;#qDlbS;s?OP5'Z.a%G=NsX0NUQ1X%7Bbm8-<T*YrC3)="
|
||||
"9whv@Avo*E,VNC7+eIm%M4k#>Kdgtq,WOvYaNWhZMOH##TWvNb@(%9rSllV$+^8I%OuBv$`)bJ2UiCQ8gjo6*uS)`%-`W/%?)c;-d&?s%GWRh*@O/w7=$O#Rix,`%`a=&FC6$XLYxDH;"
|
||||
"Y5=2C`Fws7Bhki$MJ$-++`_8RWmU9R$ui$G;6Na,I8g$&g5<NKm=mQqg/mW%5e7QAG+gVgal^)O-iT`$h1?qtQq,KlOeMo>x9f$nwTWJ']jk=-3^^m2vZ8@(#O,W8$Gj9DZRV49/J=P;"
|
||||
"``a;&#pbJ28k)e<?_`xfPn;J:H@xNOWj9hjtlH.'lq8-;L&4TBpL0@%49Tp7SRqw.Rfu<'^<FK:ll)FPwl'LMBIDJD/uwd;%V6XA1<.G:-IbQ)=HJv&ZF--M3v[O.m_=p^)A6wJGUn@'"
|
||||
"SK``-)or4#NImdM.O?a$`nOE<Y0:+?v=PkLN34S2T=B<H=k[1E&8,c'whm;-[f*$%_7MaNZg*`+-jD4:XW_c/Y2nZ>AA`/s+j&BH>:oB&&g1<-N:md$bSYm8#u^7).4H0&q3n0#B[G&#"
|
||||
"%baa*`3t,;Nm>v]^JtC(mC:/%*WN7:aarL7;f[=-XbnHbSm`I&Z?ap7[pZ@1dIa:8FZkL:p,kRM^$lf%92@v&mCeA-XHFK&t/c9BBP)CZSu>*(]G8l#>aD<okffx2c@-c*EUkE<_`fG5"
|
||||
"8Wjb:XgxcPEcZ6)8q&_S/]^GMZr6Tg?oOb*i^qpIUDGn(<UI@ZPbm##S%o,;V^8U)_.idDhTF&##h$<?'s-+6W@-C?k+kx'_MuAO;3r2'NH0K:(._r(PCZY#Ij[1$:j61U$h,A-av4A="
|
||||
"W)Y?e>L'k$XRf2Nn-8V8*lb`69FF3N@uNe+.AYXS9ALPSV/-Y$<H=n/4####";
|
||||
#endif
|
||||
8
SpaceCadetPinball/EmbeddedData.h
Normal file
8
SpaceCadetPinball/EmbeddedData.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
class EmbeddedData
|
||||
{
|
||||
public:
|
||||
static const char PB_MSGFT_bin_compressed_data_base85[5380 + 1];
|
||||
};
|
||||
362
SpaceCadetPinball/GroupData.cpp
Normal file
362
SpaceCadetPinball/GroupData.cpp
Normal file
@@ -0,0 +1,362 @@
|
||||
#include "pch.h"
|
||||
|
||||
#include "GroupData.h"
|
||||
|
||||
#include "EmbeddedData.h"
|
||||
#include "fullscrn.h"
|
||||
#include "gdrv.h"
|
||||
#include "pb.h"
|
||||
#include "pinball.h"
|
||||
#include "zdrv.h"
|
||||
|
||||
|
||||
EntryData::~EntryData()
|
||||
{
|
||||
if (Buffer)
|
||||
{
|
||||
if (EntryType == FieldTypes::Bitmap8bit)
|
||||
{
|
||||
delete reinterpret_cast<gdrv_bitmap8*>(Buffer);
|
||||
}
|
||||
else if (EntryType == FieldTypes::Bitmap16bit)
|
||||
{
|
||||
delete reinterpret_cast<zmap_header_type*>(Buffer);
|
||||
}
|
||||
else
|
||||
delete[] Buffer;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GroupData::GroupData(int groupId)
|
||||
{
|
||||
GroupId = groupId;
|
||||
}
|
||||
|
||||
void GroupData::AddEntry(EntryData* entry)
|
||||
{
|
||||
auto addEntry = true;
|
||||
switch (entry->EntryType)
|
||||
{
|
||||
case FieldTypes::GroupName:
|
||||
GroupName = entry->Buffer;
|
||||
break;
|
||||
case FieldTypes::Bitmap8bit:
|
||||
{
|
||||
auto srcBmp = reinterpret_cast<gdrv_bitmap8*>(entry->Buffer);
|
||||
if (srcBmp->BitmapType == BitmapTypes::Spliced)
|
||||
{
|
||||
// Get rid of spliced bitmap early on, to simplify render pipeline
|
||||
auto bmp = new gdrv_bitmap8(srcBmp->Width, srcBmp->Height, srcBmp->Width);
|
||||
auto zMap = new zmap_header_type(srcBmp->Width, srcBmp->Height, srcBmp->Width);
|
||||
SplitSplicedBitmap(*srcBmp, *bmp, *zMap);
|
||||
|
||||
NeedsSort = true;
|
||||
addEntry = false;
|
||||
AddEntry(new EntryData(FieldTypes::Bitmap8bit, reinterpret_cast<char*>(bmp)));
|
||||
AddEntry(new EntryData(FieldTypes::Bitmap16bit, reinterpret_cast<char*>(zMap)));
|
||||
delete entry;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetBitmap(srcBmp);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FieldTypes::Bitmap16bit:
|
||||
{
|
||||
SetZMap(reinterpret_cast<zmap_header_type*>(entry->Buffer));
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
|
||||
if (addEntry)
|
||||
Entries.push_back(entry);
|
||||
}
|
||||
|
||||
void GroupData::FinalizeGroup()
|
||||
{
|
||||
if (NeedsSort)
|
||||
{
|
||||
// Entries within a group are sorted by EntryType, in ascending order.
|
||||
// Dat files follow this rule, zMaps inserted in the middle break it.
|
||||
NeedsSort = false;
|
||||
std::sort(Entries.begin(), Entries.end(), [](const EntryData* lhs, const EntryData* rhs)
|
||||
{
|
||||
return lhs->EntryType < rhs->EntryType;
|
||||
});
|
||||
Entries.shrink_to_fit();
|
||||
}
|
||||
}
|
||||
|
||||
gdrv_bitmap8* GroupData::GetBitmap(int resolution) const
|
||||
{
|
||||
return Bitmaps[resolution];
|
||||
}
|
||||
|
||||
zmap_header_type* GroupData::GetZMap(int resolution) const
|
||||
{
|
||||
return ZMaps[resolution];
|
||||
}
|
||||
|
||||
void GroupData::SplitSplicedBitmap(const gdrv_bitmap8& srcBmp, gdrv_bitmap8& bmp, zmap_header_type& zMap)
|
||||
{
|
||||
assertm(srcBmp.BitmapType == BitmapTypes::Spliced, "GroupData: wrong bitmap type");
|
||||
|
||||
std::memset(bmp.IndexedBmpPtr, 0xff, bmp.Stride * bmp.Height);
|
||||
bmp.XPosition = srcBmp.XPosition;
|
||||
bmp.YPosition = srcBmp.YPosition;
|
||||
bmp.Resolution = srcBmp.Resolution;
|
||||
|
||||
zdrv::fill(&zMap, zMap.Width, zMap.Height, 0, 0, 0xFFFF);
|
||||
zMap.Resolution = srcBmp.Resolution;
|
||||
|
||||
auto tableWidth = fullscrn::resolution_array[srcBmp.Resolution].TableWidth;
|
||||
auto src = reinterpret_cast<uint16_t*>(srcBmp.IndexedBmpPtr);
|
||||
auto srcChar = reinterpret_cast<char**>(&src);
|
||||
for (int dstInd = 0;;)
|
||||
{
|
||||
auto stride = static_cast<int16_t>(*src++);
|
||||
if (stride < 0)
|
||||
break;
|
||||
|
||||
// Stride is in terms of dst stride, hardcoded to match vScreen width in current resolution
|
||||
if (stride > bmp.Width)
|
||||
{
|
||||
stride += bmp.Width - tableWidth;
|
||||
assertm(stride >= 0, "Spliced bitmap: negative computed stride");
|
||||
}
|
||||
|
||||
dstInd += stride;
|
||||
for (auto count = *src++; count; count--)
|
||||
{
|
||||
auto depth = *src++;
|
||||
bmp.IndexedBmpPtr[dstInd] = **srcChar;
|
||||
zMap.ZPtr1[dstInd] = depth;
|
||||
|
||||
(*srcChar)++;
|
||||
dstInd++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GroupData::SetBitmap(gdrv_bitmap8* bmp)
|
||||
{
|
||||
assertm(Bitmaps[bmp->Resolution] == nullptr, "GroupData: bitmap override");
|
||||
Bitmaps[bmp->Resolution] = bmp;
|
||||
|
||||
auto zMap = ZMaps[bmp->Resolution];
|
||||
if (zMap)
|
||||
{
|
||||
assertm(bmp->Width == zMap->Width && bmp->Height == zMap->Height,
|
||||
"GroupData: mismatched bitmap/zMap dimensions");
|
||||
}
|
||||
}
|
||||
|
||||
void GroupData::SetZMap(zmap_header_type* zMap)
|
||||
{
|
||||
// Flip zMap to match with flipped non-indexed bitmaps
|
||||
zdrv::FlipZMapHorizontally(*zMap);
|
||||
|
||||
assertm(ZMaps[zMap->Resolution] == nullptr, "GroupData: zMap override");
|
||||
ZMaps[zMap->Resolution] = zMap;
|
||||
|
||||
auto bmp = Bitmaps[zMap->Resolution];
|
||||
if (bmp)
|
||||
{
|
||||
assertm(bmp->Width == zMap->Width && bmp->Height == zMap->Height,
|
||||
"GroupData: mismatched bitmap/zMap dimensions");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DatFile::~DatFile()
|
||||
{
|
||||
for (auto group : Groups)
|
||||
{
|
||||
if (!group)
|
||||
continue;
|
||||
|
||||
for (const auto entry : group->GetEntries())
|
||||
{
|
||||
delete entry;
|
||||
}
|
||||
delete group;
|
||||
}
|
||||
}
|
||||
|
||||
char* DatFile::field(int groupIndex, FieldTypes targetEntryType)
|
||||
{
|
||||
assertm(targetEntryType != FieldTypes::Bitmap8bit && targetEntryType != FieldTypes::Bitmap16bit,
|
||||
"partman: Use specific get for bitmaps");
|
||||
|
||||
auto group = Groups[groupIndex];
|
||||
for (const auto entry : group->GetEntries())
|
||||
{
|
||||
if (entry->EntryType == targetEntryType)
|
||||
{
|
||||
return entry->Buffer;
|
||||
}
|
||||
if (entry->EntryType > targetEntryType)
|
||||
break;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
char* DatFile::field_nth(int groupIndex, FieldTypes targetEntryType, int skipFirstN)
|
||||
{
|
||||
assertm(targetEntryType != FieldTypes::Bitmap8bit && targetEntryType != FieldTypes::Bitmap16bit,
|
||||
"partman: Use specific get for bitmaps");
|
||||
|
||||
auto group = Groups[groupIndex];
|
||||
auto skipCount = 0;
|
||||
for (const auto entry : group->GetEntries())
|
||||
{
|
||||
if (entry->EntryType > targetEntryType)
|
||||
break;
|
||||
if (entry->EntryType == targetEntryType)
|
||||
if (skipCount++ == skipFirstN)
|
||||
return entry->Buffer;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int DatFile::field_size_nth(int groupIndex, FieldTypes targetEntryType, int skipFirstN)
|
||||
{
|
||||
auto group = Groups[groupIndex];
|
||||
auto skipCount = 0;
|
||||
for (const auto entry : group->GetEntries())
|
||||
{
|
||||
if (entry->EntryType > targetEntryType)
|
||||
return 0;
|
||||
if (entry->EntryType == targetEntryType)
|
||||
if (skipCount++ == skipFirstN)
|
||||
return entry->FieldSize;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DatFile::field_size(int groupIndex, FieldTypes targetEntryType)
|
||||
{
|
||||
return field_size_nth(groupIndex, targetEntryType, 0);
|
||||
}
|
||||
|
||||
int DatFile::record_labeled(LPCSTR targetGroupName)
|
||||
{
|
||||
auto targetLength = strlen(targetGroupName);
|
||||
for (int groupIndex = Groups.size() - 1; groupIndex >= 0; --groupIndex)
|
||||
{
|
||||
auto groupName = field(groupIndex, FieldTypes::GroupName);
|
||||
if (!groupName)
|
||||
continue;
|
||||
|
||||
auto index = 0u;
|
||||
for (; index < targetLength; index++)
|
||||
if (targetGroupName[index] != groupName[index])
|
||||
break;
|
||||
if (index == targetLength && !targetGroupName[index] && !groupName[index])
|
||||
return groupIndex;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
char* DatFile::field_labeled(LPCSTR lpString, FieldTypes fieldType)
|
||||
{
|
||||
auto groupIndex = record_labeled(lpString);
|
||||
return groupIndex < 0 ? nullptr : field(groupIndex, fieldType);
|
||||
}
|
||||
|
||||
gdrv_bitmap8* DatFile::GetBitmap(int groupIndex)
|
||||
{
|
||||
auto group = Groups[groupIndex];
|
||||
return group->GetBitmap(fullscrn::GetResolution());
|
||||
}
|
||||
|
||||
zmap_header_type* DatFile::GetZMap(int groupIndex)
|
||||
{
|
||||
auto group = Groups[groupIndex];
|
||||
return group->GetZMap(fullscrn::GetResolution());
|
||||
}
|
||||
|
||||
void DatFile::Finalize()
|
||||
{
|
||||
if (!pb::FullTiltMode)
|
||||
{
|
||||
int groupIndex = record_labeled("pbmsg_ft");
|
||||
assertm(groupIndex < 0, "DatFile: pbmsg_ft is already in .dat");
|
||||
|
||||
// Load 3DPB font into dat to simplify pipeline
|
||||
auto rcData = reinterpret_cast<MsgFont*>(ImFontAtlas::DecompressCompressedBase85Data(
|
||||
EmbeddedData::PB_MSGFT_bin_compressed_data_base85));
|
||||
AddMsgFont(rcData, "pbmsg_ft");
|
||||
IM_FREE(rcData);
|
||||
|
||||
// PINBALL2.MID is an alternative font provided in 3DPB data
|
||||
// Scaled down because it is too large for top text box
|
||||
/*auto file = pinball::make_path_name("PINBALL2.MID");
|
||||
auto fileHandle = fopen(file.c_str(), "rb");
|
||||
fseek(fileHandle, 0, SEEK_END);
|
||||
auto fileSize = static_cast<uint32_t>(ftell(fileHandle));
|
||||
auto rcData = reinterpret_cast<MsgFont*>(new uint8_t[fileSize]);
|
||||
fseek(fileHandle, 0, SEEK_SET);
|
||||
fread(rcData, 1, fileSize, fileHandle);
|
||||
fclose(fileHandle);
|
||||
auto groupId = Groups.back()->GroupId + 1u;
|
||||
AddMsgFont(rcData, "pbmsg_ft");
|
||||
delete[] rcData;
|
||||
for (auto i = groupId; i < Groups.size(); i++)
|
||||
Groups[i]->GetBitmap(0)->ScaleIndexed(0.84f, 0.84f);*/
|
||||
}
|
||||
|
||||
for (auto group : Groups)
|
||||
{
|
||||
group->FinalizeGroup();
|
||||
}
|
||||
}
|
||||
|
||||
void DatFile::AddMsgFont(MsgFont* font, const std::string& fontName)
|
||||
{
|
||||
auto groupId = Groups.back()->GroupId + 1;
|
||||
auto ptrToData = reinterpret_cast<char*>(font->Data);
|
||||
for (auto charInd = 32; charInd < 128; charInd++, groupId++)
|
||||
{
|
||||
auto curChar = reinterpret_cast<MsgFontChar*>(ptrToData);
|
||||
assertm(curChar->Width == font->CharWidths[charInd], "Score: mismatched font width");
|
||||
ptrToData += curChar->Width * font->Height + 1;
|
||||
|
||||
auto bmp = new gdrv_bitmap8(curChar->Width, font->Height, true);
|
||||
auto srcPtr = curChar->Data;
|
||||
auto dstPtr = &bmp->IndexedBmpPtr[bmp->Stride * (bmp->Height - 1)];
|
||||
for (auto y = 0; y < font->Height; ++y)
|
||||
{
|
||||
memcpy(dstPtr, srcPtr, curChar->Width);
|
||||
srcPtr += curChar->Width;
|
||||
dstPtr -= bmp->Stride;
|
||||
}
|
||||
|
||||
auto group = new GroupData(groupId);
|
||||
group->AddEntry(new EntryData(FieldTypes::Bitmap8bit, reinterpret_cast<char*>(bmp)));
|
||||
if (charInd == 32)
|
||||
{
|
||||
// First font group holds font name and gap width
|
||||
auto groupName = new char[fontName.length() + 1];
|
||||
strcpy(groupName, fontName.c_str());
|
||||
group->AddEntry(new EntryData(FieldTypes::GroupName, groupName));
|
||||
|
||||
auto gaps = new char[2];
|
||||
*reinterpret_cast<int16_t*>(gaps) = font->GapWidth;
|
||||
group->AddEntry(new EntryData(FieldTypes::ShortArray, gaps));
|
||||
}
|
||||
else
|
||||
{
|
||||
auto groupName = new char[30];
|
||||
sprintf(groupName, "char %d='%c'", charInd, charInd);
|
||||
group->AddEntry(new EntryData(FieldTypes::GroupName, groupName));
|
||||
}
|
||||
|
||||
Groups.push_back(group);
|
||||
}
|
||||
}
|
||||
128
SpaceCadetPinball/GroupData.h
Normal file
128
SpaceCadetPinball/GroupData.h
Normal file
@@ -0,0 +1,128 @@
|
||||
#pragma once
|
||||
|
||||
struct zmap_header_type;
|
||||
struct gdrv_bitmap8;
|
||||
|
||||
|
||||
enum class FieldTypes : int16_t
|
||||
{
|
||||
// One 16 bit signed integer
|
||||
ShortValue = 0,
|
||||
|
||||
// Sprite bitmap, 8bpp, indexed color
|
||||
Bitmap8bit = 1,
|
||||
|
||||
Unknown2 = 2,
|
||||
|
||||
// Group name, char[]. Not all groups have names.
|
||||
GroupName = 3,
|
||||
|
||||
Unknown4 = 4,
|
||||
|
||||
// Palette, contains 256 RBGA 4-byte colors.
|
||||
Palette = 5,
|
||||
|
||||
Unknown6 = 6,
|
||||
|
||||
Unknown7 = 7,
|
||||
|
||||
Unknown8 = 8,
|
||||
|
||||
// String, char[]
|
||||
String = 9,
|
||||
|
||||
// Array of 16 bit signed integers
|
||||
ShortArray = 10,
|
||||
|
||||
// Array of 32 bit floats
|
||||
FloatArray = 11,
|
||||
|
||||
// Sprite depth map, 16bpp, unsigned
|
||||
Bitmap16bit = 12,
|
||||
};
|
||||
|
||||
struct EntryData
|
||||
{
|
||||
EntryData() = default;
|
||||
|
||||
EntryData(FieldTypes entryType, char* buffer): EntryType(entryType), FieldSize(-1), Buffer(buffer)
|
||||
{
|
||||
}
|
||||
|
||||
~EntryData();
|
||||
FieldTypes EntryType{};
|
||||
int FieldSize{};
|
||||
char* Buffer{};
|
||||
};
|
||||
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct MsgFontChar
|
||||
{
|
||||
uint8_t Width;
|
||||
char Data[1];
|
||||
};
|
||||
|
||||
struct MsgFont
|
||||
{
|
||||
int16_t GapWidth;
|
||||
int16_t Unknown1;
|
||||
int16_t Height;
|
||||
uint8_t CharWidths[128];
|
||||
MsgFontChar Data[1];
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
static_assert(sizeof(MsgFont) == 136, "Wrong size of MsgFont");
|
||||
|
||||
|
||||
class GroupData
|
||||
{
|
||||
public:
|
||||
int GroupId;
|
||||
std::string GroupName;
|
||||
|
||||
GroupData(int groupId);
|
||||
void AddEntry(EntryData* entry);
|
||||
void FinalizeGroup();
|
||||
const std::vector<EntryData*>& GetEntries() const { return Entries; }
|
||||
const EntryData* GetEntry(size_t index) const { return Entries[index]; }
|
||||
size_t EntryCount() const { return Entries.size(); }
|
||||
void ReserveEntries(size_t count) { Entries.reserve(count); }
|
||||
gdrv_bitmap8* GetBitmap(int resolution) const;
|
||||
zmap_header_type* GetZMap(int resolution) const;
|
||||
|
||||
private:
|
||||
std::vector<EntryData*> Entries;
|
||||
gdrv_bitmap8* Bitmaps[3]{};
|
||||
zmap_header_type* ZMaps[3]{};
|
||||
bool NeedsSort = false;
|
||||
|
||||
static void SplitSplicedBitmap(const gdrv_bitmap8& srcBmp, gdrv_bitmap8& bmp, zmap_header_type& zMap);
|
||||
|
||||
void SetBitmap(gdrv_bitmap8* bmp);
|
||||
void SetZMap(zmap_header_type* zMap);
|
||||
};
|
||||
|
||||
|
||||
class DatFile
|
||||
{
|
||||
public:
|
||||
std::string AppName;
|
||||
std::string Description;
|
||||
std::vector<GroupData*> Groups;
|
||||
|
||||
~DatFile();
|
||||
char* field_nth(int groupIndex, FieldTypes targetEntryType, int skipFirstN);
|
||||
char* field(int groupIndex, FieldTypes entryType);
|
||||
int field_size_nth(int groupIndex, FieldTypes targetEntryType, int skipFirstN);
|
||||
int field_size(int groupIndex, FieldTypes targetEntryType);
|
||||
int record_labeled(LPCSTR targetGroupName);
|
||||
char* field_labeled(LPCSTR lpString, FieldTypes fieldType);
|
||||
gdrv_bitmap8* GetBitmap(int groupIndex);
|
||||
zmap_header_type* GetZMap(int groupIndex);
|
||||
void Finalize();
|
||||
|
||||
private:
|
||||
void AddMsgFont(MsgFont* font, const std::string& fontName);
|
||||
};
|
||||
@@ -1,266 +1,83 @@
|
||||
#include "pch.h"
|
||||
#include "Sound.h"
|
||||
|
||||
#include "pinball.h"
|
||||
#include "WaveMix.h"
|
||||
#include "winmain.h"
|
||||
|
||||
int Sound::num_channels;
|
||||
HWND Sound::wavemix_window;
|
||||
HANDLE Sound::pMem;
|
||||
unsigned int Sound::enabled_flag;
|
||||
int Sound::channel_time[8];
|
||||
MIXWAVE* Sound::channel_wavePtr[8];
|
||||
void (*Sound::callback_ptr)(int, MIXWAVE*, int);
|
||||
HMODULE Sound::HInstance;
|
||||
bool Sound::enabled_flag = false;
|
||||
int* Sound::TimeStamps = nullptr;
|
||||
|
||||
|
||||
int Sound::Init(HINSTANCE hInstance, int voices, void (* someFuncPtr)(int, MIXWAVE*, int))
|
||||
bool Sound::Init(int channels, bool enableFlag)
|
||||
{
|
||||
WNDCLASSA WndClass;
|
||||
char FileName[300];
|
||||
|
||||
int channelCount = voices;
|
||||
if (voices > 8)
|
||||
channelCount = 8;
|
||||
num_channels = channelCount;
|
||||
if (wavemix_window || pMem)
|
||||
return 0;
|
||||
enabled_flag = -1;
|
||||
for (int i = 0; i < channelCount; ++i)
|
||||
{
|
||||
channel_time[i] = 0;
|
||||
channel_wavePtr[i] = nullptr;
|
||||
}
|
||||
callback_ptr = someFuncPtr;
|
||||
if (!someFuncPtr)
|
||||
callback_ptr = NullCallback;
|
||||
|
||||
pinball::make_path_name(FileName, "wavemix.inf", 300);
|
||||
FILE* wavemixIniFile = nullptr;
|
||||
fopen_s(&wavemixIniFile, FileName, "r");
|
||||
if (wavemixIniFile)
|
||||
{
|
||||
fclose(wavemixIniFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBoxA(winmain::hwnd_frame, pinball::get_rc_string(42, 0), pinball::WindowName, 0x2000u);
|
||||
}
|
||||
|
||||
WndClass.style = 0;
|
||||
WndClass.lpfnWndProc = SoundCallBackWndProc;
|
||||
WndClass.cbClsExtra = 0;
|
||||
WndClass.cbWndExtra = 0;
|
||||
WndClass.hInstance = hInstance;
|
||||
WndClass.hIcon = nullptr;
|
||||
WndClass.hCursor = nullptr;
|
||||
WndClass.hbrBackground = nullptr;
|
||||
WndClass.lpszMenuName = nullptr;
|
||||
WndClass.lpszClassName = "WaveMixSoundGuy";
|
||||
RegisterClassA(&WndClass);
|
||||
wavemix_window = CreateWindowExA(
|
||||
0,
|
||||
"WaveMixSoundGuy",
|
||||
nullptr,
|
||||
0x80000000,
|
||||
0x80000000,
|
||||
0,
|
||||
0x80000000,
|
||||
0,
|
||||
nullptr,
|
||||
nullptr,
|
||||
hInstance,
|
||||
nullptr);
|
||||
if (!wavemix_window)
|
||||
return 0;
|
||||
|
||||
HInstance = hInstance;
|
||||
HANDLE hMixSession = WaveMix::Init();
|
||||
pMem = hMixSession;
|
||||
if (!hMixSession)
|
||||
return 0;
|
||||
WaveMix::OpenChannel(hMixSession, num_channels, 2u);
|
||||
return 1;
|
||||
Mix_Init(MIX_INIT_MID_Proxy);
|
||||
auto result = Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, 2, 1024);
|
||||
SetChannels(channels);
|
||||
Enable(enableFlag);
|
||||
return !result;
|
||||
}
|
||||
|
||||
void Sound::Enable(int channelFrom, int channelTo, int enableFlag)
|
||||
void Sound::Enable(bool enableFlag)
|
||||
{
|
||||
if (pMem)
|
||||
{
|
||||
if (channelTo >= num_channels)
|
||||
channelTo = num_channels - 1;
|
||||
|
||||
if (channelFrom >= 0 && channelTo < num_channels)
|
||||
{
|
||||
for (int index = channelFrom; index <= channelTo; ++index)
|
||||
{
|
||||
int channelFlag = 1 << index;
|
||||
if (enableFlag)
|
||||
{
|
||||
enabled_flag |= channelFlag;
|
||||
}
|
||||
else
|
||||
{
|
||||
enabled_flag &= ~channelFlag;
|
||||
Flush(index, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Sound::Idle()
|
||||
{
|
||||
if (pMem)
|
||||
WaveMix::Pump();
|
||||
enabled_flag = enableFlag;
|
||||
if (!enableFlag)
|
||||
Mix_HaltChannel(-1);
|
||||
}
|
||||
|
||||
void Sound::Activate()
|
||||
{
|
||||
if (pMem)
|
||||
WaveMix::Activate(pMem, true);
|
||||
Mix_Resume(-1);
|
||||
}
|
||||
|
||||
void Sound::Deactivate()
|
||||
{
|
||||
if (pMem)
|
||||
WaveMix::Activate(pMem, false);
|
||||
Mix_Pause(-1);
|
||||
}
|
||||
|
||||
void Sound::Close()
|
||||
{
|
||||
if (wavemix_window)
|
||||
{
|
||||
DestroyWindow(wavemix_window);
|
||||
wavemix_window = nullptr;
|
||||
}
|
||||
if (pMem)
|
||||
{
|
||||
WaveMix::CloseChannel(pMem, 0, 1);
|
||||
WaveMix::CloseSession(pMem);
|
||||
pMem = nullptr;
|
||||
}
|
||||
delete[] TimeStamps;
|
||||
TimeStamps = nullptr;
|
||||
Mix_CloseAudio();
|
||||
Mix_Quit();
|
||||
}
|
||||
|
||||
void Sound::PlaySound(MIXWAVE* wavePtr, int minChannel, int maxChannel, unsigned int dwFlags, __int16 loops)
|
||||
void Sound::PlaySound(Mix_Chunk* wavePtr, int time)
|
||||
{
|
||||
MIXPLAYPARAMS mixParams{};
|
||||
|
||||
if (!pMem)
|
||||
return;
|
||||
|
||||
if (maxChannel >= num_channels)
|
||||
maxChannel = num_channels - 1;
|
||||
if (!wavePtr || minChannel < 0 || maxChannel >= num_channels)
|
||||
return;
|
||||
|
||||
if ((dwFlags & 0x8000) != 0 && num_channels > 0)
|
||||
if (wavePtr && enabled_flag)
|
||||
{
|
||||
int index2 = 0;
|
||||
bool ok = false;
|
||||
while (channel_wavePtr[index2] != wavePtr)
|
||||
if (Mix_Playing(-1) == num_channels)
|
||||
{
|
||||
if (++index2 >= num_channels)
|
||||
{
|
||||
ok = true;
|
||||
break;
|
||||
}
|
||||
auto oldestChannel = std::min_element(TimeStamps, TimeStamps + num_channels) - TimeStamps;
|
||||
Mix_HaltChannel(oldestChannel);
|
||||
}
|
||||
if (!ok)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int playChannel = minChannel;
|
||||
if (minChannel < maxChannel)
|
||||
{
|
||||
int curChannel = minChannel;
|
||||
do
|
||||
{
|
||||
++curChannel;
|
||||
if ((1 << curChannel) & enabled_flag &&
|
||||
channel_time[curChannel] < channel_time[playChannel])
|
||||
{
|
||||
playChannel = curChannel;
|
||||
}
|
||||
}
|
||||
while (curChannel < maxChannel);
|
||||
}
|
||||
|
||||
if ((1 << playChannel) & enabled_flag)
|
||||
{
|
||||
mixParams.hMixSession = pMem;
|
||||
mixParams.hWndNotify = wavemix_window;
|
||||
mixParams.dwFlags = dwFlags;
|
||||
mixParams.wSize = 28;
|
||||
mixParams.wLoops = loops;
|
||||
mixParams.iChannel = playChannel;
|
||||
mixParams.lpMixWave = wavePtr;
|
||||
|
||||
callback_ptr(1, wavePtr, playChannel);
|
||||
channel_time[playChannel] = timeGetTime();
|
||||
channel_wavePtr[playChannel] = wavePtr;
|
||||
WaveMix::Play(&mixParams);
|
||||
auto channel = Mix_PlayChannel(-1, wavePtr, 0);
|
||||
if (channel != -1)
|
||||
TimeStamps[channel] = time;
|
||||
}
|
||||
}
|
||||
|
||||
MIXWAVE* Sound::LoadWaveFile(LPCSTR lpName)
|
||||
Mix_Chunk* Sound::LoadWaveFile(const std::string& lpName)
|
||||
{
|
||||
return pMem ? WaveMix::OpenWave(pMem, lpName, HInstance, 1u) : nullptr;
|
||||
auto wavFile = fopen(lpName.c_str(), "r");
|
||||
if (!wavFile)
|
||||
return nullptr;
|
||||
fclose(wavFile);
|
||||
|
||||
return Mix_LoadWAV(lpName.c_str());
|
||||
}
|
||||
|
||||
void Sound::FreeSound(MIXWAVE* wave)
|
||||
void Sound::FreeSound(Mix_Chunk* wave)
|
||||
{
|
||||
if (wave && pMem)
|
||||
WaveMix::FreeWave(pMem, wave);
|
||||
if (wave)
|
||||
Mix_FreeChunk(wave);
|
||||
}
|
||||
|
||||
void Sound::Flush(int channelFrom, int channelTo)
|
||||
void Sound::SetChannels(int channels)
|
||||
{
|
||||
if (pMem)
|
||||
{
|
||||
if (channelTo >= num_channels)
|
||||
channelTo = num_channels - 1;
|
||||
if (channels <= 0)
|
||||
channels = 8;
|
||||
|
||||
if (channelFrom >= 0 && channelTo < num_channels)
|
||||
{
|
||||
for (auto index = channelFrom; index <= channelTo; index++)
|
||||
{
|
||||
WaveMix::FlushChannel(pMem, index, 0);
|
||||
channel_time[index] = 0;
|
||||
channel_wavePtr[index] = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Sound::NullCallback(int a1, MIXWAVE* a2, int a3)
|
||||
{
|
||||
}
|
||||
|
||||
LRESULT Sound::SoundCallBackWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (Msg != MM_WOM_DONE)
|
||||
return DefWindowProcA(hWnd, Msg, wParam, lParam);
|
||||
|
||||
auto wavePtr = reinterpret_cast<MIXWAVE*>(lParam);
|
||||
int channel = -1;
|
||||
for (auto index = 0; index < num_channels; ++index)
|
||||
{
|
||||
if (channel_wavePtr[index] == wavePtr &&
|
||||
(channel < 0 || channel_time[index] < channel_time[channel]))
|
||||
{
|
||||
channel = index;
|
||||
}
|
||||
}
|
||||
|
||||
if (channel >= 0)
|
||||
{
|
||||
channel_time[channel] = 0;
|
||||
channel_wavePtr[channel] = nullptr;
|
||||
}
|
||||
|
||||
callback_ptr(2, wavePtr, channel);
|
||||
return 0;
|
||||
num_channels = channels;
|
||||
delete[] TimeStamps;
|
||||
TimeStamps = new int[num_channels]();
|
||||
Mix_AllocateChannels(num_channels);
|
||||
}
|
||||
|
||||
@@ -1,28 +1,20 @@
|
||||
#pragma once
|
||||
#include "WaveMix.h"
|
||||
|
||||
|
||||
class Sound
|
||||
{
|
||||
public:
|
||||
static int Init(HINSTANCE hInstance, int voices, void (* someFuncPtr)(int, MIXWAVE*, int));
|
||||
static void Enable(int channelFrom, int channelTo, int enableFlag);
|
||||
static void Idle();
|
||||
static bool Init(int channels, bool enableFlag);
|
||||
static void Enable(bool enableFlag);
|
||||
static void Activate();
|
||||
static void Deactivate();
|
||||
static void Close();
|
||||
static void PlaySound(MIXWAVE* wavePtr, int minChannel, int maxChannel, unsigned int dwFlags, __int16 loops);
|
||||
static MIXWAVE* LoadWaveFile(LPCSTR lpName);
|
||||
static void FreeSound(MIXWAVE* wave);
|
||||
static void Flush(int channelFrom, int channelTo);
|
||||
static void NullCallback(int a1, MIXWAVE* a2, int a3);
|
||||
static LRESULT __stdcall SoundCallBackWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
|
||||
static void PlaySound(Mix_Chunk* wavePtr, int time);
|
||||
static Mix_Chunk* LoadWaveFile(const std::string& lpName);
|
||||
static void FreeSound(Mix_Chunk* wave);
|
||||
static void SetChannels(int channels);
|
||||
private:
|
||||
static int num_channels;
|
||||
static HWND wavemix_window;
|
||||
static HANDLE pMem;
|
||||
static unsigned int enabled_flag;
|
||||
static int channel_time[8];
|
||||
static MIXWAVE* channel_wavePtr[8];
|
||||
static void (* callback_ptr)(int, MIXWAVE*, int);
|
||||
static HMODULE HInstance;
|
||||
static bool enabled_flag;
|
||||
static int* TimeStamps;
|
||||
};
|
||||
|
||||
@@ -3,81 +3,39 @@
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#include <iostream>
|
||||
#include "objlist_class.h"
|
||||
#include "partman.h"
|
||||
#include "gdrv.h"
|
||||
#include "loader.h"
|
||||
#include "pb.h"
|
||||
#include "pinball.h"
|
||||
#include "score.h"
|
||||
#include "TPinballTable.h"
|
||||
#include "TTextBox.h"
|
||||
#include "winmain.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
int MainActual(LPCSTR lpCmdLine)
|
||||
{
|
||||
// Todo: get rid of restart to change resolution.
|
||||
int returnCode;
|
||||
do
|
||||
{
|
||||
// Testing with UI
|
||||
char cmdLine[1]{};
|
||||
WinMain(GetModuleHandleA(nullptr), 0, cmdLine, 10);
|
||||
return 0;
|
||||
returnCode = winmain::WinMain(lpCmdLine);
|
||||
}
|
||||
|
||||
std::cout << "Hello World!\n";
|
||||
gdrv::init(0, 0);
|
||||
auto dib = gdrv::DibCreate(8, 1, 1);
|
||||
gdrv::DibSetUsage(dib, 0, 1);
|
||||
|
||||
objlist_class d = objlist_class(2, 4);
|
||||
for (int i = 0; i < 100; i++)
|
||||
{
|
||||
d.Add((void*)i);
|
||||
}
|
||||
d.Delete((void*)3);
|
||||
|
||||
auto xx = sizeof(datFileHeader);
|
||||
|
||||
lstrcpyA(winmain::DatFileName, "PINBALL.DAT");
|
||||
pb::init();
|
||||
auto datFile = pb::record_table;
|
||||
|
||||
assert(partman::field_size_nth(datFile, 0, datFieldTypes::String, 0) == 43);
|
||||
assert(partman::field_size_nth(datFile, 2, datFieldTypes::Palette, 0) == 1024);
|
||||
assert(partman::field_size_nth(datFile, 101, datFieldTypes::FloatArray, 4) == 32);
|
||||
|
||||
assert(strcmp(partman::field(datFile, 0, datFieldTypes::String), "3D-Pinball: Copyright 1994, Cinematronics") == 0);
|
||||
assert(strcmp(partman::field(datFile, 540, datFieldTypes::GroupName), "table_objects") == 0);
|
||||
|
||||
assert(partman::record_labeled(datFile, "background") == 2);
|
||||
assert(partman::record_labeled(datFile, "a_bump1") == 372);
|
||||
|
||||
assert(memcmp(partman::field_labeled(datFile, "table_size", datFieldTypes::ShortArray), new short[2]{ 600, 416 }, 2 * 2) == 0);
|
||||
|
||||
//loader::error(25, 26);
|
||||
loader::get_sound_id(18);
|
||||
visualStruct visual1{};
|
||||
loader::material(96, &visual1);
|
||||
loader::query_visual(283, 0, &visual1);
|
||||
visualKickerStruct kicker1{};
|
||||
loader::kicker(509, &kicker1);
|
||||
|
||||
auto score1 = score::create("score1", nullptr);
|
||||
|
||||
auto pinballTable = pb::MainTable;
|
||||
//pinballTable->find_component(1);
|
||||
|
||||
for (int i = 0; i < 190; i++)
|
||||
{
|
||||
auto rsc = pinball::get_rc_string(i, 0);
|
||||
if (rsc)
|
||||
printf_s("%d:\t%s\n", i, rsc);
|
||||
}
|
||||
|
||||
//DatParser::Parse(dataFileName);
|
||||
std::cout << "Goodby World!\n";
|
||||
while (winmain::RestartRequested());
|
||||
return returnCode;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
std::string cmdLine;
|
||||
for (int i = 1; i < argc; i++)
|
||||
cmdLine += argv[i];
|
||||
|
||||
return MainActual(cmdLine.c_str());
|
||||
}
|
||||
|
||||
#if _WIN32
|
||||
#include <windows.h>
|
||||
|
||||
// Windows subsystem main
|
||||
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
|
||||
{
|
||||
return MainActual(lpCmdLine);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Run program: Ctrl + F5 or Debug > Start Without Debugging menu
|
||||
// Debug program: F5 or Debug > Start Debugging menu
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,314 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>15.0</VCProjectVersion>
|
||||
<ProjectGuid>{F7B78CC7-6984-4F79-9486-ABCF87DF9F06}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>SpaceCadetPinball</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
<PreprocessToFile>false</PreprocessToFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>Comctl32.lib;Winmm.lib;Htmlhelp.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>Comctl32.lib;Winmm.lib;Htmlhelp.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>Comctl32.lib;Winmm.lib;Htmlhelp.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>Comctl32.lib;Winmm.lib;Htmlhelp.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="control.h" />
|
||||
<ClInclude Include="fullscrn.h" />
|
||||
<ClInclude Include="gdrv.h" />
|
||||
<ClInclude Include="high_score.h" />
|
||||
<ClInclude Include="loader.h" />
|
||||
<ClInclude Include="maths.h" />
|
||||
<ClInclude Include="memory.h" />
|
||||
<ClInclude Include="midi.h" />
|
||||
<ClInclude Include="nudge.h" />
|
||||
<ClInclude Include="objlist_class.h" />
|
||||
<ClInclude Include="options.h" />
|
||||
<ClInclude Include="partman.h" />
|
||||
<ClInclude Include="pb.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="pinball.h" />
|
||||
<ClInclude Include="proj.h" />
|
||||
<ClInclude Include="render.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
<ClInclude Include="score.h" />
|
||||
<ClInclude Include="Sound.h" />
|
||||
<ClInclude Include="splash.h" />
|
||||
<ClInclude Include="TBall.h" />
|
||||
<ClInclude Include="TBlocker.h" />
|
||||
<ClInclude Include="TBumper.h" />
|
||||
<ClInclude Include="TCircle.h" />
|
||||
<ClInclude Include="TCollisionComponent.h" />
|
||||
<ClInclude Include="TComponentGroup.h" />
|
||||
<ClInclude Include="TDemo.h" />
|
||||
<ClInclude Include="TDrain.h" />
|
||||
<ClInclude Include="TEdgeBox.h" />
|
||||
<ClInclude Include="TEdgeManager.h" />
|
||||
<ClInclude Include="TEdgeSegment.h" />
|
||||
<ClInclude Include="TFlagSpinner.h" />
|
||||
<ClInclude Include="TFlipper.h" />
|
||||
<ClInclude Include="TFlipperEdge.h" />
|
||||
<ClInclude Include="TGate.h" />
|
||||
<ClInclude Include="THole.h" />
|
||||
<ClInclude Include="timer.h" />
|
||||
<ClInclude Include="TKickback.h" />
|
||||
<ClInclude Include="TKickout.h" />
|
||||
<ClInclude Include="TLight.h" />
|
||||
<ClInclude Include="TLightBargraph.h" />
|
||||
<ClInclude Include="TLightGroup.h" />
|
||||
<ClInclude Include="TLightRollover.h" />
|
||||
<ClInclude Include="TLine.h" />
|
||||
<ClInclude Include="TOneway.h" />
|
||||
<ClInclude Include="TPinballComponent.h" />
|
||||
<ClInclude Include="TPinballTable.h" />
|
||||
<ClInclude Include="TPlunger.h" />
|
||||
<ClInclude Include="TPopupTarget.h" />
|
||||
<ClInclude Include="TRamp.h" />
|
||||
<ClInclude Include="TRollover.h" />
|
||||
<ClInclude Include="TSink.h" />
|
||||
<ClInclude Include="TSoloTarget.h" />
|
||||
<ClInclude Include="TSound.h" />
|
||||
<ClInclude Include="TTableLayer.h" />
|
||||
<ClInclude Include="TTextBox.h" />
|
||||
<ClInclude Include="TTextBoxMessage.h" />
|
||||
<ClInclude Include="TTimer.h" />
|
||||
<ClInclude Include="TTripwire.h" />
|
||||
<ClInclude Include="TWall.h" />
|
||||
<ClInclude Include="TZmapList.h" />
|
||||
<ClInclude Include="WaveMix.h" />
|
||||
<ClInclude Include="winmain.h" />
|
||||
<ClInclude Include="zdrv.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="control.cpp" />
|
||||
<ClCompile Include="fullscrn.cpp" />
|
||||
<ClCompile Include="gdrv.cpp" />
|
||||
<ClCompile Include="high_score.cpp" />
|
||||
<ClCompile Include="loader.cpp" />
|
||||
<ClCompile Include="maths.cpp" />
|
||||
<ClCompile Include="memory.cpp" />
|
||||
<ClCompile Include="midi.cpp" />
|
||||
<ClCompile Include="nudge.cpp" />
|
||||
<ClCompile Include="objlist_class.cpp" />
|
||||
<ClCompile Include="options.cpp" />
|
||||
<ClCompile Include="partman.cpp" />
|
||||
<ClCompile Include="pb.cpp" />
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="pinball.cpp" />
|
||||
<ClCompile Include="proj.cpp" />
|
||||
<ClCompile Include="render.cpp" />
|
||||
<ClCompile Include="score.cpp" />
|
||||
<ClCompile Include="Sound.cpp" />
|
||||
<ClCompile Include="SpaceCadetPinball.cpp" />
|
||||
<ClCompile Include="splash.cpp" />
|
||||
<ClCompile Include="TBall.cpp" />
|
||||
<ClCompile Include="TBlocker.cpp" />
|
||||
<ClCompile Include="TBumper.cpp" />
|
||||
<ClCompile Include="TCircle.cpp" />
|
||||
<ClCompile Include="TCollisionComponent.cpp" />
|
||||
<ClCompile Include="TComponentGroup.cpp" />
|
||||
<ClCompile Include="TDemo.cpp" />
|
||||
<ClCompile Include="TDrain.cpp" />
|
||||
<ClCompile Include="TEdgeBox.cpp" />
|
||||
<ClCompile Include="TEdgeManager.cpp" />
|
||||
<ClCompile Include="TEdgeSegment.cpp" />
|
||||
<ClCompile Include="TFlagSpinner.cpp" />
|
||||
<ClCompile Include="TFlipper.cpp" />
|
||||
<ClCompile Include="TFlipperEdge.cpp" />
|
||||
<ClCompile Include="TGate.cpp" />
|
||||
<ClCompile Include="THole.cpp" />
|
||||
<ClCompile Include="timer.cpp" />
|
||||
<ClCompile Include="TKickback.cpp" />
|
||||
<ClCompile Include="TKickout.cpp" />
|
||||
<ClCompile Include="TLight.cpp" />
|
||||
<ClCompile Include="TLightBargraph.cpp" />
|
||||
<ClCompile Include="TLightGroup.cpp" />
|
||||
<ClCompile Include="TLightRollover.cpp" />
|
||||
<ClCompile Include="TLine.cpp" />
|
||||
<ClCompile Include="TOneway.cpp" />
|
||||
<ClCompile Include="TPinballComponent.cpp" />
|
||||
<ClCompile Include="TPinballTable.cpp" />
|
||||
<ClCompile Include="TPlunger.cpp" />
|
||||
<ClCompile Include="TPopupTarget.cpp" />
|
||||
<ClCompile Include="TRamp.cpp" />
|
||||
<ClCompile Include="TRollover.cpp" />
|
||||
<ClCompile Include="TSink.cpp" />
|
||||
<ClCompile Include="TSoloTarget.cpp" />
|
||||
<ClCompile Include="TSound.cpp" />
|
||||
<ClCompile Include="TTableLayer.cpp" />
|
||||
<ClCompile Include="TTextBox.cpp" />
|
||||
<ClCompile Include="TTextBoxMessage.cpp" />
|
||||
<ClCompile Include="TTimer.cpp" />
|
||||
<ClCompile Include="TTripwire.cpp" />
|
||||
<ClCompile Include="TWall.cpp" />
|
||||
<ClCompile Include="WaveMix.cpp" />
|
||||
<ClCompile Include="winmain.cpp" />
|
||||
<ClCompile Include="zdrv.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="NatvisFile.natvis" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="SpaceCadetPinball.rc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="PB_MSGFT.bin" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="Icon_1.ico" />
|
||||
<Image Include="splash_bitmap.bmp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -1,447 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files\TEdgeSegment">
|
||||
<UniqueIdentifier>{0aa40751-a44a-400e-8809-ee817161e8e0}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\TEdgeSegment">
|
||||
<UniqueIdentifier>{d70e7fca-2294-41a4-9cf8-78052bdb9aa4}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\TCollisionComponent">
|
||||
<UniqueIdentifier>{01aed326-d2ec-457a-b99f-08ef32ed97fa}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Header Files\TCollisionComponent">
|
||||
<UniqueIdentifier>{7ed2796a-da4b-4edd-8783-53e45d8d1c88}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Header Files\TPinballComponent">
|
||||
<UniqueIdentifier>{9ee086c2-1a95-48fb-92d8-4b7e7f6682ff}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\TPinballComponent">
|
||||
<UniqueIdentifier>{33813da8-81ac-449c-b19a-9756272519b9}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="pch.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="objlist_class.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="partman.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="loader.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="pinball.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="score.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TPinballComponent.h">
|
||||
<Filter>Header Files\TPinballComponent</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TBall.h">
|
||||
<Filter>Header Files\TPinballComponent</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="resource.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TComponentGroup.h">
|
||||
<Filter>Header Files\TPinballComponent</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TLight.h">
|
||||
<Filter>Header Files\TPinballComponent</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TLightBargraph.h">
|
||||
<Filter>Header Files\TPinballComponent</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TLightGroup.h">
|
||||
<Filter>Header Files\TPinballComponent</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TSound.h">
|
||||
<Filter>Header Files\TPinballComponent</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TTextBox.h">
|
||||
<Filter>Header Files\TPinballComponent</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TTimer.h">
|
||||
<Filter>Header Files\TPinballComponent</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TZmapList.h">
|
||||
<Filter>Header Files\TPinballComponent</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="memory.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="winmain.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="options.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Sound.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="pb.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="render.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="fullscrn.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="gdrv.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="maths.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="zdrv.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TEdgeSegment.h">
|
||||
<Filter>Header Files\TEdgeSegment</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TCollisionComponent.h">
|
||||
<Filter>Header Files\TCollisionComponent</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TCircle.h">
|
||||
<Filter>Header Files\TEdgeSegment</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TLine.h">
|
||||
<Filter>Header Files\TEdgeSegment</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TWall.h">
|
||||
<Filter>Header Files\TCollisionComponent</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TBumper.h">
|
||||
<Filter>Header Files\TCollisionComponent</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TBlocker.h">
|
||||
<Filter>Header Files\TCollisionComponent</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TDemo.h">
|
||||
<Filter>Header Files\TCollisionComponent</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TDrain.h">
|
||||
<Filter>Header Files\TCollisionComponent</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TFlagSpinner.h">
|
||||
<Filter>Header Files\TCollisionComponent</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TFlipper.h">
|
||||
<Filter>Header Files\TCollisionComponent</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TGate.h">
|
||||
<Filter>Header Files\TCollisionComponent</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="THole.h">
|
||||
<Filter>Header Files\TCollisionComponent</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TKickback.h">
|
||||
<Filter>Header Files\TCollisionComponent</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TKickout.h">
|
||||
<Filter>Header Files\TCollisionComponent</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TOneway.h">
|
||||
<Filter>Header Files\TCollisionComponent</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TPlunger.h">
|
||||
<Filter>Header Files\TCollisionComponent</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TPopupTarget.h">
|
||||
<Filter>Header Files\TCollisionComponent</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TRamp.h">
|
||||
<Filter>Header Files\TCollisionComponent</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TRollover.h">
|
||||
<Filter>Header Files\TCollisionComponent</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TSink.h">
|
||||
<Filter>Header Files\TCollisionComponent</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TSoloTarget.h">
|
||||
<Filter>Header Files\TCollisionComponent</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TTableLayer.h">
|
||||
<Filter>Header Files\TCollisionComponent</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TPinballTable.h">
|
||||
<Filter>Header Files\TPinballComponent</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TTripwire.h">
|
||||
<Filter>Header Files\TCollisionComponent</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TLightRollover.h">
|
||||
<Filter>Header Files\TCollisionComponent</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="proj.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="timer.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="midi.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="nudge.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TTextBoxMessage.h">
|
||||
<Filter>Header Files\TPinballComponent</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="high_score.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="control.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TEdgeManager.h">
|
||||
<Filter>Header Files\TPinballComponent</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TEdgeBox.h">
|
||||
<Filter>Header Files\TPinballComponent</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TFlipperEdge.h">
|
||||
<Filter>Header Files\TEdgeSegment</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="WaveMix.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="splash.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="pch.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SpaceCadetPinball.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="objlist_class.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="partman.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="loader.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="pinball.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="score.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TPinballComponent.cpp">
|
||||
<Filter>Source Files\TPinballComponent</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TPinballTable.cpp">
|
||||
<Filter>Source Files\TPinballComponent</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TBall.cpp">
|
||||
<Filter>Source Files\TPinballComponent</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TComponentGroup.cpp">
|
||||
<Filter>Source Files\TPinballComponent</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TLight.cpp">
|
||||
<Filter>Source Files\TPinballComponent</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TLightBargraph.cpp">
|
||||
<Filter>Source Files\TPinballComponent</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TLightGroup.cpp">
|
||||
<Filter>Source Files\TPinballComponent</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TSound.cpp">
|
||||
<Filter>Source Files\TPinballComponent</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TTextBox.cpp">
|
||||
<Filter>Source Files\TPinballComponent</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TTimer.cpp">
|
||||
<Filter>Source Files\TPinballComponent</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="memory.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="winmain.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="options.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Sound.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="pb.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="render.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="fullscrn.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="gdrv.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="maths.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="zdrv.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TEdgeSegment.cpp">
|
||||
<Filter>Source Files\TEdgeSegment</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TCollisionComponent.cpp">
|
||||
<Filter>Source Files\TCollisionComponent</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TCircle.cpp">
|
||||
<Filter>Source Files\TEdgeSegment</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TLine.cpp">
|
||||
<Filter>Source Files\TEdgeSegment</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TWall.cpp">
|
||||
<Filter>Source Files\TCollisionComponent</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TBlocker.cpp">
|
||||
<Filter>Source Files\TCollisionComponent</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TBumper.cpp">
|
||||
<Filter>Source Files\TCollisionComponent</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TDemo.cpp">
|
||||
<Filter>Source Files\TCollisionComponent</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TDrain.cpp">
|
||||
<Filter>Source Files\TCollisionComponent</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TFlagSpinner.cpp">
|
||||
<Filter>Source Files\TCollisionComponent</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TFlipper.cpp">
|
||||
<Filter>Source Files\TCollisionComponent</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TGate.cpp">
|
||||
<Filter>Source Files\TCollisionComponent</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="THole.cpp">
|
||||
<Filter>Source Files\TCollisionComponent</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TKickback.cpp">
|
||||
<Filter>Source Files\TCollisionComponent</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TKickout.cpp">
|
||||
<Filter>Source Files\TCollisionComponent</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TOneway.cpp">
|
||||
<Filter>Source Files\TCollisionComponent</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TPlunger.cpp">
|
||||
<Filter>Source Files\TCollisionComponent</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TPopupTarget.cpp">
|
||||
<Filter>Source Files\TCollisionComponent</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TRamp.cpp">
|
||||
<Filter>Source Files\TCollisionComponent</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TRollover.cpp">
|
||||
<Filter>Source Files\TCollisionComponent</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TSink.cpp">
|
||||
<Filter>Source Files\TCollisionComponent</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TSoloTarget.cpp">
|
||||
<Filter>Source Files\TCollisionComponent</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TTableLayer.cpp">
|
||||
<Filter>Source Files\TCollisionComponent</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TTripwire.cpp">
|
||||
<Filter>Source Files\TCollisionComponent</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TLightRollover.cpp">
|
||||
<Filter>Source Files\TCollisionComponent</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="proj.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="timer.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="midi.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="nudge.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TTextBoxMessage.cpp">
|
||||
<Filter>Source Files\TPinballComponent</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="high_score.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="control.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TEdgeManager.cpp">
|
||||
<Filter>Source Files\TPinballComponent</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TEdgeBox.cpp">
|
||||
<Filter>Source Files\TPinballComponent</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TFlipperEdge.cpp">
|
||||
<Filter>Source Files\TEdgeSegment</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="WaveMix.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="splash.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="NatvisFile.natvis" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="SpaceCadetPinball.rc">
|
||||
<Filter>Resource Files</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="PB_MSGFT.bin">
|
||||
<Filter>Resource Files</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="Icon_1.ico">
|
||||
<Filter>Resource Files</Filter>
|
||||
</Image>
|
||||
<Image Include="splash_bitmap.bmp">
|
||||
<Filter>Resource Files</Filter>
|
||||
</Image>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -2,17 +2,18 @@
|
||||
#include "TBall.h"
|
||||
|
||||
|
||||
#include "fullscrn.h"
|
||||
#include "loader.h"
|
||||
#include "maths.h"
|
||||
#include "objlist_class.h"
|
||||
#include "pb.h"
|
||||
#include "proj.h"
|
||||
#include "render.h"
|
||||
#include "TPinballTable.h"
|
||||
#include "TZmapList.h"
|
||||
|
||||
TBall::TBall(TPinballTable* table) : TPinballComponent(table, -1, false)
|
||||
{
|
||||
visualStruct visual{};
|
||||
char ballGroupName[10]{"ball"};
|
||||
|
||||
TimeNow = 0.0;
|
||||
RayMaxDistance = 0.0;
|
||||
@@ -30,28 +31,26 @@ TBall::TBall(TPinballTable* table) : TPinballComponent(table, -1, false)
|
||||
Position.X = 0.0;
|
||||
Position.Y = 0.0;
|
||||
|
||||
ListBitmap = new TZmapList(0, 4);
|
||||
auto groupIndex = loader::query_handle("ball");
|
||||
ListBitmap = new std::vector<gdrv_bitmap8*>();
|
||||
|
||||
/*Full tilt: ball is ballN, where N[0,2] resolution*/
|
||||
if (pb::FullTiltMode)
|
||||
ballGroupName[4] = '0' + fullscrn::GetResolution();
|
||||
auto groupIndex = loader::query_handle(ballGroupName);
|
||||
|
||||
Offset = *loader::query_float_attribute(groupIndex, 0, 500);
|
||||
|
||||
auto visualCount = loader::query_visual_states(groupIndex);
|
||||
auto index = 0;
|
||||
if (visualCount > 0)
|
||||
for (auto index = 0; index < visualCount; ++index)
|
||||
{
|
||||
auto visualZPtr = VisualZArray;
|
||||
do
|
||||
{
|
||||
loader::query_visual(groupIndex, index, &visual);
|
||||
if (ListBitmap)
|
||||
ListBitmap->Add(visual.Bitmap);
|
||||
auto visVec = reinterpret_cast<vector_type*>(loader::query_float_attribute(groupIndex, index, 501));
|
||||
auto zDepth = proj::z_distance(visVec);
|
||||
++index;
|
||||
*visualZPtr = zDepth;
|
||||
++visualZPtr;
|
||||
}
|
||||
while (index < visualCount);
|
||||
loader::query_visual(groupIndex, index, &visual);
|
||||
if (ListBitmap)
|
||||
ListBitmap->push_back(visual.Bitmap);
|
||||
auto visVec = reinterpret_cast<vector_type*>(loader::query_float_attribute(groupIndex, index, 501));
|
||||
auto zDepth = proj::z_distance(visVec);
|
||||
VisualZArray[index] = zDepth;
|
||||
}
|
||||
RenderSprite = render::create_sprite(VisualType::Ball, nullptr, nullptr, 0, 0, nullptr);
|
||||
RenderSprite = render::create_sprite(VisualTypes::Ball, nullptr, nullptr, 0, 0, nullptr);
|
||||
PinballTable->CollisionCompOffset = Offset;
|
||||
Position.Z = Offset;
|
||||
}
|
||||
@@ -72,13 +71,13 @@ void TBall::Repaint()
|
||||
auto zDepth = proj::z_distance(&Position);
|
||||
|
||||
auto zArrPtr = VisualZArray;
|
||||
int index;
|
||||
for (index = 0; index < ListBitmap->Count() - 1; ++index, zArrPtr++)
|
||||
auto index = 0u;
|
||||
for (; index < ListBitmap->size() - 1; ++index, zArrPtr++)
|
||||
{
|
||||
if (*zArrPtr <= zDepth) break;
|
||||
}
|
||||
|
||||
auto bmp = static_cast<gdrv_bitmap8*>(ListBitmap->Get(index));
|
||||
auto bmp = ListBitmap->at(index);
|
||||
render::ball_set(
|
||||
RenderSprite,
|
||||
bmp,
|
||||
@@ -131,10 +130,9 @@ void TBall::throw_ball(TBall* ball, vector_type* acceleration, float angleMult,
|
||||
{
|
||||
ball->CollisionComp = nullptr;
|
||||
ball->Acceleration = *acceleration;
|
||||
float rnd = static_cast<float>(rand());
|
||||
float angle = (1.0f - (rnd * 0.00003051850947599719f + rnd * 0.00003051850947599719f)) * angleMult;
|
||||
float rnd = RandFloat();
|
||||
float angle = (1.0f - (rnd + rnd)) * angleMult;
|
||||
maths::RotateVector(&ball->Acceleration, angle);
|
||||
rnd = static_cast<float>(rand());
|
||||
ball->Speed = (1.0f - (rnd * 0.00003051850947599719f + rnd * 0.00003051850947599719f)) * (speedMult1 *
|
||||
speedMult2) + speedMult1;
|
||||
rnd = RandFloat();
|
||||
ball->Speed = (1.0f - (rnd + rnd)) * (speedMult1 * speedMult2) + speedMult1;
|
||||
}
|
||||
|
||||
@@ -17,21 +17,20 @@ public :
|
||||
static void throw_ball(TBall* ball, struct vector_type* acceleration, float angleMult, float speedMult1,
|
||||
float speedMult2);
|
||||
|
||||
vector_type Position;
|
||||
vector_type Acceleration;
|
||||
vector_type Position{};
|
||||
vector_type Acceleration{};
|
||||
float Speed;
|
||||
float RayMaxDistance;
|
||||
float TimeDelta;
|
||||
float TimeNow;
|
||||
vector_type InvAcceleration;
|
||||
vector_type RampFieldForce;
|
||||
vector_type InvAcceleration{};
|
||||
vector_type RampFieldForce{};
|
||||
TCollisionComponent* CollisionComp;
|
||||
int FieldFlag;
|
||||
TEdgeSegment* Collisions[5];
|
||||
TEdgeSegment* Collisions[5]{};
|
||||
int EdgeCollisionCount;
|
||||
vector_type CollisionOffset;
|
||||
vector_type CollisionOffset{};
|
||||
int CollisionFlag;
|
||||
float Offset;
|
||||
int Unknown29;
|
||||
float VisualZArray[50];
|
||||
float VisualZArray[50]{};
|
||||
};
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include "loader.h"
|
||||
#include "render.h"
|
||||
#include "timer.h"
|
||||
#include "TZmapList.h"
|
||||
|
||||
TBlocker::TBlocker(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true)
|
||||
{
|
||||
@@ -46,7 +45,7 @@ int TBlocker::Message(int code, float value)
|
||||
case 52:
|
||||
ActiveFlag = 1;
|
||||
loader::play_sound(SoundIndex4);
|
||||
render::sprite_set_bitmap(RenderSprite, static_cast<gdrv_bitmap8*>(ListBitmap->Get(0)));
|
||||
render::sprite_set_bitmap(RenderSprite, ListBitmap->at(0));
|
||||
break;
|
||||
case 59:
|
||||
break;
|
||||
@@ -57,7 +56,7 @@ int TBlocker::Message(int code, float value)
|
||||
timer::kill(Timer);
|
||||
|
||||
float timerTime;
|
||||
if (value <= 0.0)
|
||||
if (value <= 0.0f)
|
||||
timerTime = 0.0;
|
||||
else
|
||||
timerTime = value;
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#include "render.h"
|
||||
#include "timer.h"
|
||||
#include "TPinballTable.h"
|
||||
#include "TZmapList.h"
|
||||
|
||||
TBumper::TBumper(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true)
|
||||
{
|
||||
@@ -29,8 +28,9 @@ int TBumper::Message(int code, float value)
|
||||
case 11:
|
||||
{
|
||||
auto nextBmp = static_cast<int>(floor(value));
|
||||
if (2 * nextBmp > ListBitmap->Count() - 1)
|
||||
nextBmp = (ListBitmap->Count() - 1) / 2;
|
||||
auto maxBmp = static_cast<int>(ListBitmap->size()) - 1;
|
||||
if (2 * nextBmp > maxBmp)
|
||||
nextBmp = maxBmp / 2;
|
||||
if (nextBmp < 0)
|
||||
nextBmp = 0;
|
||||
if (nextBmp != BmpIndex)
|
||||
@@ -48,7 +48,7 @@ int TBumper::Message(int code, float value)
|
||||
case 12:
|
||||
{
|
||||
auto nextBmp = BmpIndex + 1;
|
||||
auto maxBmp = ListBitmap->Count() - 1;
|
||||
auto maxBmp = static_cast<int>(ListBitmap->size()) - 1;
|
||||
if (2 * nextBmp > maxBmp)
|
||||
nextBmp = maxBmp / 2;
|
||||
TBumper::Message(11, static_cast<float>(nextBmp));
|
||||
@@ -124,8 +124,8 @@ int TBumper::get_scoring(int index)
|
||||
void TBumper::TimerExpired(int timerId, void* caller)
|
||||
{
|
||||
auto bump = static_cast<TBumper*>(caller);
|
||||
auto bmp = static_cast<gdrv_bitmap8*>(bump->ListBitmap->Get(bump->BmpIndex * 2));
|
||||
auto zMap = static_cast<zmap_header_type*>(bump->ListZMap->Get(bump->BmpIndex * 2));
|
||||
auto bmp = bump->ListBitmap->at(bump->BmpIndex * 2);
|
||||
auto zMap = bump->ListZMap->at(bump->BmpIndex * 2);
|
||||
bump->Timer = 0;
|
||||
render::sprite_set(
|
||||
bump->RenderSprite,
|
||||
@@ -139,8 +139,8 @@ void TBumper::TimerExpired(int timerId, void* caller)
|
||||
void TBumper::Fire()
|
||||
{
|
||||
int bmpIndex = 2 * BmpIndex + 1;
|
||||
auto bmp = static_cast<gdrv_bitmap8*>(ListBitmap->Get(bmpIndex));
|
||||
auto zMap = static_cast<zmap_header_type*>(ListZMap->Get(bmpIndex));
|
||||
auto bmp = ListBitmap->at(bmpIndex);
|
||||
auto zMap = ListZMap->at(bmpIndex);
|
||||
render::sprite_set(
|
||||
RenderSprite,
|
||||
bmp,
|
||||
|
||||
@@ -28,6 +28,6 @@ public:
|
||||
float OriginalThreshold;
|
||||
int SoundIndex4;
|
||||
int SoundIndex3;
|
||||
int Scores[4];
|
||||
TBumper_player_backup PlayerData[4];
|
||||
int Scores[4]{};
|
||||
TBumper_player_backup PlayerData[4]{};
|
||||
};
|
||||
|
||||
@@ -6,7 +6,7 @@ class TCircle :
|
||||
public TEdgeSegment
|
||||
{
|
||||
public:
|
||||
circle_type Circle;
|
||||
circle_type Circle{};
|
||||
|
||||
TCircle(TCollisionComponent* collComp, char* activeFlag, unsigned int collisionGroup, vector_type* center,
|
||||
float radius);
|
||||
|
||||
@@ -2,17 +2,15 @@
|
||||
#include "TCollisionComponent.h"
|
||||
#include "loader.h"
|
||||
#include "maths.h"
|
||||
#include "objlist_class.h"
|
||||
#include "TEdgeSegment.h"
|
||||
#include "TPinballTable.h"
|
||||
|
||||
|
||||
TCollisionComponent::TCollisionComponent(TPinballTable* table, int groupIndex, bool createWall) : TPinballComponent(
|
||||
table, groupIndex, true)
|
||||
TCollisionComponent::TCollisionComponent(TPinballTable* table, int groupIndex, bool createWall) :
|
||||
TPinballComponent(table, groupIndex, true)
|
||||
{
|
||||
visualStruct visual{};
|
||||
|
||||
EdgeList = new objlist_class(4, 4);
|
||||
ActiveFlag = 1;
|
||||
if (GroupName != nullptr)
|
||||
UnusedBaseFlag = 1;
|
||||
@@ -42,22 +40,15 @@ TCollisionComponent::TCollisionComponent(TPinballTable* table, int groupIndex, b
|
||||
|
||||
TCollisionComponent::~TCollisionComponent()
|
||||
{
|
||||
for (TEdgeSegment* edge; EdgeList->Count() > 0;)
|
||||
{
|
||||
edge = static_cast<TEdgeSegment*>(EdgeList->Get(0));
|
||||
EdgeList->Delete(edge);
|
||||
for (auto edge : EdgeList)
|
||||
delete edge;
|
||||
}
|
||||
delete EdgeList;
|
||||
}
|
||||
|
||||
|
||||
void TCollisionComponent::port_draw()
|
||||
{
|
||||
for (int index = EdgeList->Count() - 1; index >= 0; index--)
|
||||
{
|
||||
static_cast<TEdgeSegment*>(EdgeList->Get(index))->port_draw();
|
||||
}
|
||||
for (auto edge : EdgeList)
|
||||
edge->port_draw();
|
||||
}
|
||||
|
||||
int TCollisionComponent::DefaultCollision(TBall* ball, vector_type* nextPosition, vector_type* direction)
|
||||
@@ -70,7 +61,7 @@ int TCollisionComponent::DefaultCollision(TBall* ball, vector_type* nextPosition
|
||||
auto projSpeed = maths::basic_collision(ball, nextPosition, direction, Elasticity, Smoothness, Threshold, Boost);
|
||||
if (projSpeed <= Threshold)
|
||||
{
|
||||
if (projSpeed > 0.2)
|
||||
if (projSpeed > 0.2f)
|
||||
{
|
||||
if (SoftHitSoundId)
|
||||
loader::play_sound(SoftHitSoundId);
|
||||
@@ -92,7 +83,7 @@ void TCollisionComponent::Collision(TBall* ball, vector_type* nextPosition, vect
|
||||
maths::basic_collision(ball, nextPosition, direction, Elasticity, Smoothness, 1000000000.0, 0.0);
|
||||
return;
|
||||
}
|
||||
double projSpeed = maths::basic_collision(
|
||||
auto projSpeed = maths::basic_collision(
|
||||
ball,
|
||||
nextPosition,
|
||||
direction,
|
||||
@@ -102,7 +93,7 @@ void TCollisionComponent::Collision(TBall* ball, vector_type* nextPosition, vect
|
||||
Boost);
|
||||
if (projSpeed <= Threshold)
|
||||
{
|
||||
if (projSpeed <= 0.2)
|
||||
if (projSpeed <= 0.2f)
|
||||
return;
|
||||
soundIndex = SoftHitSoundId;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
#include "TPinballComponent.h"
|
||||
|
||||
class objlist_class;
|
||||
struct vector_type;
|
||||
class TEdgeSegment;
|
||||
class TBall;
|
||||
@@ -9,7 +8,7 @@ class TBall;
|
||||
class TCollisionComponent : public TPinballComponent
|
||||
{
|
||||
public:
|
||||
objlist_class* EdgeList;
|
||||
std::vector<TEdgeSegment*> EdgeList;
|
||||
float Elasticity;
|
||||
float Smoothness;
|
||||
float Boost;
|
||||
|
||||
@@ -4,13 +4,11 @@
|
||||
|
||||
#include "control.h"
|
||||
#include "loader.h"
|
||||
#include "objlist_class.h"
|
||||
#include "timer.h"
|
||||
#include "TPinballTable.h"
|
||||
|
||||
TComponentGroup::TComponentGroup(TPinballTable* table, int groupIndex) : TPinballComponent(table, groupIndex, false)
|
||||
{
|
||||
List = new objlist_class(4, 4);
|
||||
Timer = 0;
|
||||
if (groupIndex > 0)
|
||||
{
|
||||
@@ -21,7 +19,7 @@ TComponentGroup::TComponentGroup(TPinballTable* table, int groupIndex) : TPinbal
|
||||
{
|
||||
auto component = table->find_component(*shortArrPtr);
|
||||
if (component)
|
||||
List->Add(component);
|
||||
List.push_back(component);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -33,7 +31,6 @@ TComponentGroup::~TComponentGroup()
|
||||
timer::kill(Timer);
|
||||
Timer = 0;
|
||||
}
|
||||
delete List;
|
||||
}
|
||||
|
||||
int TComponentGroup::Message(int code, float value)
|
||||
@@ -45,14 +42,14 @@ int TComponentGroup::Message(int code, float value)
|
||||
timer::kill(this->Timer);
|
||||
this->Timer = 0;
|
||||
}
|
||||
if (value > 0.0)
|
||||
if (value > 0.0f)
|
||||
this->Timer = timer::set(value, this, NotifyTimerExpired);
|
||||
}
|
||||
else if (code <= 1007 || code > 1011 && code != 1020 && code != 1022)
|
||||
else if (code <= 1007 || (code > 1011 && code != 1020 && code != 1022))
|
||||
{
|
||||
for (int i = 0; i < List->Count(); i++)
|
||||
for (auto component : List)
|
||||
{
|
||||
static_cast<TPinballComponent*>(List->Get(i))->Message(code, value);
|
||||
component->Message(code, value);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
#include "TPinballComponent.h"
|
||||
|
||||
class objlist_class;
|
||||
|
||||
class TComponentGroup :
|
||||
public TPinballComponent
|
||||
@@ -12,6 +11,6 @@ public:
|
||||
int Message(int code, float value) override;
|
||||
static void NotifyTimerExpired(int timerId, void* caller);
|
||||
|
||||
objlist_class* List;
|
||||
std::vector<TPinballComponent*> List;
|
||||
int Timer;
|
||||
};
|
||||
|
||||
@@ -100,13 +100,12 @@ void TDemo::Collision(TBall* ball, vector_type* nextPosition, vector_type* direc
|
||||
ball->Position.Y = nextPosition->Y;
|
||||
ball->RayMaxDistance -= coef;
|
||||
|
||||
switch (reinterpret_cast<int>(edge->WallValue))
|
||||
switch (reinterpret_cast<size_t>(edge->WallValue))
|
||||
{
|
||||
case 1400:
|
||||
if (!FlipLeftTimer && !FlipLeftFlag)
|
||||
{
|
||||
float time = FlipTimerTime1 + FlipTimerTime2 - static_cast<float>(rand()) *
|
||||
0.00003051850947599719f * (FlipTimerTime2 + FlipTimerTime2);
|
||||
float time = FlipTimerTime1 + FlipTimerTime2 - RandFloat() * (FlipTimerTime2 + FlipTimerTime2);
|
||||
FlipLeftTimer = timer::set(time, this, FlipLeft);
|
||||
}
|
||||
break;
|
||||
@@ -116,8 +115,7 @@ void TDemo::Collision(TBall* ball, vector_type* nextPosition, vector_type* direc
|
||||
case 1402:
|
||||
if (!FlipRightTimer && !FlipRightFlag)
|
||||
{
|
||||
float time = FlipTimerTime1 + FlipTimerTime2 - static_cast<float>(rand()) *
|
||||
0.00003051850947599719f * (FlipTimerTime2 + FlipTimerTime2);
|
||||
float time = FlipTimerTime1 + FlipTimerTime2 - RandFloat() * (FlipTimerTime2 + FlipTimerTime2);
|
||||
FlipRightTimer = timer::set(time, this, FlipRight);
|
||||
}
|
||||
break;
|
||||
@@ -128,7 +126,7 @@ void TDemo::Collision(TBall* ball, vector_type* nextPosition, vector_type* direc
|
||||
if (!PlungerFlag)
|
||||
{
|
||||
PinballTable->Message(1004, ball->TimeNow);
|
||||
float time = static_cast<float>(rand()) * 0.00003051850947599719f + 2.0f;
|
||||
float time = RandFloat() + 2.0f;
|
||||
PlungerFlag = timer::set(time, this, PlungerRelease);
|
||||
}
|
||||
break;
|
||||
@@ -172,8 +170,8 @@ void TDemo::FlipRight(int timerId, void* caller)
|
||||
}
|
||||
demo->PinballTable->Message(1002, pb::time_next);
|
||||
demo->FlipRightFlag = 1;
|
||||
float time = demo->UnFlipTimerTime1 + demo->UnFlipTimerTime2 - static_cast<float>(rand()) *
|
||||
0.00003051850947599719f * (demo->UnFlipTimerTime2 + demo->UnFlipTimerTime2);
|
||||
float time = demo->UnFlipTimerTime1 + demo->UnFlipTimerTime2 - RandFloat() *
|
||||
(demo->UnFlipTimerTime2 + demo->UnFlipTimerTime2);
|
||||
timer::set(time, demo, UnFlipRight);
|
||||
}
|
||||
}
|
||||
@@ -190,8 +188,8 @@ void TDemo::FlipLeft(int timerId, void* caller)
|
||||
}
|
||||
demo->PinballTable->Message(1000, pb::time_next);
|
||||
demo->FlipLeftFlag = 1;
|
||||
float time = demo->UnFlipTimerTime1 + demo->UnFlipTimerTime2 - static_cast<float>(rand()) *
|
||||
0.00003051850947599719f * (demo->UnFlipTimerTime2 + demo->UnFlipTimerTime2);
|
||||
float time = demo->UnFlipTimerTime1 + demo->UnFlipTimerTime2 - RandFloat() *
|
||||
(demo->UnFlipTimerTime2 + demo->UnFlipTimerTime2);
|
||||
timer::set(time, demo, UnFlipLeft);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
#include "pch.h"
|
||||
#include "TEdgeBox.h"
|
||||
|
||||
#include "objlist_class.h"
|
||||
|
||||
TEdgeBox::TEdgeBox()
|
||||
{
|
||||
EdgeList = new objlist_class(0, 4);
|
||||
FieldList = new objlist_class(0, 1);
|
||||
}
|
||||
|
||||
TEdgeBox::~TEdgeBox()
|
||||
{
|
||||
delete EdgeList;
|
||||
delete FieldList;
|
||||
}
|
||||
@@ -1,13 +1,11 @@
|
||||
#pragma once
|
||||
class objlist_class;
|
||||
|
||||
struct field_effect_type;
|
||||
class TEdgeSegment;
|
||||
|
||||
class TEdgeBox
|
||||
{
|
||||
public:
|
||||
TEdgeBox();
|
||||
~TEdgeBox();
|
||||
|
||||
objlist_class* EdgeList;
|
||||
objlist_class* FieldList;
|
||||
std::vector<TEdgeSegment*> EdgeList{};
|
||||
std::vector<field_effect_type*> FieldList{};
|
||||
};
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
|
||||
#include "maths.h"
|
||||
#include "objlist_class.h"
|
||||
#include "TBall.h"
|
||||
#include "TEdgeBox.h"
|
||||
#include "TEdgeSegment.h"
|
||||
@@ -29,32 +28,32 @@ TEdgeManager::~TEdgeManager()
|
||||
|
||||
int TEdgeManager::box_x(float x)
|
||||
{
|
||||
return static_cast<int>((max(0, min(floor((x - X) * AdvanceXInv), (MaxBoxX - 1)))));
|
||||
return std::max(0, std::min(static_cast<int>(floor((x - X) * AdvanceXInv)), MaxBoxX - 1));
|
||||
}
|
||||
|
||||
int TEdgeManager::box_y(float y)
|
||||
{
|
||||
return static_cast<int>((max(0, min(floor((y - Y) * AdvanceYInv), (MaxBoxY - 1)))));
|
||||
return std::max(0, std::min(static_cast<int>(floor((y - Y) * AdvanceYInv)), MaxBoxY - 1));
|
||||
}
|
||||
|
||||
int TEdgeManager::increment_box_x(int x)
|
||||
{
|
||||
return min(x + 1, MaxBoxX - 1);
|
||||
return std::min(x + 1, MaxBoxX - 1);
|
||||
}
|
||||
|
||||
int TEdgeManager::increment_box_y(int y)
|
||||
{
|
||||
return min(y + 1, MaxBoxY - 1);
|
||||
return std::min(y + 1, MaxBoxY - 1);
|
||||
}
|
||||
|
||||
void TEdgeManager::add_edge_to_box(int x, int y, TEdgeSegment* edge)
|
||||
{
|
||||
BoxArray[x + y * MaxBoxX].EdgeList->Add(edge);
|
||||
BoxArray[x + y * MaxBoxX].EdgeList.push_back(edge);
|
||||
}
|
||||
|
||||
void TEdgeManager::add_field_to_box(int x, int y, field_effect_type* field)
|
||||
{
|
||||
BoxArray[x + y * MaxBoxX].FieldList->Add(field);
|
||||
BoxArray[x + y * MaxBoxX].FieldList.push_back(field);
|
||||
}
|
||||
|
||||
int TEdgeManager::TestGridBox(int x, int y, float* distPtr, TEdgeSegment** edgeDst, ray_type* ray, TBall* ball,
|
||||
@@ -64,9 +63,9 @@ int TEdgeManager::TestGridBox(int x, int y, float* distPtr, TEdgeSegment** edgeD
|
||||
{
|
||||
TEdgeBox* edgeBox = &BoxArray[x + y * MaxBoxX];
|
||||
TEdgeSegment** edgePtr = &EdgeArray[edgeIndex];
|
||||
for (auto index = edgeBox->EdgeList->Count() - 1; index >= 0; --index)
|
||||
for (auto it = edgeBox->EdgeList.rbegin(); it != edgeBox->EdgeList.rend(); ++it)
|
||||
{
|
||||
auto edge = static_cast<TEdgeSegment*>(edgeBox->EdgeList->Get(index));
|
||||
auto edge = *it;
|
||||
if (!edge->ProcessedFlag && *edge->ActiveFlag && (edge->CollisionGroup & ray->FieldFlag))
|
||||
{
|
||||
if (!ball->already_hit(edge))
|
||||
@@ -94,9 +93,9 @@ void TEdgeManager::FieldEffects(TBall* ball, vector_type* dstVec)
|
||||
TEdgeBox* edgeBox = &BoxArray[box_x(ball->Position.X) + box_y(ball->Position.Y) *
|
||||
MaxBoxX];
|
||||
|
||||
for (int index = edgeBox->FieldList->Count() - 1; index >= 0; --index)
|
||||
for (auto it = edgeBox->FieldList.rbegin(); it != edgeBox->FieldList.rend(); ++it)
|
||||
{
|
||||
auto field = static_cast<field_effect_type*>(edgeBox->FieldList->Get(index));
|
||||
auto field = *it;
|
||||
if (*field->Flag2Ptr && ball->FieldFlag & field->Mask)
|
||||
{
|
||||
if (field->CollisionComp->FieldEffect(ball, &vec))
|
||||
|
||||
@@ -35,5 +35,5 @@ public:
|
||||
float X;
|
||||
float Y;
|
||||
TEdgeBox* BoxArray;
|
||||
TEdgeSegment* EdgeArray[1000];
|
||||
TEdgeSegment* EdgeArray[1000]{};
|
||||
};
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "pch.h"
|
||||
#include "TEdgeSegment.h"
|
||||
|
||||
#include "objlist_class.h"
|
||||
#include "TCircle.h"
|
||||
#include "TCollisionComponent.h"
|
||||
#include "TLine.h"
|
||||
@@ -19,7 +18,7 @@ void TEdgeSegment::port_draw()
|
||||
}
|
||||
|
||||
TEdgeSegment* TEdgeSegment::install_wall(float* floatArr, TCollisionComponent* collComp, char* activeFlagPtr,
|
||||
unsigned int collisionGroup, float offset, int wallValue)
|
||||
unsigned int collisionGroup, float offset, size_t wallValue)
|
||||
{
|
||||
vector_type center{}, start{}, end{}, prevCenter{}, vec1{}, vec2{}, dstVec{};
|
||||
TEdgeSegment* edge = nullptr;
|
||||
@@ -41,7 +40,7 @@ TEdgeSegment* TEdgeSegment::install_wall(float* floatArr, TCollisionComponent* c
|
||||
circle->place_in_grid();
|
||||
}
|
||||
|
||||
collComp->EdgeList->Add(circle);
|
||||
collComp->EdgeList.push_back(circle);
|
||||
break;
|
||||
}
|
||||
case wall_type::Line:
|
||||
@@ -58,7 +57,7 @@ TEdgeSegment* TEdgeSegment::install_wall(float* floatArr, TCollisionComponent* c
|
||||
line->WallValue = reinterpret_cast<void*>(wallValue);
|
||||
line->Offset(offset);
|
||||
line->place_in_grid();
|
||||
collComp->EdgeList->Add(line);
|
||||
collComp->EdgeList.push_back(line);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -87,15 +86,15 @@ TEdgeSegment* TEdgeSegment::install_wall(float* floatArr, TCollisionComponent* c
|
||||
|
||||
center.X = centerX1;
|
||||
center.Y = centerY1;
|
||||
if (offset != 0.0)
|
||||
if (offset != 0.0f)
|
||||
{
|
||||
vec1.X = centerX1 - prevCenter.X;
|
||||
vec1.Y = center.Y - prevCenter.Y;
|
||||
vec2.X = centerX2 - centerX1;
|
||||
vec2.Y = centerY2 - center.Y;
|
||||
maths::cross(&vec1, &vec2, &dstVec);
|
||||
if (dstVec.Z > 0.0 && offset > 0.0 ||
|
||||
dstVec.Z < 0.0 && offset < 0.0)
|
||||
if ((dstVec.Z > 0.0f && offset > 0.0f) ||
|
||||
(dstVec.Z < 0.0f && offset < 0.0f))
|
||||
{
|
||||
float radius = offset * 1.001f;
|
||||
auto circle = new TCircle(collComp, activeFlagPtr, collisionGroup, ¢er, radius);
|
||||
@@ -104,7 +103,7 @@ TEdgeSegment* TEdgeSegment::install_wall(float* floatArr, TCollisionComponent* c
|
||||
{
|
||||
circle->WallValue = reinterpret_cast<void*>(wallValue);
|
||||
circle->place_in_grid();
|
||||
collComp->EdgeList->Add(circle);
|
||||
collComp->EdgeList.push_back(circle);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -121,7 +120,7 @@ TEdgeSegment* TEdgeSegment::install_wall(float* floatArr, TCollisionComponent* c
|
||||
line->WallValue = reinterpret_cast<void*>(wallValue);
|
||||
line->Offset(offset);
|
||||
line->place_in_grid();
|
||||
collComp->EdgeList->Add(line);
|
||||
collComp->EdgeList.push_back(line);
|
||||
}
|
||||
|
||||
prevCenter = center;
|
||||
|
||||
@@ -16,7 +16,7 @@ public:
|
||||
TCollisionComponent* CollisionComponent;
|
||||
char* ActiveFlag;
|
||||
char ProcessedFlag;
|
||||
void* WallValue;
|
||||
void* WallValue{};
|
||||
unsigned int CollisionGroup;
|
||||
|
||||
TEdgeSegment(TCollisionComponent* collComp, char* activeFlag, unsigned int collisionGroup);
|
||||
@@ -28,5 +28,5 @@ public:
|
||||
virtual float FindCollisionDistance(ray_type* ray) = 0;
|
||||
|
||||
static TEdgeSegment* install_wall(float* floatArr, TCollisionComponent* collComp, char* activeFlagPtr,
|
||||
unsigned int collisionGroup, float offset, int wallValue);
|
||||
unsigned int collisionGroup, float offset, size_t wallValue);
|
||||
};
|
||||
|
||||
@@ -4,13 +4,11 @@
|
||||
|
||||
#include "control.h"
|
||||
#include "loader.h"
|
||||
#include "objlist_class.h"
|
||||
#include "render.h"
|
||||
#include "TBall.h"
|
||||
#include "timer.h"
|
||||
#include "TLine.h"
|
||||
#include "TPinballTable.h"
|
||||
#include "TZmapList.h"
|
||||
|
||||
TFlagSpinner::TFlagSpinner(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, false)
|
||||
{
|
||||
@@ -19,7 +17,7 @@ TFlagSpinner::TFlagSpinner(TPinballTable* table, int groupIndex) : TCollisionCom
|
||||
|
||||
Timer = 0;
|
||||
loader::query_visual(groupIndex, 0, &visual);
|
||||
end.X = *visual.FloatArr;
|
||||
end.X = visual.FloatArr[0];
|
||||
end.Y = visual.FloatArr[1];
|
||||
start.X = visual.FloatArr[2];
|
||||
start.Y = visual.FloatArr[3];
|
||||
@@ -27,7 +25,7 @@ TFlagSpinner::TFlagSpinner(TPinballTable* table, int groupIndex) : TCollisionCom
|
||||
if (line)
|
||||
{
|
||||
line->place_in_grid();
|
||||
EdgeList->Add(line);
|
||||
EdgeList.push_back(line);
|
||||
}
|
||||
|
||||
line = new TLine(this, &ActiveFlag, visual.CollisionGroup, &end, &start);
|
||||
@@ -35,7 +33,7 @@ TFlagSpinner::TFlagSpinner(TPinballTable* table, int groupIndex) : TCollisionCom
|
||||
if (line)
|
||||
{
|
||||
line->place_in_grid();
|
||||
EdgeList->Add(line);
|
||||
EdgeList.push_back(line);
|
||||
}
|
||||
|
||||
SpeedDecrement = 0.64999998f;
|
||||
@@ -62,8 +60,8 @@ int TFlagSpinner::Message(int code, float value)
|
||||
Timer = 0;
|
||||
}
|
||||
BmpIndex = 0;
|
||||
auto bmp = static_cast<gdrv_bitmap8*>(ListBitmap->Get(0));
|
||||
auto zMap = static_cast<zmap_header_type*>(ListZMap->Get(0));
|
||||
auto bmp = ListBitmap->at(0);
|
||||
auto zMap = ListZMap->at(0);
|
||||
render::sprite_set(
|
||||
RenderSprite,
|
||||
bmp,
|
||||
@@ -83,7 +81,7 @@ void TFlagSpinner::Collision(TBall* ball, vector_type* nextPosition, vector_type
|
||||
ball->not_again(edge);
|
||||
|
||||
SpinDirection = 2 * (PrevCollider != edge) - 1;
|
||||
if (ball->Speed == 0.0)
|
||||
if (ball->Speed == 0.0f)
|
||||
Speed = MinSpeed;
|
||||
else
|
||||
Speed = ball->Speed * 20.0f;
|
||||
@@ -109,7 +107,7 @@ void TFlagSpinner::NextFrame()
|
||||
{
|
||||
BmpIndex += SpinDirection;
|
||||
int bmpIndex = BmpIndex;
|
||||
int bmpCount = ListBitmap->Count();
|
||||
int bmpCount = ListBitmap->size();
|
||||
if (bmpIndex >= bmpCount)
|
||||
BmpIndex = 0;
|
||||
else if (bmpIndex < 0)
|
||||
@@ -124,8 +122,8 @@ void TFlagSpinner::NextFrame()
|
||||
control::handler(62, this);
|
||||
}
|
||||
|
||||
auto bmp = static_cast<gdrv_bitmap8*>(ListBitmap->Get(BmpIndex));
|
||||
auto zMap = static_cast<zmap_header_type*>(ListZMap->Get(BmpIndex));
|
||||
auto bmp = ListBitmap->at(BmpIndex);
|
||||
auto zMap = ListZMap->at(BmpIndex);
|
||||
render::sprite_set(
|
||||
RenderSprite,
|
||||
bmp,
|
||||
|
||||
@@ -15,14 +15,14 @@ public:
|
||||
|
||||
static void SpinTimer(int timerId, void* caller);
|
||||
|
||||
float Speed;
|
||||
float Speed{};
|
||||
float MaxSpeed;
|
||||
float MinSpeed;
|
||||
float SpeedDecrement;
|
||||
int SpinDirection;
|
||||
int BmpIndex;
|
||||
int SpinDirection{};
|
||||
int BmpIndex{};
|
||||
int Timer;
|
||||
TEdgeSegment* PrevCollider;
|
||||
int Scores[2];
|
||||
int Scores[2]{};
|
||||
};
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include "render.h"
|
||||
#include "TFlipperEdge.h"
|
||||
#include "timer.h"
|
||||
#include "TZmapList.h"
|
||||
#include "TPinballTable.h"
|
||||
|
||||
TFlipper::TFlipper(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, false)
|
||||
{
|
||||
@@ -21,12 +21,16 @@ TFlipper::TFlipper(TPinballTable* table, int groupIndex) : TCollisionComponent(t
|
||||
Timer = 0;
|
||||
Smoothness = visual.Smoothness;
|
||||
|
||||
auto floatArr = loader::query_float_attribute(groupIndex, 0, 803);
|
||||
auto floatArr2 = loader::query_float_attribute(groupIndex, 0, 805);
|
||||
auto floatArr3 = loader::query_float_attribute(groupIndex, 0, 804);
|
||||
auto collMult = *floatArr;
|
||||
auto bmpCoef2 = *floatArr2;
|
||||
auto bmpCoef1 = *floatArr3;
|
||||
auto collMult = *loader::query_float_attribute(groupIndex, 0, 803);
|
||||
auto retractTime = *loader::query_float_attribute(groupIndex, 0, 805);
|
||||
auto extendTime = *loader::query_float_attribute(groupIndex, 0, 804);
|
||||
|
||||
/*Full tilt hack: different flipper speed*/
|
||||
if (pb::FullTiltMode)
|
||||
{
|
||||
retractTime = 0.08f;
|
||||
extendTime = 0.04f;
|
||||
}
|
||||
auto vecT2 = reinterpret_cast<vector_type*>(loader::query_float_attribute(groupIndex, 0, 802));
|
||||
auto vecT1 = reinterpret_cast<vector_type*>(loader::query_float_attribute(groupIndex, 0, 801));
|
||||
auto origin = reinterpret_cast<vector_type*>(loader::query_float_attribute(groupIndex, 0, 800));
|
||||
@@ -38,8 +42,8 @@ TFlipper::TFlipper(TPinballTable* table, int groupIndex) : TCollisionComponent(t
|
||||
origin,
|
||||
vecT1,
|
||||
vecT2,
|
||||
bmpCoef1,
|
||||
bmpCoef2,
|
||||
extendTime,
|
||||
retractTime,
|
||||
collMult,
|
||||
Elasticity,
|
||||
Smoothness);
|
||||
@@ -47,8 +51,8 @@ TFlipper::TFlipper(TPinballTable* table, int groupIndex) : TCollisionComponent(t
|
||||
FlipperEdge = flipperEdge;
|
||||
if (flipperEdge)
|
||||
{
|
||||
BmpCoef1 = flipperEdge->BmpCoef1 / static_cast<float>(ListBitmap->Count() - 1);
|
||||
BmpCoef2 = flipperEdge->BmpCoef2 / static_cast<float>(ListBitmap->Count() - 1);
|
||||
ExtendAnimationFrameTime = flipperEdge->ExtendTime / static_cast<float>(ListBitmap->size() - 1);
|
||||
RetractAnimationFrameTime = flipperEdge->RetractTime / static_cast<float>(ListBitmap->size() - 1);
|
||||
}
|
||||
BmpIndex = 0;
|
||||
InputTime = 0.0;
|
||||
@@ -61,49 +65,47 @@ TFlipper::~TFlipper()
|
||||
|
||||
int TFlipper::Message(int code, float value)
|
||||
{
|
||||
if (code == 1 || code == 2 || code > 1008 && code <= 1011 || code == 1022)
|
||||
if (code == 1 || code == 2 || (code > 1008 && code <= 1011) || code == 1022)
|
||||
{
|
||||
float timerTime;
|
||||
int soundIndex = 0, code2 = code;
|
||||
int command = code;
|
||||
if (code == 1)
|
||||
{
|
||||
control::handler(1, this);
|
||||
TimerTime = BmpCoef1;
|
||||
soundIndex = HardHitSoundId;
|
||||
TimerTime = ExtendAnimationFrameTime;
|
||||
loader::play_sound(HardHitSoundId);
|
||||
}
|
||||
else if (code == 2)
|
||||
{
|
||||
TimerTime = BmpCoef2;
|
||||
soundIndex = SoftHitSoundId;
|
||||
TimerTime = RetractAnimationFrameTime;
|
||||
loader::play_sound(SoftHitSoundId);
|
||||
}
|
||||
else
|
||||
{
|
||||
code2 = 2;
|
||||
TimerTime = BmpCoef2;
|
||||
// Retract for all non-input messages
|
||||
command = 2;
|
||||
TimerTime = RetractAnimationFrameTime;
|
||||
}
|
||||
|
||||
if (soundIndex)
|
||||
loader::play_sound(soundIndex);
|
||||
if (Timer)
|
||||
{
|
||||
timer::kill(Timer);
|
||||
Timer = 0;
|
||||
}
|
||||
if (MessageField)
|
||||
{
|
||||
auto v10 = value - FlipperEdge->InputTime;
|
||||
timerTime = v10 - floor(v10 / TimerTime) * TimerTime;
|
||||
if (timerTime < 0.0)
|
||||
// Message arrived before animation is finished
|
||||
auto inputDt = value - FlipperEdge->InputTime;
|
||||
timerTime = inputDt - floor(inputDt / TimerTime) * TimerTime;
|
||||
if (timerTime < 0.0f)
|
||||
timerTime = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
timerTime = TimerTime;
|
||||
}
|
||||
MessageField = code2;
|
||||
|
||||
MessageField = command;
|
||||
InputTime = value;
|
||||
if (Timer)
|
||||
timer::kill(Timer);
|
||||
Timer = timer::set(timerTime, this, TimerExpired);
|
||||
FlipperEdge->SetMotion(code2, value);
|
||||
FlipperEdge->SetMotion(command, value);
|
||||
}
|
||||
|
||||
if (code == 1020 || code == 1024)
|
||||
@@ -133,52 +135,46 @@ void TFlipper::Collision(TBall* ball, vector_type* nextPosition, vector_type* di
|
||||
void TFlipper::TimerExpired(int timerId, void* caller)
|
||||
{
|
||||
auto flip = static_cast<TFlipper*>(caller);
|
||||
int timer; // eax
|
||||
int bmpCountSub1 = flip->ListBitmap->size() - 1;
|
||||
|
||||
auto newBmpIndex = static_cast<int>(floor((pb::time_now - flip->InputTime) / flip->TimerTime));
|
||||
if (newBmpIndex > bmpCountSub1)
|
||||
newBmpIndex = bmpCountSub1;
|
||||
if (newBmpIndex < 0)
|
||||
newBmpIndex = 0;
|
||||
|
||||
bool bmpIndexOutOfBounds = false;
|
||||
auto bmpIndexAdvance = static_cast<int>(floor((pb::time_now - flip->InputTime) / flip->TimerTime + 0.5f));
|
||||
int bmpCount = flip->ListBitmap->Count();
|
||||
if (bmpIndexAdvance > bmpCount)
|
||||
bmpIndexAdvance = bmpCount;
|
||||
if (bmpIndexAdvance < 0)
|
||||
bmpIndexAdvance = 0;
|
||||
|
||||
if (!bmpIndexAdvance)
|
||||
bmpIndexAdvance = 1;
|
||||
|
||||
if (flip->MessageField == 1)
|
||||
{
|
||||
flip->BmpIndex += bmpIndexAdvance;
|
||||
int countSub1 = flip->ListBitmap->Count() - 1;
|
||||
if (flip->BmpIndex >= countSub1)
|
||||
flip->BmpIndex = newBmpIndex;
|
||||
if (flip->BmpIndex >= bmpCountSub1)
|
||||
{
|
||||
flip->BmpIndex = countSub1;
|
||||
flip->BmpIndex = bmpCountSub1;
|
||||
bmpIndexOutOfBounds = true;
|
||||
}
|
||||
}
|
||||
if (flip->MessageField == 2)
|
||||
{
|
||||
flip->BmpIndex -= bmpIndexAdvance;
|
||||
timer = 0;
|
||||
flip->BmpIndex = bmpCountSub1 - newBmpIndex;
|
||||
if (flip->BmpIndex <= 0)
|
||||
{
|
||||
flip->BmpIndex = 0;
|
||||
bmpIndexOutOfBounds = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
timer = 0;
|
||||
}
|
||||
|
||||
if (bmpIndexOutOfBounds)
|
||||
{
|
||||
flip->MessageField = 0;
|
||||
flip->Timer = 0;
|
||||
}
|
||||
else
|
||||
timer = timer::set(flip->TimerTime, flip, TimerExpired);
|
||||
flip->Timer = timer;
|
||||
{
|
||||
flip->Timer = timer::set(flip->TimerTime, flip, TimerExpired);
|
||||
}
|
||||
|
||||
auto bmp = static_cast<gdrv_bitmap8*>(flip->ListBitmap->Get(flip->BmpIndex));
|
||||
auto zMap = static_cast<zmap_header_type*>(flip->ListZMap->Get(flip->BmpIndex));
|
||||
auto bmp = flip->ListBitmap->at(flip->BmpIndex);
|
||||
auto zMap = flip->ListZMap->at(flip->BmpIndex);
|
||||
render::sprite_set(
|
||||
flip->RenderSprite,
|
||||
bmp,
|
||||
|
||||
@@ -19,8 +19,8 @@ public:
|
||||
int BmpIndex;
|
||||
TFlipperEdge* FlipperEdge;
|
||||
int Timer;
|
||||
float BmpCoef1;
|
||||
float BmpCoef2;
|
||||
float TimerTime;
|
||||
float ExtendAnimationFrameTime{};
|
||||
float RetractAnimationFrameTime{};
|
||||
float TimerTime{};
|
||||
float InputTime;
|
||||
};
|
||||
|
||||
@@ -12,15 +12,15 @@ line_type TFlipperEdge::lineA, TFlipperEdge::lineB;
|
||||
circle_type TFlipperEdge::circlebase, TFlipperEdge::circleT1;
|
||||
|
||||
TFlipperEdge::TFlipperEdge(TCollisionComponent* collComp, char* activeFlag, unsigned int collisionGroup, TPinballTable* table,
|
||||
vector_type* origin, vector_type* vecT1, vector_type* vecT2, float bmpCoef1, float bmpCoef2,
|
||||
vector_type* origin, vector_type* vecT1, vector_type* vecT2, float extendTime, float retractTime,
|
||||
float collMult, float elasticity, float smoothness): TEdgeSegment(collComp, activeFlag, collisionGroup)
|
||||
{
|
||||
vector_type crossProd{}, vecDir1{}, vecDir2{};
|
||||
|
||||
Elasticity = elasticity;
|
||||
Smoothness = smoothness;
|
||||
BmpCoef1 = bmpCoef1;
|
||||
BmpCoef2 = bmpCoef2;
|
||||
ExtendTime = extendTime;
|
||||
RetractTime = retractTime;
|
||||
CollisionMult = collMult;
|
||||
|
||||
T1Src = *vecT1;
|
||||
@@ -48,7 +48,7 @@ TFlipperEdge::TFlipperEdge(TCollisionComponent* collComp, char* activeFlag, unsi
|
||||
|
||||
AngleMax = acos(maths::DotProduct(&vecDir1, &vecDir2));
|
||||
maths::cross(&vecDir1, &vecDir2, &crossProd);
|
||||
if (crossProd.Z < 0.0)
|
||||
if (crossProd.Z < 0.0f)
|
||||
AngleMax = -AngleMax;
|
||||
FlipperFlag = 0;
|
||||
Angle1 = 0.0;
|
||||
@@ -67,7 +67,7 @@ TFlipperEdge::TFlipperEdge(TCollisionComponent* collComp, char* activeFlag, unsi
|
||||
B2Src.X = dirY1 * CircleT1Radius + vecT1->X;
|
||||
B2Src.Y = dirX1 * CircleT1Radius + vecT1->Y;
|
||||
|
||||
if (AngleMax < 0.0)
|
||||
if (AngleMax < 0.0f)
|
||||
{
|
||||
maths::vswap(&A1Src, &B1Src);
|
||||
maths::vswap(&A2Src, &B2Src);
|
||||
@@ -78,9 +78,9 @@ TFlipperEdge::TFlipperEdge(TCollisionComponent* collComp, char* activeFlag, unsi
|
||||
auto distance1 = sqrt(dy * dy + dx * dx) + table->CollisionCompOffset + vecT1->Z;
|
||||
DistanceDivSq = distance1 * distance1;
|
||||
|
||||
float bmpCoef = min(BmpCoef1, BmpCoef2);
|
||||
float minMoveTime = std::min(ExtendTime, RetractTime);
|
||||
auto distance = maths::Distance(vecT1, vecT2);
|
||||
CollisionTimeAdvance = bmpCoef / (distance / CircleT1Radius + distance / CircleT1Radius);
|
||||
CollisionTimeAdvance = minMoveTime / (distance / CircleT1Radius + distance / CircleT1Radius);
|
||||
|
||||
TFlipperEdge::place_in_grid();
|
||||
EdgeCollisionFlag = 0;
|
||||
@@ -109,7 +109,6 @@ float TFlipperEdge::FindCollisionDistance(ray_type* ray)
|
||||
{
|
||||
if (FlipperFlag == 0)
|
||||
{
|
||||
EdgeCollisionFlag = 0;
|
||||
CollisionFlag1 = 0;
|
||||
CollisionFlag2 = 0;
|
||||
set_control_points(ogRay->TimeNow);
|
||||
@@ -122,7 +121,7 @@ float TFlipperEdge::FindCollisionDistance(ray_type* ray)
|
||||
srcRay.MaxDistance = ogRay->MaxDistance;
|
||||
srcRay.Origin = ogRay->Origin;
|
||||
auto distance = maths::distance_to_flipper(&srcRay, &dstRay);
|
||||
if (distance == 0.0)
|
||||
if (distance == 0.0f)
|
||||
{
|
||||
NextBallPosition = dstRay.Origin;
|
||||
NextBallPosition.X -= srcRay.Direction.X * 1e-05f;
|
||||
@@ -167,14 +166,14 @@ float TFlipperEdge::FindCollisionDistance(ray_type* ray)
|
||||
srcRay.Origin.X = ogRay->Origin.X - srcRay.Direction.X * 5.0f;
|
||||
srcRay.Origin.Y = ogRay->Origin.Y - srcRay.Direction.Y * 5.0f;
|
||||
srcRay.MaxDistance = ogRay->MaxDistance + 10.0f;
|
||||
if (maths::distance_to_flipper(&srcRay, &dstRay) >= 1e+09)
|
||||
if (maths::distance_to_flipper(&srcRay, &dstRay) >= 1e+09f)
|
||||
{
|
||||
srcRay.Direction.X = RotOrigin.X - ogRay->Origin.X;
|
||||
srcRay.Direction.Y = RotOrigin.Y - ogRay->Origin.Y;
|
||||
maths::normalize_2d(&srcRay.Direction);
|
||||
srcRay.Origin.X = ogRay->Origin.X - srcRay.Direction.X * 5.0f;
|
||||
srcRay.Origin.Y = ogRay->Origin.Y - srcRay.Direction.Y * 5.0f;
|
||||
if (maths::distance_to_flipper(&srcRay, &dstRay) >= 1e+09)
|
||||
if (maths::distance_to_flipper(&srcRay, &dstRay) >= 1e+09f)
|
||||
{
|
||||
return 1e+09;
|
||||
}
|
||||
@@ -221,7 +220,7 @@ float TFlipperEdge::FindCollisionDistance(ray_type* ray)
|
||||
srcRay.Origin.X = posX - srcRay.Direction.X * 5.0f;
|
||||
srcRay.Origin.Y = posY - srcRay.Direction.Y * 5.0f;
|
||||
srcRay.MaxDistance = ogRay->MaxDistance + 10.0f;
|
||||
if (maths::distance_to_flipper(&srcRay, &dstRay) >= 1e+09)
|
||||
if (maths::distance_to_flipper(&srcRay, &dstRay) >= 1e+09f)
|
||||
{
|
||||
NextBallPosition.X = posX;
|
||||
NextBallPosition.Y = posY;
|
||||
@@ -252,7 +251,7 @@ float TFlipperEdge::FindCollisionDistance(ray_type* ray)
|
||||
srcRay.MaxDistance = ogRay->MaxDistance + 10.0f;
|
||||
auto distance = maths::distance_to_flipper(&srcRay, &dstRay);
|
||||
CollisionDirection = dstRay.Direction;
|
||||
if (distance >= 1e+09)
|
||||
if (distance >= 1e+09f)
|
||||
{
|
||||
return 1e+09;
|
||||
}
|
||||
@@ -267,7 +266,7 @@ float TFlipperEdge::FindCollisionDistance(ray_type* ray)
|
||||
srcRay.Origin = ogRay->Origin;
|
||||
srcRay.MaxDistance = rayMaxDistance;
|
||||
auto distance = maths::distance_to_flipper(&srcRay, &dstRay);
|
||||
if (distance < 1e+09)
|
||||
if (distance < 1e+09f)
|
||||
{
|
||||
NextBallPosition = dstRay.Origin;
|
||||
NextBallPosition.X -= srcRay.Direction.X * 1e-05f;
|
||||
@@ -276,11 +275,11 @@ float TFlipperEdge::FindCollisionDistance(ray_type* ray)
|
||||
if (FlipperFlag == 2)
|
||||
{
|
||||
linePtr = &lineB.PerpendicularL;
|
||||
CollisionFlag1 = AngleMax <= 0.0;
|
||||
CollisionFlag1 = AngleMax <= 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
CollisionFlag1 = AngleMax > 0.0;
|
||||
CollisionFlag1 = AngleMax > 0.0f;
|
||||
linePtr = &lineA.PerpendicularL;
|
||||
}
|
||||
CollisionLinePerp = *linePtr;
|
||||
@@ -310,12 +309,12 @@ void TFlipperEdge::EdgeCollision(TBall* ball, float coef)
|
||||
float dx = NextBallPosition.X - RotOrigin.X;
|
||||
float dy = NextBallPosition.Y - RotOrigin.Y;
|
||||
float distance = dy * dy + dx * dx;
|
||||
if (circlebase.RadiusSq * 1.01 < distance)
|
||||
if (circlebase.RadiusSq * 1.01f < distance)
|
||||
{
|
||||
float v11;
|
||||
float v20 = sqrt(distance / DistanceDivSq) * (fabs(AngleMax) / AngleMult);
|
||||
float dot1 = maths::DotProduct(&CollisionLinePerp, &CollisionDirection);
|
||||
if (dot1 >= 0.0)
|
||||
if (dot1 >= 0.0f)
|
||||
v11 = dot1 * v20;
|
||||
else
|
||||
v11 = 0.0;
|
||||
@@ -323,7 +322,7 @@ void TFlipperEdge::EdgeCollision(TBall* ball, float coef)
|
||||
}
|
||||
}
|
||||
|
||||
float threshold = boost <= 0.0 ? 1000000000.0f : -1.0f;
|
||||
float threshold = boost <= 0.0f ? 1000000000.0f : -1.0f;
|
||||
maths::basic_collision(
|
||||
ball,
|
||||
&NextBallPosition,
|
||||
@@ -339,7 +338,7 @@ void TFlipperEdge::EdgeCollision(TBall* ball, float coef)
|
||||
float dx = NextBallPosition.X - RotOrigin.X;
|
||||
float dy = NextBallPosition.Y - RotOrigin.Y;
|
||||
float distance = dy * dy + dx * dx;
|
||||
if (circlebase.RadiusSq * 1.01 < distance)
|
||||
if (circlebase.RadiusSq * 1.01f < distance)
|
||||
elasticity = (1.0f - sqrt(distance / DistanceDivSq)) * Elasticity;
|
||||
else
|
||||
elasticity = Elasticity;
|
||||
@@ -420,15 +419,15 @@ float TFlipperEdge::flipper_angle(float timeNow)
|
||||
if (!FlipperFlag)
|
||||
return Angle1;
|
||||
float angle = (Angle1 - Angle2) / AngleMax * AngleMult;
|
||||
if (angle < 0.0)
|
||||
if (angle < 0.0f)
|
||||
angle = -angle;
|
||||
|
||||
if (angle >= 0.0000001)
|
||||
if (angle >= 0.0000001f)
|
||||
angle = (timeNow - InputTime) / angle;
|
||||
else
|
||||
angle = 1.0;
|
||||
|
||||
angle = min(1, max(angle, 0));
|
||||
angle = std::min(1.0f, std::max(angle, 0.0f));
|
||||
if (FlipperFlag == 2)
|
||||
angle = 1.0f - angle;
|
||||
return angle * AngleMax;
|
||||
@@ -439,23 +438,23 @@ int TFlipperEdge::is_ball_inside(float x, float y)
|
||||
vector_type testPoint{};
|
||||
float dx = RotOrigin.X - x;
|
||||
float dy = RotOrigin.Y - y;
|
||||
if ((A2.X - A1.X) * (y - A1.Y) - (A2.Y - A1.Y) * (x - A1.X) >= 0.0 &&
|
||||
(B1.X - A2.X) * (y - A2.Y) - (B1.Y - A2.Y) * (x - A2.X) >= 0.0 &&
|
||||
(B2.X - B1.X) * (y - B1.Y) - (B2.Y - B1.Y) * (x - B1.X) >= 0.0 &&
|
||||
(A1.X - B2.X) * (y - B2.Y) - (A1.Y - B2.Y) * (x - B2.X) >= 0.0 ||
|
||||
if (((A2.X - A1.X) * (y - A1.Y) - (A2.Y - A1.Y) * (x - A1.X) >= 0.0f &&
|
||||
(B1.X - A2.X) * (y - A2.Y) - (B1.Y - A2.Y) * (x - A2.X) >= 0.0f &&
|
||||
(B2.X - B1.X) * (y - B1.Y) - (B2.Y - B1.Y) * (x - B1.X) >= 0.0f &&
|
||||
(A1.X - B2.X) * (y - B2.Y) - (A1.Y - B2.Y) * (x - B2.X) >= 0.0f) ||
|
||||
dy * dy + dx * dx <= CirclebaseRadiusSq ||
|
||||
(T1.Y - y) * (T1.Y - y) + (T1.X - x) * (T1.X - x) < CircleT1RadiusSq)
|
||||
{
|
||||
float flipperLR = AngleMax < 0.0 ? -1.0f : 1.0f;
|
||||
float flipperLR = AngleMax < 0.0f ? -1.0f : 1.0f;
|
||||
if (FlipperFlag == 1)
|
||||
testPoint = AngleMax < 0.0 ? B1 : B2;
|
||||
testPoint = AngleMax < 0.0f ? B1 : B2;
|
||||
else if (FlipperFlag == 2)
|
||||
testPoint = AngleMax < 0.0 ? A2 : A1;
|
||||
testPoint = AngleMax < 0.0f ? A2 : A1;
|
||||
else
|
||||
testPoint = T1;
|
||||
|
||||
if (((y - testPoint.Y) * (RotOrigin.X - testPoint.X) -
|
||||
(x - testPoint.X) * (RotOrigin.Y - testPoint.Y)) * flipperLR < 0.0)
|
||||
(x - testPoint.X) * (RotOrigin.Y - testPoint.Y)) * flipperLR < 0.0f)
|
||||
return 4;
|
||||
return 5;
|
||||
}
|
||||
@@ -469,12 +468,12 @@ void TFlipperEdge::SetMotion(int code, float value)
|
||||
case 1:
|
||||
Angle2 = flipper_angle(value);
|
||||
Angle1 = AngleMax;
|
||||
AngleMult = BmpCoef1;
|
||||
AngleMult = ExtendTime;
|
||||
break;
|
||||
case 2:
|
||||
Angle2 = flipper_angle(value);
|
||||
Angle1 = 0.0;
|
||||
AngleMult = BmpCoef2;
|
||||
AngleMult = RetractTime;
|
||||
break;
|
||||
case 1024:
|
||||
FlipperFlag = 0;
|
||||
|
||||
@@ -8,7 +8,7 @@ class TFlipperEdge : public TEdgeSegment
|
||||
{
|
||||
public:
|
||||
TFlipperEdge(TCollisionComponent* collComp, char* activeFlag, unsigned int collisionGroup, TPinballTable* table,
|
||||
vector_type* origin, vector_type* vecT1, vector_type* vecT2, float bmpCoef1, float bmpCoef2, float collMult,
|
||||
vector_type* origin, vector_type* vecT1, vector_type* vecT2, float extendTime, float retractTime, float collMult,
|
||||
float elasticity, float smoothness);
|
||||
void port_draw() override;
|
||||
float FindCollisionDistance(ray_type* ray) override;
|
||||
@@ -23,7 +23,7 @@ public:
|
||||
int FlipperFlag;
|
||||
float Elasticity;
|
||||
float Smoothness;
|
||||
vector_type RotOrigin;
|
||||
vector_type RotOrigin{};
|
||||
float CirclebaseRadius;
|
||||
float CircleT1Radius;
|
||||
float CirclebaseRadiusSq;
|
||||
@@ -31,28 +31,28 @@ public:
|
||||
float CirclebaseRadiusMSq;
|
||||
float CircleT1RadiusMSq;
|
||||
float AngleMax;
|
||||
float Angle2;
|
||||
float Angle2{};
|
||||
float Angle1;
|
||||
int CollisionFlag1;
|
||||
int CollisionFlag2;
|
||||
vector_type CollisionLinePerp;
|
||||
vector_type A1Src;
|
||||
vector_type A2Src;
|
||||
vector_type B1Src;
|
||||
vector_type B2Src;
|
||||
int CollisionFlag2{};
|
||||
vector_type CollisionLinePerp{};
|
||||
vector_type A1Src{};
|
||||
vector_type A2Src{};
|
||||
vector_type B1Src{};
|
||||
vector_type B2Src{};
|
||||
float CollisionMult;
|
||||
vector_type T1Src;
|
||||
vector_type T2Src;
|
||||
vector_type T1Src{};
|
||||
vector_type T2Src{};
|
||||
float DistanceDivSq;
|
||||
float CollisionTimeAdvance;
|
||||
vector_type CollisionDirection;
|
||||
vector_type CollisionDirection{};
|
||||
int EdgeCollisionFlag;
|
||||
float InputTime;
|
||||
float AngleStopTime;
|
||||
float AngleMult;
|
||||
float BmpCoef1;
|
||||
float BmpCoef2;
|
||||
vector_type NextBallPosition;
|
||||
float ExtendTime;
|
||||
float RetractTime;
|
||||
vector_type NextBallPosition{};
|
||||
|
||||
static float flipper_sin_angle, flipper_cos_angle;
|
||||
static vector_type A1, A2, B1, B2, T1;
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include "control.h"
|
||||
#include "loader.h"
|
||||
#include "render.h"
|
||||
#include "TZmapList.h"
|
||||
|
||||
TGate::TGate(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true)
|
||||
{
|
||||
@@ -15,7 +14,7 @@ TGate::TGate(TPinballTable* table, int groupIndex) : TCollisionComponent(table,
|
||||
SoundIndex4 = visual.SoundIndex4;
|
||||
SoundIndex3 = visual.SoundIndex3;
|
||||
ActiveFlag = 1;
|
||||
render::sprite_set_bitmap(RenderSprite, static_cast<gdrv_bitmap8*>(ListBitmap->Get(0)));
|
||||
render::sprite_set_bitmap(RenderSprite, ListBitmap->at(0));
|
||||
control::handler(1024, this);
|
||||
}
|
||||
|
||||
@@ -32,7 +31,7 @@ int TGate::Message(int code, float value)
|
||||
else if (code == 54 || code == 1024)
|
||||
{
|
||||
ActiveFlag = 1;
|
||||
render::sprite_set_bitmap(RenderSprite, static_cast<gdrv_bitmap8*>(ListBitmap->Get(0)));
|
||||
render::sprite_set_bitmap(RenderSprite, ListBitmap->at(0));
|
||||
if (code == 54)
|
||||
loader::play_sound(SoundIndex4);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#include "control.h"
|
||||
#include "loader.h"
|
||||
#include "objlist_class.h"
|
||||
#include "pb.h"
|
||||
#include "TBall.h"
|
||||
#include "timer.h"
|
||||
#include "TPinballTable.h"
|
||||
@@ -19,36 +19,33 @@ THole::THole(TPinballTable* table, int groupIndex) : TCollisionComponent(table,
|
||||
MessageField = 0;
|
||||
Timer = 0;
|
||||
BallCapturedFlag = 0;
|
||||
auto floatArr1 = loader::query_float_attribute(groupIndex, 0, 407);
|
||||
if (floatArr1)
|
||||
Unknown3 = *floatArr1;
|
||||
else
|
||||
Unknown3 = 0.25;
|
||||
auto floatArr2 = loader::query_float_attribute(groupIndex, 0, 701);
|
||||
if (floatArr2)
|
||||
GravityMult = *floatArr2;
|
||||
else
|
||||
GravityMult = 0.5;
|
||||
Unknown3 = loader::query_float_attribute(groupIndex, 0, 407, 0.25f);
|
||||
GravityMult = loader::query_float_attribute(groupIndex, 0, 701, 0.2f);
|
||||
GravityPull = *loader::query_float_attribute(groupIndex, 0, 305);
|
||||
|
||||
loader::query_visual(groupIndex, 0, &visual);
|
||||
Circle.Center.X = visual.FloatArr[0];
|
||||
Circle.Center.Y = visual.FloatArr[1];
|
||||
Circle.RadiusSq = *loader::query_float_attribute(groupIndex, 0, 306) * visual.FloatArr[2];
|
||||
if (Circle.RadiusSq == 0.0)
|
||||
if (Circle.RadiusSq == 0.0f)
|
||||
Circle.RadiusSq = 0.001f;
|
||||
|
||||
auto tCircle = new TCircle(this, &ActiveFlag, visual.CollisionGroup, reinterpret_cast<vector_type*>(visual.FloatArr),
|
||||
auto tCircle = new TCircle(this, &ActiveFlag, visual.CollisionGroup,
|
||||
reinterpret_cast<vector_type*>(visual.FloatArr),
|
||||
Circle.RadiusSq);
|
||||
if (tCircle)
|
||||
{
|
||||
tCircle->place_in_grid();
|
||||
EdgeList->Add(tCircle);
|
||||
EdgeList.push_back(tCircle);
|
||||
}
|
||||
|
||||
ZSetValue = loader::query_float_attribute(groupIndex, 0, 408)[2];
|
||||
FieldFlag = static_cast<int>(floor(*loader::query_float_attribute(groupIndex, 0, 1304)));
|
||||
|
||||
/*Full tilt hack - FieldFlag should be on*/
|
||||
if (pb::FullTiltMode)
|
||||
FieldFlag = 1;
|
||||
|
||||
Circle.RadiusSq = visual.FloatArr[2] * visual.FloatArr[2];
|
||||
circle.RadiusSq = Circle.RadiusSq;
|
||||
circle.Center.X = Circle.Center.X;
|
||||
@@ -84,7 +81,11 @@ void THole::Collision(TBall* ball, vector_type* nextPosition, vector_type* direc
|
||||
ball->Position.X = Circle.Center.X;
|
||||
ball->Position.Y = Circle.Center.Y;
|
||||
ball->Acceleration.Z = 0.0;
|
||||
Timer = timer::set(0.5f, this, TimerExpired);
|
||||
|
||||
// Ramp hole has no delay in FT.
|
||||
auto captureTime = pb::FullTiltMode ? 0 : 0.5f;
|
||||
Timer = timer::set(captureTime, this, TimerExpired);
|
||||
|
||||
if (!PinballTable->TiltLockFlag)
|
||||
{
|
||||
loader::play_sound(HardHitSoundId);
|
||||
|
||||
@@ -16,7 +16,7 @@ public:
|
||||
static void TimerExpired(int timerId, void* caller);
|
||||
|
||||
int BallCapturedFlag;
|
||||
int BallCapturedSecondStage;
|
||||
int BallCapturedSecondStage{};
|
||||
int Timer;
|
||||
float Unknown3;
|
||||
float Unknown4;
|
||||
@@ -24,6 +24,6 @@ public:
|
||||
float ZSetValue;
|
||||
int FieldFlag;
|
||||
float GravityPull;
|
||||
circle_type Circle;
|
||||
field_effect_type Field;
|
||||
circle_type Circle{};
|
||||
field_effect_type Field{};
|
||||
};
|
||||
|
||||
@@ -8,14 +8,13 @@
|
||||
#include "render.h"
|
||||
#include "timer.h"
|
||||
#include "TPinballTable.h"
|
||||
#include "TZmapList.h"
|
||||
|
||||
TKickback::TKickback(TPinballTable* table, int groupIndex): TCollisionComponent(table, groupIndex, true)
|
||||
{
|
||||
MessageField = 0;
|
||||
Timer = 0;
|
||||
ActiveFlag = 0;
|
||||
TimerTime = 0.69999999f;
|
||||
KickActiveFlag = 0;
|
||||
TimerTime = 0.7f;
|
||||
TimerTime2 = 0.1f;
|
||||
Threshold = 1000000000.0f;
|
||||
}
|
||||
@@ -28,7 +27,7 @@ int TKickback::Message(int code, float value)
|
||||
if (ListBitmap)
|
||||
render::sprite_set_bitmap(RenderSprite, nullptr);
|
||||
Timer = 0;
|
||||
ActiveFlag = 0;
|
||||
KickActiveFlag = 0;
|
||||
Threshold = 1000000000.0;
|
||||
}
|
||||
return 0;
|
||||
@@ -44,14 +43,14 @@ void TKickback::Collision(TBall* ball, vector_type* nextPosition, vector_type* d
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ActiveFlag)
|
||||
if (!KickActiveFlag)
|
||||
{
|
||||
Threshold = 1000000000.0;
|
||||
ActiveFlag = 1;
|
||||
KickActiveFlag = 1;
|
||||
Timer = timer::set(TimerTime, this, TimerExpired);
|
||||
}
|
||||
if (DefaultCollision(ball, nextPosition, direction))
|
||||
ActiveFlag = 0;
|
||||
KickActiveFlag = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,15 +58,15 @@ void TKickback::TimerExpired(int timerId, void* caller)
|
||||
{
|
||||
auto kick = static_cast<TKickback*>(caller);
|
||||
|
||||
if (kick->ActiveFlag)
|
||||
if (kick->KickActiveFlag)
|
||||
{
|
||||
kick->Threshold = 0.0;
|
||||
kick->Timer = timer::set(kick->TimerTime2, kick, TimerExpired);
|
||||
loader::play_sound(kick->HardHitSoundId);
|
||||
if (kick->ListBitmap)
|
||||
{
|
||||
auto bmp = static_cast<gdrv_bitmap8*>(kick->ListBitmap->Get(1));
|
||||
auto zMap = static_cast<zmap_header_type*>(kick->ListZMap->Get(1));
|
||||
auto bmp = kick->ListBitmap->at(1);
|
||||
auto zMap = kick->ListZMap->at(1);
|
||||
render::sprite_set(
|
||||
kick->RenderSprite,
|
||||
bmp,
|
||||
@@ -80,8 +79,8 @@ void TKickback::TimerExpired(int timerId, void* caller)
|
||||
{
|
||||
if (kick->ListBitmap)
|
||||
{
|
||||
auto bmp = static_cast<gdrv_bitmap8*>(kick->ListBitmap->Get(0));
|
||||
auto zMap = static_cast<zmap_header_type*>(kick->ListZMap->Get(0));
|
||||
auto bmp = kick->ListBitmap->at(0);
|
||||
auto zMap = kick->ListZMap->at(0);
|
||||
render::sprite_set(
|
||||
kick->RenderSprite,
|
||||
bmp,
|
||||
|
||||
@@ -15,5 +15,5 @@ public:
|
||||
float TimerTime;
|
||||
float TimerTime2;
|
||||
int Timer;
|
||||
int ActiveFlag;
|
||||
int KickActiveFlag;
|
||||
};
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#include "control.h"
|
||||
#include "loader.h"
|
||||
#include "objlist_class.h"
|
||||
#include "pb.h"
|
||||
#include "TBall.h"
|
||||
#include "TCircle.h"
|
||||
#include "timer.h"
|
||||
@@ -30,21 +30,22 @@ TKickout::TKickout(TPinballTable* table, int groupIndex, bool someFlag): TCollis
|
||||
SoftHitSoundId = visual.SoftHitSoundId;
|
||||
HardHitSoundId = visual.Kicker.HardHitSoundId;
|
||||
|
||||
Circle.Center.X = *visual.FloatArr;
|
||||
Circle.Center.X = visual.FloatArr[0];
|
||||
Circle.Center.Y = visual.FloatArr[1];
|
||||
Circle.RadiusSq = *loader::query_float_attribute(groupIndex, 0, 306) * visual.FloatArr[2];
|
||||
if (Circle.RadiusSq == 0.0)
|
||||
if (Circle.RadiusSq == 0.0f)
|
||||
Circle.RadiusSq = 0.001f;
|
||||
auto tCircle = new TCircle(this, &ActiveFlag, visual.CollisionGroup,
|
||||
reinterpret_cast<vector_type*>(visual.FloatArr), Circle.RadiusSq);
|
||||
if (tCircle)
|
||||
{
|
||||
tCircle->place_in_grid();
|
||||
EdgeList->Add(tCircle);
|
||||
EdgeList.push_back(tCircle);
|
||||
}
|
||||
|
||||
Circle.RadiusSq = visual.FloatArr[2] * visual.FloatArr[2];
|
||||
CollisionBallSetZ = loader::query_float_attribute(groupIndex, 0, 408)[2];
|
||||
auto zAttr = loader::query_float_attribute(groupIndex, 0, 408);
|
||||
CollisionBallSetZ = pb::FullTiltMode ? zAttr[3] : zAttr[2];
|
||||
ThrowSpeedMult2 = visual.Kicker.ThrowBallMult * 0.01f;
|
||||
BallAcceleration = visual.Kicker.ThrowBallAcceleration;
|
||||
ThrowAngleMult = visual.Kicker.ThrowBallAngleMult;
|
||||
@@ -67,7 +68,7 @@ int TKickout::Message(int code, float value)
|
||||
case 55:
|
||||
if (KickFlag1)
|
||||
{
|
||||
if (value < 0.0)
|
||||
if (value < 0.0f)
|
||||
value = TimerTime1;
|
||||
Timer = timer::set(value, this, TimerExpired);
|
||||
}
|
||||
|
||||
@@ -24,14 +24,14 @@ public:
|
||||
float TimerTime1;
|
||||
float TimerTime2;
|
||||
float CollisionBallSetZ;
|
||||
TBall* Ball;
|
||||
TBall* Ball{};
|
||||
float FieldMult;
|
||||
circle_type Circle;
|
||||
float OriginalBallZ;
|
||||
vector_type BallAcceleration;
|
||||
circle_type Circle{};
|
||||
float OriginalBallZ{};
|
||||
vector_type BallAcceleration{};
|
||||
float ThrowAngleMult;
|
||||
float ThrowSpeedMult1;
|
||||
float ThrowSpeedMult2;
|
||||
field_effect_type Field;
|
||||
int Scores[5];
|
||||
field_effect_type Field{};
|
||||
int Scores[5]{};
|
||||
};
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#include "render.h"
|
||||
#include "timer.h"
|
||||
#include "TPinballTable.h"
|
||||
#include "TZmapList.h"
|
||||
|
||||
TLight::TLight(TPinballTable* table, int groupIndex) : TPinballComponent(table, groupIndex, true)
|
||||
{
|
||||
@@ -143,14 +142,14 @@ int TLight::Message(int code, float value)
|
||||
schedule_timeout(value);
|
||||
break;
|
||||
case 11:
|
||||
BmpIndex2 = static_cast<int>(floor(value));
|
||||
if (BmpIndex2 > ListBitmap->Count())
|
||||
BmpIndex2 = ListBitmap->Count();
|
||||
bmpIndex = 0;
|
||||
BmpIndex2 = static_cast<int>(floor(value));
|
||||
if (BmpIndex2 > static_cast<int>(ListBitmap->size()))
|
||||
BmpIndex2 = ListBitmap->size();
|
||||
if (BmpIndex2 < 0)
|
||||
BmpIndex2 = 0;
|
||||
Flasher.BmpArr[0] = nullptr;
|
||||
Flasher.BmpArr[1] = static_cast<gdrv_bitmap8*>(ListBitmap->Get(BmpIndex2));
|
||||
Flasher.BmpArr[1] = ListBitmap->at(BmpIndex2);
|
||||
if (FlasherActive == 0)
|
||||
{
|
||||
if (!FlasherFlag1)
|
||||
@@ -169,8 +168,8 @@ int TLight::Message(int code, float value)
|
||||
break;
|
||||
case 12:
|
||||
bmpIndex = BmpIndex2 + 1;
|
||||
if (bmpIndex > ListBitmap->Count())
|
||||
bmpIndex = ListBitmap->Count();
|
||||
if (bmpIndex > static_cast<int>(ListBitmap->size()))
|
||||
bmpIndex = ListBitmap->size();
|
||||
Message(11, static_cast<float>(bmpIndex));
|
||||
break;
|
||||
case 13:
|
||||
@@ -257,7 +256,7 @@ void TLight::Reset()
|
||||
Flasher.Sprite = RenderSprite;
|
||||
Flasher.BmpArr[0] = nullptr;
|
||||
if (ListBitmap)
|
||||
Flasher.BmpArr[1] = static_cast<gdrv_bitmap8*>(ListBitmap->Get(0));
|
||||
Flasher.BmpArr[1] = ListBitmap->at(0);
|
||||
Flasher.Unknown4 = 0;
|
||||
Flasher.Unknown3 = 0;
|
||||
MessageField = 0;
|
||||
@@ -270,7 +269,7 @@ void TLight::schedule_timeout(float time)
|
||||
if (Timer1)
|
||||
timer::kill(Timer1);
|
||||
Timer1 = 0;
|
||||
if (time > 0.0)
|
||||
if (time > 0.0f)
|
||||
Timer1 = timer::set(time, this, TimerExpired);
|
||||
}
|
||||
|
||||
|
||||
@@ -40,17 +40,16 @@ public:
|
||||
static void flasher_start(struct flasher_type* flash, int bmpIndex);
|
||||
static void flasher_callback(int timerId, void* caller);
|
||||
|
||||
flasher_type Flasher;
|
||||
int BmpIndex1;
|
||||
flasher_type Flasher{};
|
||||
int BmpIndex1{};
|
||||
int FlasherActive;
|
||||
int FlasherFlag1;
|
||||
int FlasherFlag2;
|
||||
int TurnOffAfterFlashingFg;
|
||||
int BmpIndex2;
|
||||
float FlasherDelay[2];
|
||||
int FlasherFlag1{};
|
||||
int FlasherFlag2{};
|
||||
int TurnOffAfterFlashingFg{};
|
||||
int BmpIndex2{};
|
||||
float FlasherDelay[2]{};
|
||||
int Timer1;
|
||||
int Timer2;
|
||||
int Unknown19;
|
||||
float Unknown20F;
|
||||
TLight_player_backup PlayerData[4];
|
||||
float Unknown20F{};
|
||||
TLight_player_backup PlayerData[4]{};
|
||||
};
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
|
||||
#include "control.h"
|
||||
#include "loader.h"
|
||||
#include "memory.h"
|
||||
#include "objlist_class.h"
|
||||
#include "timer.h"
|
||||
#include "TPinballTable.h"
|
||||
|
||||
@@ -18,11 +16,11 @@ TLightBargraph::TLightBargraph(TPinballTable* table, int groupIndex) : TLightGro
|
||||
float* floatArr = loader::query_float_attribute(groupIndex, 0, 904);
|
||||
if (floatArr)
|
||||
{
|
||||
int count = 2 * List->Count();
|
||||
TimerTimeArray = reinterpret_cast<float*>(memory::allocate(count * sizeof(float)));
|
||||
auto count = 2 * List.size();
|
||||
TimerTimeArray = new float[count];
|
||||
if (TimerTimeArray)
|
||||
{
|
||||
for (int i = 0; i < count; ++floatArr)
|
||||
for (auto i = 0u; i < count; ++floatArr)
|
||||
TimerTimeArray[i++] = *floatArr;
|
||||
}
|
||||
}
|
||||
@@ -31,8 +29,7 @@ TLightBargraph::TLightBargraph(TPinballTable* table, int groupIndex) : TLightGro
|
||||
|
||||
TLightBargraph::~TLightBargraph()
|
||||
{
|
||||
if (TimerTimeArray)
|
||||
memory::free(TimerTimeArray);
|
||||
delete[] TimerTimeArray;
|
||||
}
|
||||
|
||||
int TLightBargraph::Message(int code, float value)
|
||||
@@ -49,7 +46,7 @@ int TLightBargraph::Message(int code, float value)
|
||||
TimerBargraph = 0;
|
||||
}
|
||||
auto timeIndex = static_cast<int>(floor(value));
|
||||
auto maxCount = 2 * List->Count();
|
||||
auto maxCount = static_cast<int>(List.size()) * 2;
|
||||
if (timeIndex >= maxCount)
|
||||
timeIndex = maxCount - 1;
|
||||
if (timeIndex >= 0)
|
||||
@@ -57,9 +54,8 @@ int TLightBargraph::Message(int code, float value)
|
||||
TLightGroup::Message(45, static_cast<float>(timeIndex / 2));
|
||||
if (!(timeIndex & 1))
|
||||
TLightGroup::Message(46, 0.0);
|
||||
float* timeArray = TimerTimeArray;
|
||||
if (timeArray)
|
||||
TimerBargraph = timer::set(timeArray[timeIndex], this, BargraphTimerExpired);
|
||||
if (TimerTimeArray)
|
||||
TimerBargraph = timer::set(TimerTimeArray[timeIndex], this, BargraphTimerExpired);
|
||||
TimeIndex = timeIndex;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -13,7 +13,7 @@ public:
|
||||
static void BargraphTimerExpired(int timerId, void* caller);
|
||||
|
||||
float* TimerTimeArray;
|
||||
int TimerBargraph;
|
||||
int TimeIndex;
|
||||
int PlayerTimerIndexBackup[4];
|
||||
int TimerBargraph{};
|
||||
int TimeIndex{};
|
||||
int PlayerTimerIndexBackup[4]{};
|
||||
};
|
||||
|
||||
@@ -4,39 +4,33 @@
|
||||
|
||||
#include "control.h"
|
||||
#include "loader.h"
|
||||
#include "objlist_class.h"
|
||||
#include "timer.h"
|
||||
#include "TLight.h"
|
||||
#include "TPinballTable.h"
|
||||
|
||||
TLightGroup::TLightGroup(TPinballTable* table, int groupIndex) : TPinballComponent(table, groupIndex, false)
|
||||
{
|
||||
List = new objlist_class(4, 4);
|
||||
Timer = 0;
|
||||
NotifyTimer = 0;
|
||||
Reset();
|
||||
TLightGroup::Reset();
|
||||
if (groupIndex > 0)
|
||||
{
|
||||
int count;
|
||||
Timer1TimeDefault = *loader::query_float_attribute(groupIndex, 0, 903);
|
||||
__int16* groupIndArr = loader::query_iattribute(groupIndex, 1027, &count);
|
||||
int16_t* groupIndArr = loader::query_iattribute(groupIndex, 1027, &count);
|
||||
for (int index = 0; index < count; ++groupIndArr)
|
||||
{
|
||||
auto comp = table->find_component(*groupIndArr);
|
||||
auto comp = dynamic_cast<TLight*>(table->find_component(*groupIndArr));
|
||||
if (comp)
|
||||
List->Add(comp);
|
||||
List.push_back(comp);
|
||||
++index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TLightGroup::~TLightGroup()
|
||||
{
|
||||
delete List;
|
||||
}
|
||||
|
||||
int TLightGroup::Message(int code, float value)
|
||||
{
|
||||
auto const count = static_cast<int>(List.size());
|
||||
switch (code)
|
||||
{
|
||||
case 1011:
|
||||
@@ -71,8 +65,7 @@ int TLightGroup::Message(int code, float value)
|
||||
break;
|
||||
case 24:
|
||||
{
|
||||
auto count = List->Count();
|
||||
auto lastLight = static_cast<TLight*>(List->Get(count - 1));
|
||||
auto lastLight = List.at(count - 1);
|
||||
if (lastLight->FlasherActive || lastLight->FlasherFlag2 || lastLight->FlasherFlag1)
|
||||
break;
|
||||
if (MessageField2)
|
||||
@@ -85,12 +78,12 @@ int TLightGroup::Message(int code, float value)
|
||||
auto bmpIndex1 = lastLight->BmpIndex1;
|
||||
for (auto index = count - 1; index > 0; --index)
|
||||
{
|
||||
auto lightCur = static_cast<TLight*>(List->Get(index));
|
||||
auto lightPrev = static_cast<TLight*>(List->Get(index - 1));
|
||||
auto lightCur = List.at(index);
|
||||
auto lightPrev = List.at(index - 1);
|
||||
lightCur->Message(lightPrev->BmpIndex1 != 0, 0.0);
|
||||
lightCur->MessageField = lightPrev->MessageField;
|
||||
}
|
||||
auto firstLight = static_cast<TLight*>(List->Get(0));
|
||||
auto firstLight = List.at(0);
|
||||
firstLight->Message(bmpIndex1 != 0, 0.0);
|
||||
firstLight->MessageField = lightMessageField;
|
||||
reschedule_animation(value);
|
||||
@@ -98,23 +91,22 @@ int TLightGroup::Message(int code, float value)
|
||||
}
|
||||
case 25:
|
||||
{
|
||||
auto count = List->Count();
|
||||
auto lastLight = static_cast<TLight*>(List->Get(count - 1));
|
||||
auto lastLight = List.at(count - 1);
|
||||
if (lastLight->FlasherActive || lastLight->FlasherFlag2 || lastLight->FlasherFlag1)
|
||||
break;
|
||||
if (MessageField2)
|
||||
{
|
||||
TLightGroup::Message(34, 0.0);
|
||||
}
|
||||
auto firstLight = static_cast<TLight*>(List->Get(0));
|
||||
auto firstLight = List.at(0);
|
||||
AnimationFlag = 1;
|
||||
MessageField2 = code;
|
||||
auto lightMessageField = firstLight->MessageField;
|
||||
auto bmpIndex1 = firstLight->BmpIndex1;
|
||||
for (auto index = 0; index < count - 1; index++)
|
||||
{
|
||||
auto lightCur = static_cast<TLight*>(List->Get(index));
|
||||
auto lightNext = static_cast<TLight*>(List->Get(index + 1));
|
||||
auto lightCur = List.at(index);
|
||||
auto lightNext = List.at(index + 1);
|
||||
lightCur->Message(lightNext->BmpIndex1 != 0, 0.0);
|
||||
lightCur->MessageField = lightNext->MessageField;
|
||||
}
|
||||
@@ -129,16 +121,15 @@ int TLightGroup::Message(int code, float value)
|
||||
start_animation();
|
||||
MessageField2 = code;
|
||||
AnimationFlag = 0;
|
||||
auto count = List->Count();
|
||||
auto lastLight = static_cast<TLight*>(List->Get(count - 1));
|
||||
auto lastLight = List.at(count - 1);
|
||||
auto flasherFlag2 = lastLight->FlasherFlag2;
|
||||
for (auto i = count - 1; i > 0; --i)
|
||||
{
|
||||
auto lightCur = static_cast<TLight*>(List->Get(i));
|
||||
auto lightPrev = static_cast<TLight*>(List->Get(i - 1));
|
||||
auto lightCur = List.at(i);
|
||||
auto lightPrev = List.at(i - 1);
|
||||
lightCur->Message((lightPrev->FlasherFlag2 != 0) + 8, 0.0);
|
||||
}
|
||||
auto firstLight = static_cast<TLight*>(List->Get(0));
|
||||
auto firstLight = List.at(0);
|
||||
firstLight->Message((flasherFlag2 != 0) + 8, 0);
|
||||
reschedule_animation(value);
|
||||
break;
|
||||
@@ -149,16 +140,15 @@ int TLightGroup::Message(int code, float value)
|
||||
start_animation();
|
||||
MessageField2 = code;
|
||||
AnimationFlag = 0;
|
||||
auto count = List->Count();
|
||||
auto firstLight = static_cast<TLight*>(List->Get(0));
|
||||
auto firstLight = List.at(0);
|
||||
auto flasherFlag2 = firstLight->FlasherFlag2;
|
||||
for (auto i = 0; i < count - 1; i++)
|
||||
{
|
||||
auto lightCur = static_cast<TLight*>(List->Get(i));
|
||||
auto lightNext = static_cast<TLight*>(List->Get(i + 1));
|
||||
auto lightCur = List.at(i);
|
||||
auto lightNext = List.at(i + 1);
|
||||
lightCur->Message((lightNext->FlasherFlag2 != 0) + 8, 0.0);
|
||||
}
|
||||
auto lastLight = static_cast<TLight*>(List->Get(count - 1));
|
||||
auto lastLight = List.at(count - 1);
|
||||
lastLight->Message((flasherFlag2 != 0) + 8, 0);
|
||||
reschedule_animation(value);
|
||||
break;
|
||||
@@ -169,13 +159,11 @@ int TLightGroup::Message(int code, float value)
|
||||
start_animation();
|
||||
MessageField2 = code;
|
||||
AnimationFlag = 0;
|
||||
auto count = List->Count();
|
||||
for (auto i = 0; i < count - 1; i++)
|
||||
for (auto light : List)
|
||||
{
|
||||
if (rand() % 100 > 70)
|
||||
{
|
||||
auto light = static_cast<TLight*>(List->Get(i));
|
||||
auto randVal = static_cast<float>(rand()) * 0.00003051850947599719f * value * 3.0f + 0.1f;
|
||||
auto randVal = RandFloat() * value * 3.0f + 0.1f;
|
||||
light->Message(9, randVal);
|
||||
}
|
||||
}
|
||||
@@ -188,10 +176,8 @@ int TLightGroup::Message(int code, float value)
|
||||
start_animation();
|
||||
MessageField2 = code;
|
||||
AnimationFlag = 0;
|
||||
auto count = List->Count();
|
||||
for (auto i = 0; i < count - 1; i++)
|
||||
for (auto light : List)
|
||||
{
|
||||
auto light = static_cast<TLight*>(List->Get(i));
|
||||
auto randVal = static_cast<float>(rand() % 100 > 70);
|
||||
light->Message(18, randVal);
|
||||
}
|
||||
@@ -201,22 +187,18 @@ int TLightGroup::Message(int code, float value)
|
||||
case 30:
|
||||
{
|
||||
auto noBmpInd1Count = 0;
|
||||
auto countSub1 = List->Count() - 1;
|
||||
if (countSub1 < 0)
|
||||
break;
|
||||
|
||||
for (auto i = countSub1; i >= 0; i--)
|
||||
for (auto light : List)
|
||||
{
|
||||
if (!static_cast<TLight*>(List->Get(i))->BmpIndex1)
|
||||
if (!light->BmpIndex1)
|
||||
++noBmpInd1Count;
|
||||
}
|
||||
if (!noBmpInd1Count)
|
||||
break;
|
||||
|
||||
auto randModCount = rand() % noBmpInd1Count;
|
||||
for (auto i = countSub1; i >= 0; i--)
|
||||
for (auto it = List.rbegin(); it != List.rend(); ++it)
|
||||
{
|
||||
auto light = static_cast<TLight*>(List->Get(i));
|
||||
auto light = *it;
|
||||
if (!light->BmpIndex1 && randModCount-- == 0)
|
||||
{
|
||||
light->Message(1, 0.0);
|
||||
@@ -231,22 +213,18 @@ int TLightGroup::Message(int code, float value)
|
||||
case 31:
|
||||
{
|
||||
auto bmpInd1Count = 0;
|
||||
auto countSub1 = List->Count() - 1;
|
||||
if (countSub1 < 0)
|
||||
break;
|
||||
|
||||
for (auto i = countSub1; i >= 0; i--)
|
||||
for (auto light : List)
|
||||
{
|
||||
if (static_cast<TLight*>(List->Get(i))->BmpIndex1)
|
||||
if (light->BmpIndex1)
|
||||
++bmpInd1Count;
|
||||
}
|
||||
if (!bmpInd1Count)
|
||||
break;
|
||||
|
||||
auto randModCount = rand() % bmpInd1Count;
|
||||
for (auto i = countSub1; i >= 0; i--)
|
||||
for (auto it = List.rbegin(); it != List.rend(); ++it)
|
||||
{
|
||||
auto light = static_cast<TLight*>(List->Get(i));
|
||||
auto light = *it;
|
||||
if (light->BmpIndex1 && randModCount-- == 0)
|
||||
{
|
||||
light->Message(0, 0.0);
|
||||
@@ -263,7 +241,7 @@ int TLightGroup::Message(int code, float value)
|
||||
auto index = next_light_up();
|
||||
if (index < 0)
|
||||
break;
|
||||
static_cast<TLight*>(List->Get(index))->Message(1, 0.0);
|
||||
List.at(index)->Message(1, 0.0);
|
||||
if (MessageField2)
|
||||
start_animation();
|
||||
return 1;
|
||||
@@ -273,7 +251,7 @@ int TLightGroup::Message(int code, float value)
|
||||
auto index = next_light_down();
|
||||
if (index < 0)
|
||||
break;
|
||||
static_cast<TLight*>(List->Get(index))->Message(0, 0.0);
|
||||
List.at(index)->Message(0, 0.0);
|
||||
if (MessageField2)
|
||||
start_animation();
|
||||
return 1;
|
||||
@@ -292,10 +270,10 @@ int TLightGroup::Message(int code, float value)
|
||||
case 35:
|
||||
{
|
||||
auto index = static_cast<int>(floor(value));
|
||||
if (index >= List->Count() || index < 0)
|
||||
if (index >= count || index < 0)
|
||||
break;
|
||||
|
||||
auto light = static_cast<TLight*>(List->Get(index));
|
||||
auto light = List.at(index);
|
||||
light->Message(1, 0.0);
|
||||
if (MessageField2)
|
||||
start_animation();
|
||||
@@ -304,10 +282,10 @@ int TLightGroup::Message(int code, float value)
|
||||
case 36:
|
||||
{
|
||||
auto index = static_cast<int>(floor(value));
|
||||
if (index >= List->Count() || index < 0)
|
||||
if (index >= count || index < 0)
|
||||
break;
|
||||
|
||||
auto light = static_cast<TLight*>(List->Get(index));
|
||||
auto light = List.at(index);
|
||||
light->Message(0, 0.0);
|
||||
if (MessageField2)
|
||||
start_animation();
|
||||
@@ -316,16 +294,15 @@ int TLightGroup::Message(int code, float value)
|
||||
case 37:
|
||||
{
|
||||
auto bmp1Count = 0;
|
||||
auto countSub1 = List->Count() - 1;
|
||||
for (auto i = countSub1; i >= 0; i--)
|
||||
for (auto light : List)
|
||||
{
|
||||
if (static_cast<TLight*>(List->Get(i))->BmpIndex1)
|
||||
if (light->BmpIndex1)
|
||||
++bmp1Count;
|
||||
}
|
||||
return bmp1Count;
|
||||
}
|
||||
case 38:
|
||||
return List->Count();
|
||||
return count;
|
||||
case 39:
|
||||
return MessageField2;
|
||||
case 40:
|
||||
@@ -337,7 +314,7 @@ int TLightGroup::Message(int code, float value)
|
||||
break;
|
||||
if (MessageField2 || AnimationFlag)
|
||||
TLightGroup::Message(34, 0.0);
|
||||
static_cast<TLight*>(List->Get(index))->Message(15, value);
|
||||
List.at(index)->Message(15, value);
|
||||
return 1;
|
||||
}
|
||||
case 42:
|
||||
@@ -347,22 +324,21 @@ int TLightGroup::Message(int code, float value)
|
||||
break;
|
||||
if (MessageField2 || AnimationFlag)
|
||||
TLightGroup::Message(34, 0.0);
|
||||
static_cast<TLight*>(List->Get(index))->Message(16, value);
|
||||
List.at(index)->Message(16, value);
|
||||
return 1;
|
||||
}
|
||||
case 43:
|
||||
if (NotifyTimer)
|
||||
timer::kill(NotifyTimer);
|
||||
NotifyTimer = 0;
|
||||
if (value > 0.0)
|
||||
if (value > 0.0f)
|
||||
NotifyTimer = timer::set(value, this, NotifyTimerExpired);
|
||||
break;
|
||||
case 44:
|
||||
{
|
||||
auto countSub1 = List->Count() - 1;
|
||||
for (auto index = countSub1; index >= 0; index--)
|
||||
for (auto it = List.rbegin(); it != List.rend(); ++it)
|
||||
{
|
||||
auto light = static_cast<TLight*>(List->Get(index));
|
||||
auto light = *it;
|
||||
if (light->BmpIndex1)
|
||||
{
|
||||
light->Message(0, 0.0);
|
||||
@@ -376,29 +352,18 @@ int TLightGroup::Message(int code, float value)
|
||||
{
|
||||
control::handler(code, this);
|
||||
auto index = static_cast<int>(floor(value));
|
||||
if (index >= 0)
|
||||
if (index >= 0 && index < count)
|
||||
{
|
||||
auto count = List->Count();
|
||||
if (index <= count)
|
||||
// Turn off lights (index, end]
|
||||
for (auto i = count - 1; i > index; i--)
|
||||
{
|
||||
auto countSub1 = count - 1;
|
||||
if (countSub1 > index)
|
||||
{
|
||||
countSub1 = index;
|
||||
for (auto i = countSub1, k = countSub1 - index; k != 0; i--, k--)
|
||||
{
|
||||
auto light = static_cast<TLight*>(List->Get(i));
|
||||
light->Message(20, 0.0);
|
||||
}
|
||||
}
|
||||
if (countSub1 >= 0)
|
||||
{
|
||||
for (auto i = countSub1; i != 0; i--)
|
||||
{
|
||||
auto light = static_cast<TLight*>(List->Get(i));
|
||||
light->Message(19, 0.0);
|
||||
}
|
||||
}
|
||||
List.at(i)->Message(20, 0.0);
|
||||
}
|
||||
|
||||
// Turn on lights [begin, index]
|
||||
for (auto i = index; i >= 0; i--)
|
||||
{
|
||||
List.at(i)->Message(19, 0.0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -408,14 +373,14 @@ int TLightGroup::Message(int code, float value)
|
||||
auto index = next_light_down();
|
||||
if (index >= 0)
|
||||
{
|
||||
static_cast<TLight*>(List->Get(index))->Message(4, 0.0);
|
||||
List.at(index)->Message(4, 0.0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
for (auto index = List->Count() - 1; index >= 0; index--)
|
||||
for (auto it = List.rbegin(); it != List.rend(); ++it)
|
||||
{
|
||||
static_cast<TLight*>(List->Get(index))->Message(code, value);
|
||||
(*it)->Message(code, value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -447,15 +412,15 @@ void TLightGroup::reschedule_animation(float time)
|
||||
return;
|
||||
}
|
||||
|
||||
Timer1Time = time > 0.0 ? time : Timer1TimeDefault;
|
||||
Timer1Time = time > 0.0f ? time : Timer1TimeDefault;
|
||||
Timer = timer::set(Timer1Time, this, TimerExpired);
|
||||
}
|
||||
|
||||
void TLightGroup::start_animation()
|
||||
{
|
||||
for (int index = List->Count() - 1; index >= 0; --index)
|
||||
for (auto it = List.rbegin(); it != List.rend(); ++it)
|
||||
{
|
||||
auto light = static_cast<TLight*>(List->Get(index));
|
||||
auto light = *it;
|
||||
if (light->BmpIndex1)
|
||||
light->Message(9, 0.0);
|
||||
else
|
||||
@@ -465,19 +430,19 @@ void TLightGroup::start_animation()
|
||||
|
||||
int TLightGroup::next_light_up()
|
||||
{
|
||||
for (int index = 0; index < List->Count(); ++index)
|
||||
for (auto index = 0u; index < List.size(); ++index)
|
||||
{
|
||||
if (!static_cast<TLight*>(List->Get(index))->BmpIndex1)
|
||||
return index;
|
||||
if (!List[index]->BmpIndex1)
|
||||
return static_cast<int>(index);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int TLightGroup::next_light_down()
|
||||
{
|
||||
for (int index = List->Count() - 1; index >= 0; --index)
|
||||
for (auto index = static_cast<int>(List.size()) - 1; index >= 0; --index)
|
||||
{
|
||||
if (!static_cast<TLight*>(List->Get(index))->BmpIndex1)
|
||||
if (List.at(index)->BmpIndex1)
|
||||
return index;
|
||||
}
|
||||
return -1;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#pragma once
|
||||
#include "TPinballComponent.h"
|
||||
class objlist_class;
|
||||
|
||||
|
||||
class TLight;
|
||||
|
||||
struct TLightGroup_player_backup
|
||||
{
|
||||
@@ -16,7 +18,7 @@ class TLightGroup :
|
||||
{
|
||||
public:
|
||||
TLightGroup(TPinballTable* table, int groupIndex);
|
||||
~TLightGroup() override;
|
||||
~TLightGroup() override = default;
|
||||
int Message(int code, float value) override;
|
||||
virtual void Reset();
|
||||
void reschedule_animation(float time);
|
||||
@@ -27,12 +29,12 @@ public:
|
||||
static void TimerExpired(int timerId, void* caller);
|
||||
static void NotifyTimerExpired(int timerId, void* caller);
|
||||
|
||||
objlist_class* List;
|
||||
float Timer1Time;
|
||||
std::vector<TLight*> List;
|
||||
float Timer1Time{};
|
||||
float Timer1TimeDefault;
|
||||
int MessageField2;
|
||||
int AnimationFlag;
|
||||
int MessageField2{};
|
||||
int AnimationFlag{};
|
||||
int NotifyTimer;
|
||||
int Timer;
|
||||
TLightGroup_player_backup PlayerData[4];
|
||||
TLightGroup_player_backup PlayerData[4]{};
|
||||
};
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include "TBall.h"
|
||||
#include "timer.h"
|
||||
#include "TPinballTable.h"
|
||||
#include "TZmapList.h"
|
||||
|
||||
TLightRollover::TLightRollover(TPinballTable* table, int groupIndex) : TRollover(table, groupIndex, false)
|
||||
{
|
||||
@@ -58,7 +57,7 @@ void TLightRollover::Collision(TBall* ball, vector_type* nextPosition, vector_ty
|
||||
control::handler(63, this);
|
||||
RolloverFlag = RolloverFlag == 0;
|
||||
if (ListBitmap)
|
||||
render::sprite_set_bitmap(RenderSprite, static_cast<gdrv_bitmap8*>(ListBitmap->Get(0)));
|
||||
render::sprite_set_bitmap(RenderSprite, ListBitmap->at(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ class TLine :
|
||||
public TEdgeSegment
|
||||
{
|
||||
public:
|
||||
line_type Line;
|
||||
line_type Line{};
|
||||
float X0, Y0, X1, Y1;
|
||||
TLine(TCollisionComponent* collCmp, char* activeFlag, unsigned int collisionGroup, float x0, float y0, float x1, float y1);
|
||||
TLine(TCollisionComponent* collCmp, char* activeFlag, unsigned int collisionGroup, vector_type* start, vector_type* end);
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
#include "control.h"
|
||||
#include "loader.h"
|
||||
#include "objlist_class.h"
|
||||
#include "TBall.h"
|
||||
#include "TLine.h"
|
||||
#include "TPinballTable.h"
|
||||
@@ -27,7 +26,7 @@ TOneway::TOneway(TPinballTable* table, int groupIndex) : TCollisionComponent(tab
|
||||
{
|
||||
line->Offset(table->CollisionCompOffset);
|
||||
line->place_in_grid();
|
||||
EdgeList->Add(line);
|
||||
EdgeList.push_back(line);
|
||||
}
|
||||
|
||||
line = new TLine(this, &ActiveFlag, visual.CollisionGroup, &linePt1, &linePt2);
|
||||
@@ -36,7 +35,7 @@ TOneway::TOneway(TPinballTable* table, int groupIndex) : TCollisionComponent(tab
|
||||
{
|
||||
line->Offset(-table->CollisionCompOffset * 0.8f);
|
||||
Line->place_in_grid();
|
||||
EdgeList->Add(Line);
|
||||
EdgeList.push_back(Line);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -67,7 +66,7 @@ void TOneway::Collision(TBall* ball, vector_type* nextPosition, vector_type* dir
|
||||
Elasticity,
|
||||
Smoothness,
|
||||
Threshold,
|
||||
Boost) > 0.2)
|
||||
Boost) > 0.2f)
|
||||
{
|
||||
if (SoftHitSoundId)
|
||||
loader::play_sound(SoftHitSoundId);
|
||||
|
||||
@@ -14,5 +14,5 @@ public:
|
||||
int get_scoring(int index) override;
|
||||
|
||||
TLine* Line;
|
||||
int Scores[6];
|
||||
int Scores[6]{};
|
||||
};
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
#include "pch.h"
|
||||
#include "TPinballComponent.h"
|
||||
#include "loader.h"
|
||||
#include "objlist_class.h"
|
||||
#include "render.h"
|
||||
#include "TZmapList.h"
|
||||
#include "TPinballTable.h"
|
||||
|
||||
TPinballComponent::TPinballComponent(TPinballTable* table, int groupIndex, bool loadVisuals)
|
||||
@@ -20,7 +18,7 @@ TPinballComponent::TPinballComponent(TPinballTable* table, int groupIndex, bool
|
||||
GroupName = nullptr;
|
||||
Control = nullptr;
|
||||
if (table)
|
||||
table->ComponentList->Add(this);
|
||||
table->ComponentList.push_back(this);
|
||||
if (groupIndex >= 0)
|
||||
GroupName = loader::query_name(groupIndex);
|
||||
if (loadVisuals && groupIndex >= 0)
|
||||
@@ -32,32 +30,31 @@ TPinballComponent::TPinballComponent(TPinballTable* table, int groupIndex, bool
|
||||
if (visual.Bitmap)
|
||||
{
|
||||
if (!ListBitmap)
|
||||
ListBitmap = new TZmapList(visualCount, 4);
|
||||
ListBitmap = new std::vector<gdrv_bitmap8*>();
|
||||
if (ListBitmap)
|
||||
ListBitmap->Add(visual.Bitmap);
|
||||
ListBitmap->push_back(visual.Bitmap);
|
||||
}
|
||||
if (visual.ZMap)
|
||||
{
|
||||
if (!ListZMap)
|
||||
ListZMap = new TZmapList(visualCount, 4);
|
||||
ListZMap = new std::vector<zmap_header_type*>();
|
||||
if (ListZMap)
|
||||
ListZMap->Add(visual.ZMap);
|
||||
ListZMap->push_back(visual.ZMap);
|
||||
}
|
||||
}
|
||||
zmap_header_type* zMap = nullptr;
|
||||
if (ListZMap)
|
||||
zMap = static_cast<zmap_header_type*>(ListZMap->Get(0));
|
||||
|
||||
auto zMap = ListZMap ? ListZMap->at(0) : nullptr;
|
||||
if (ListBitmap)
|
||||
{
|
||||
rectangle_type bmp1Rect{}, tmpRect{};
|
||||
auto rootBmp = static_cast<gdrv_bitmap8*>(ListBitmap->Get(0));
|
||||
auto rootBmp = ListBitmap->at(0);
|
||||
bmp1Rect.XPosition = rootBmp->XPosition - table->XOffset;
|
||||
bmp1Rect.YPosition = rootBmp->YPosition - table->YOffset;
|
||||
bmp1Rect.Width = rootBmp->Width;
|
||||
bmp1Rect.Height = rootBmp->Height;
|
||||
for (int index = 1; index < ListBitmap->Count(); index++)
|
||||
for (auto index = 1u; index < ListBitmap->size(); index++)
|
||||
{
|
||||
auto bmp = static_cast<gdrv_bitmap8*>(ListBitmap->Get(index));
|
||||
auto bmp = ListBitmap->at(index);
|
||||
tmpRect.XPosition = bmp->XPosition - table->XOffset;
|
||||
tmpRect.YPosition = bmp->YPosition - table->YOffset;
|
||||
tmpRect.Width = bmp->Width;
|
||||
@@ -66,7 +63,7 @@ TPinballComponent::TPinballComponent(TPinballTable* table, int groupIndex, bool
|
||||
}
|
||||
|
||||
RenderSprite = render::create_sprite(
|
||||
visualCount > 0 ? VisualType::Sprite : VisualType::None,
|
||||
visualCount > 0 ? VisualTypes::Sprite : VisualTypes::None,
|
||||
rootBmp,
|
||||
zMap,
|
||||
rootBmp->XPosition - table->XOffset,
|
||||
@@ -80,9 +77,14 @@ TPinballComponent::TPinballComponent(TPinballTable* table, int groupIndex, bool
|
||||
|
||||
TPinballComponent::~TPinballComponent()
|
||||
{
|
||||
TPinballTable* table = PinballTable;
|
||||
if (table)
|
||||
table->ComponentList->Delete(this);
|
||||
if (PinballTable)
|
||||
{
|
||||
// ComponentList contains one reference to each component.
|
||||
auto& components = PinballTable->ComponentList;
|
||||
auto position = std::find(components.begin(), components.end(), this);
|
||||
if (position != components.end())
|
||||
components.erase(position);
|
||||
}
|
||||
|
||||
delete ListBitmap;
|
||||
delete ListZMap;
|
||||
@@ -109,13 +111,3 @@ int TPinballComponent::get_scoring(int index)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* TPinballComponent::operator new(size_t Size)
|
||||
{
|
||||
return calloc(1u, Size);
|
||||
}
|
||||
|
||||
void TPinballComponent::operator delete(void* p)
|
||||
{
|
||||
free(p); /*Original does not have this*/
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
struct zmap_header_type;
|
||||
struct gdrv_bitmap8;
|
||||
struct render_sprite_type_struct;
|
||||
struct component_control;
|
||||
class TPinballTable;
|
||||
class TZmapList;
|
||||
|
||||
enum class message_code
|
||||
{
|
||||
@@ -23,18 +24,14 @@ public:
|
||||
virtual void put_scoring(int index, int score);
|
||||
virtual int get_scoring(int index);
|
||||
|
||||
void* operator new(size_t Size);
|
||||
void operator delete(void* p);
|
||||
|
||||
__int8 UnusedBaseFlag;
|
||||
__int8 ActiveFlag;
|
||||
char UnusedBaseFlag;
|
||||
char ActiveFlag;
|
||||
int MessageField;
|
||||
char* GroupName;
|
||||
int Unknown4;
|
||||
component_control* Control;
|
||||
int GroupIndex;
|
||||
render_sprite_type_struct* RenderSprite;
|
||||
TPinballTable* PinballTable;
|
||||
TZmapList* ListBitmap;
|
||||
TZmapList* ListZMap;
|
||||
std::vector<gdrv_bitmap8*>* ListBitmap;
|
||||
std::vector<zmap_header_type*>* ListZMap;
|
||||
};
|
||||
|
||||
@@ -4,12 +4,9 @@
|
||||
|
||||
#include "control.h"
|
||||
#include "loader.h"
|
||||
#include "memory.h"
|
||||
#include "objlist_class.h"
|
||||
#include "pb.h"
|
||||
#include "pinball.h"
|
||||
#include "render.h"
|
||||
#include "Sound.h"
|
||||
#include "TBall.h"
|
||||
#include "TBlocker.h"
|
||||
#include "TBumper.h"
|
||||
@@ -48,8 +45,6 @@ TPinballTable::TPinballTable(): TPinballComponent(nullptr, -1, false)
|
||||
{
|
||||
int shortArrLength;
|
||||
|
||||
ComponentList = new objlist_class(32, 16);
|
||||
BallList = new objlist_class(3, 1);
|
||||
CurScoreStruct = nullptr;
|
||||
ScoreBallcount = nullptr;
|
||||
ScorePlayerNumber1 = nullptr;
|
||||
@@ -64,7 +59,7 @@ TPinballTable::TPinballTable(): TPinballComponent(nullptr, -1, false)
|
||||
PlayerCount = 0;
|
||||
|
||||
auto ballObj = new TBall(this);
|
||||
BallList->Add(ballObj);
|
||||
BallList.push_back(ballObj);
|
||||
if (ballObj)
|
||||
ballObj->ActiveFlag = 0;
|
||||
new TTableLayer(this);
|
||||
@@ -103,7 +98,7 @@ TPinballTable::TPinballTable(): TPinballComponent(nullptr, -1, false)
|
||||
Plunger = new TPlunger(this, groupIndex);
|
||||
break;
|
||||
case 1002:
|
||||
LightGroup->List->Add(new TLight(this, groupIndex));
|
||||
LightGroup->List.push_back(new TLight(this, groupIndex));
|
||||
break;
|
||||
case 1003:
|
||||
FlipperL = new TFlipper(this, groupIndex);
|
||||
@@ -198,63 +193,55 @@ TPinballTable::TPinballTable(): TPinballComponent(nullptr, -1, false)
|
||||
|
||||
TPinballTable::~TPinballTable()
|
||||
{
|
||||
for (int scoreIndex = 0; scoreIndex < 4; scoreIndex++)
|
||||
for (auto& PlayerScore : PlayerScores)
|
||||
{
|
||||
memory::free(PlayerScores[scoreIndex].ScoreStruct);
|
||||
delete PlayerScore.ScoreStruct;
|
||||
}
|
||||
if (ScorePlayerNumber1)
|
||||
{
|
||||
memory::free(ScorePlayerNumber1);
|
||||
delete ScorePlayerNumber1;
|
||||
ScorePlayerNumber1 = nullptr;
|
||||
}
|
||||
if (ScoreBallcount)
|
||||
{
|
||||
memory::free(ScoreBallcount);
|
||||
delete ScoreBallcount;
|
||||
ScoreBallcount = nullptr;
|
||||
}
|
||||
delete LightGroup;
|
||||
while (ComponentList->Count() > 0)
|
||||
while (!ComponentList.empty())
|
||||
{
|
||||
delete static_cast<TPinballComponent*>(ComponentList->Get(0));
|
||||
// Component destructor removes it from the list.
|
||||
delete ComponentList[0];
|
||||
}
|
||||
delete BallList;
|
||||
delete ComponentList;
|
||||
control::ClearLinks();
|
||||
}
|
||||
|
||||
TPinballComponent* TPinballTable::find_component(LPCSTR componentName)
|
||||
{
|
||||
int objCount = ComponentList->Count();
|
||||
if (objCount > 0)
|
||||
for (auto component : ComponentList)
|
||||
{
|
||||
for (int index = 0; index < objCount; ++index)
|
||||
const char* groupName = component->GroupName;
|
||||
if (groupName && !strcmp(groupName, componentName))
|
||||
{
|
||||
TPinballComponent* obj = static_cast<TPinballComponent*>(ComponentList->Get(index));
|
||||
const CHAR* groupName = obj->GroupName;
|
||||
if (groupName && !lstrcmpA(groupName, componentName))
|
||||
{
|
||||
return obj;
|
||||
}
|
||||
return component;
|
||||
}
|
||||
}
|
||||
MessageBoxA(nullptr, "Table cant find:", componentName, 0x2000u);
|
||||
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_WARNING, "Table cant find:", componentName, nullptr);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TPinballComponent* TPinballTable::find_component(int groupIndex)
|
||||
{
|
||||
char Buffer[40];
|
||||
int objCount = ComponentList->Count();
|
||||
if (objCount > 0)
|
||||
char Buffer[40]{};
|
||||
for (auto component : ComponentList)
|
||||
{
|
||||
for (int index = 0; index < objCount; ++index)
|
||||
{
|
||||
TPinballComponent* obj = static_cast<TPinballComponent*>(ComponentList->Get(index));
|
||||
if (obj->GroupIndex == groupIndex)
|
||||
return obj;
|
||||
}
|
||||
if (component->GroupIndex == groupIndex)
|
||||
return component;
|
||||
}
|
||||
_itoa_s(groupIndex, Buffer, 10);
|
||||
MessageBoxA(nullptr, "Table cant find (lh):", Buffer, 0x2000u);
|
||||
|
||||
snprintf(Buffer, sizeof Buffer, "%d", groupIndex);
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_WARNING, "Table cant find (lh):", Buffer, nullptr);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -307,9 +294,9 @@ void TPinballTable::tilt(float time)
|
||||
loader::play_sound(SoundIndex3);
|
||||
TiltTimeoutTimer = timer::set(30.0, this, tilt_timeout);
|
||||
|
||||
for (int i = 0; i < ComponentList->Count(); i++)
|
||||
for (auto component : ComponentList)
|
||||
{
|
||||
static_cast<TPinballComponent*>(ComponentList->Get(i))->Message(1011, time);
|
||||
component->Message(1011, time);
|
||||
}
|
||||
LightGroup->Message(8, 0);
|
||||
TiltLockFlag = 1;
|
||||
@@ -320,9 +307,9 @@ void TPinballTable::tilt(float time)
|
||||
|
||||
void TPinballTable::port_draw()
|
||||
{
|
||||
for (int index = ComponentList->Count() - 1; index >= 0; index--)
|
||||
for (auto component : ComponentList)
|
||||
{
|
||||
static_cast<TPinballComponent*>(ComponentList->Get(index))->port_draw();
|
||||
component->port_draw();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -362,9 +349,9 @@ int TPinballTable::Message(int code, float value)
|
||||
case 1008:
|
||||
case 1009:
|
||||
case 1010:
|
||||
for (int i = 0; i < ComponentList->Count(); i++)
|
||||
for (auto component : ComponentList)
|
||||
{
|
||||
static_cast<TPinballComponent*>(ComponentList->Get(i))->Message(code, value);
|
||||
component->Message(code, value);
|
||||
}
|
||||
break;
|
||||
case 1012:
|
||||
@@ -381,7 +368,7 @@ int TPinballTable::Message(int code, float value)
|
||||
LightGroup->Message(34, 0.0);
|
||||
LightGroup->Message(20, 0.0);
|
||||
Plunger->Message(1016, 0.0);
|
||||
if (Demo->ActiveFlag)
|
||||
if (Demo && Demo->ActiveFlag)
|
||||
rc_text = pinball::get_rc_string(30, 0);
|
||||
else
|
||||
rc_text = pinball::get_rc_string(26, 0);
|
||||
@@ -406,7 +393,7 @@ int TPinballTable::Message(int code, float value)
|
||||
{
|
||||
CheatsUsed = 0;
|
||||
Message(1024, 0.0);
|
||||
auto ball = static_cast<TBall*>(BallList->Get(0));
|
||||
auto ball = BallList[0];
|
||||
ball->Position.Y = 0.0;
|
||||
ball->Position.X = 0.0;
|
||||
ball->Position.Z = -0.8f;
|
||||
@@ -443,25 +430,20 @@ int TPinballTable::Message(int code, float value)
|
||||
}
|
||||
|
||||
BallCount = MaxBallCount;
|
||||
Sound::Idle();
|
||||
ChangeBallCount(BallCount);
|
||||
score::set(ScorePlayerNumber1, CurrentPlayer + 1);
|
||||
score::update(ScorePlayerNumber1);
|
||||
Sound::Idle();
|
||||
|
||||
for (auto scoreIndex = 4 - PlayerCount; scoreIndex > 0; scoreIndex--)
|
||||
{
|
||||
score::set(PlayerScores[scoreIndex].ScoreStruct, -1);
|
||||
}
|
||||
|
||||
Sound::Idle();
|
||||
ScoreSpecial3Flag = 0;
|
||||
ScoreSpecial2Flag = 0;
|
||||
UnknownP71 = 0;
|
||||
pinball::InfoTextBox->Clear();
|
||||
Sound::Idle();
|
||||
pinball::MissTextBox->Clear();
|
||||
Sound::Idle();
|
||||
LightGroup->Message(28, 0.2f);
|
||||
auto time = loader::play_sound(SoundIndex1);
|
||||
LightShowTimer = timer::set(time, this, LightShow_timeout);
|
||||
@@ -513,9 +495,9 @@ int TPinballTable::Message(int code, float value)
|
||||
score::set(ScorePlayerNumber1, nextPlayer + 1);
|
||||
score::update(ScorePlayerNumber1);
|
||||
|
||||
for (int i = 0; i < ComponentList->Count(); i++)
|
||||
for (auto component : ComponentList)
|
||||
{
|
||||
static_cast<TPinballComponent*>(ComponentList->Get(i))->Message(1020, static_cast<float>(nextPlayer));
|
||||
component->Message(1020, static_cast<float>(nextPlayer));
|
||||
}
|
||||
|
||||
char* textboxText = nullptr;
|
||||
@@ -564,9 +546,9 @@ int TPinballTable::Message(int code, float value)
|
||||
EndGameTimeoutTimer = timer::set(3.0, this, EndGame_timeout);
|
||||
break;
|
||||
case 1024:
|
||||
for (int i = 0; i < ComponentList->Count(); i++)
|
||||
for (auto component : ComponentList)
|
||||
{
|
||||
static_cast<TPinballComponent*>(ComponentList->Get(i))->Message(1024, 0);
|
||||
component->Message(1024, 0);
|
||||
}
|
||||
if (ReplayTimer)
|
||||
timer::kill(ReplayTimer);
|
||||
@@ -608,9 +590,9 @@ void TPinballTable::EndGame_timeout(int timerId, void* caller)
|
||||
table->EndGameTimeoutTimer = 0;
|
||||
pb::end_game();
|
||||
|
||||
for (int i = 0; i < table->ComponentList->Count(); i++)
|
||||
for (auto component : table->ComponentList)
|
||||
{
|
||||
static_cast<TPinballComponent*>(table->ComponentList->Get(i))->Message(1022, 0);
|
||||
component->Message(1022, 0);
|
||||
}
|
||||
if (table->Demo)
|
||||
table->Demo->Message(1022, 0.0);
|
||||
@@ -640,9 +622,9 @@ void TPinballTable::tilt_timeout(int timerId, void* caller)
|
||||
table->TiltTimeoutTimer = 0;
|
||||
if (table->TiltLockFlag)
|
||||
{
|
||||
for (int i = 0; i < table->BallList->Count(); i++)
|
||||
for (auto ball : table->BallList)
|
||||
{
|
||||
table->Drain->Collision(static_cast<TBall*>(table->BallList->Get(i)), &vec, &vec, 0.0, nullptr);
|
||||
table->Drain->Collision(ball, &vec, &vec, 0.0, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
|
||||
#include "TPinballComponent.h"
|
||||
|
||||
class TBall;
|
||||
struct scoreStruct;
|
||||
class TFlipper;
|
||||
class TPlunger;
|
||||
class TDrain;
|
||||
class TDemo;
|
||||
class objlist_class;
|
||||
class TLightGroup;
|
||||
|
||||
struct score_struct_super
|
||||
@@ -45,54 +45,54 @@ public:
|
||||
scoreStruct* CurScoreStruct;
|
||||
scoreStruct* ScoreBallcount;
|
||||
scoreStruct* ScorePlayerNumber1;
|
||||
int CheatsUsed;
|
||||
int SoundIndex1;
|
||||
int SoundIndex2;
|
||||
int SoundIndex3;
|
||||
int CheatsUsed{};
|
||||
int SoundIndex1{};
|
||||
int SoundIndex2{};
|
||||
int SoundIndex3{};
|
||||
int BallInSink;
|
||||
int CurScore;
|
||||
int CurScoreE9;
|
||||
int CurScore{};
|
||||
int CurScoreE9{};
|
||||
int LightShowTimer;
|
||||
int EndGameTimeoutTimer;
|
||||
int TiltTimeoutTimer;
|
||||
score_struct_super PlayerScores[4];
|
||||
score_struct_super PlayerScores[4]{};
|
||||
int PlayerCount;
|
||||
int CurrentPlayer;
|
||||
TPlunger* Plunger;
|
||||
TDrain* Drain;
|
||||
TDemo* Demo;
|
||||
int XOffset;
|
||||
int YOffset;
|
||||
int Width;
|
||||
int Height;
|
||||
objlist_class* ComponentList;
|
||||
objlist_class* BallList;
|
||||
TDemo* Demo{};
|
||||
int XOffset{};
|
||||
int YOffset{};
|
||||
int Width{};
|
||||
int Height{};
|
||||
std::vector<TPinballComponent*> ComponentList;
|
||||
std::vector<TBall*> BallList;
|
||||
TLightGroup* LightGroup;
|
||||
float GravityDirVectMult;
|
||||
float GravityAngleX;
|
||||
float GravityAnglY;
|
||||
float CollisionCompOffset;
|
||||
float PlungerPositionX;
|
||||
float PlungerPositionY;
|
||||
int ScoreMultiplier;
|
||||
int ScoreAdded;
|
||||
int ScoreSpecial1;
|
||||
int ScoreSpecial2;
|
||||
int ScoreSpecial2Flag;
|
||||
int ScoreSpecial3;
|
||||
int ScoreSpecial3Flag;
|
||||
int UnknownP71;
|
||||
int BallCount;
|
||||
float GravityDirVectMult{};
|
||||
float GravityAngleX{};
|
||||
float GravityAnglY{};
|
||||
float CollisionCompOffset{};
|
||||
float PlungerPositionX{};
|
||||
float PlungerPositionY{};
|
||||
int ScoreMultiplier{};
|
||||
int ScoreAdded{};
|
||||
int ScoreSpecial1{};
|
||||
int ScoreSpecial2{};
|
||||
int ScoreSpecial2Flag{};
|
||||
int ScoreSpecial3{};
|
||||
int ScoreSpecial3Flag{};
|
||||
int UnknownP71{};
|
||||
int BallCount{};
|
||||
int MaxBallCount;
|
||||
int ExtraBalls;
|
||||
int UnknownP75;
|
||||
int BallLockedCounter;
|
||||
int ExtraBalls{};
|
||||
int UnknownP75{};
|
||||
int BallLockedCounter{};
|
||||
int MultiballFlag;
|
||||
int UnknownP78;
|
||||
int ReplayActiveFlag;
|
||||
int UnknownP78{};
|
||||
int ReplayActiveFlag{};
|
||||
int ReplayTimer;
|
||||
int UnknownP81;
|
||||
int UnknownP82;
|
||||
int UnknownP81{};
|
||||
int UnknownP82{};
|
||||
int TiltLockFlag;
|
||||
|
||||
private:
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#include "TBall.h"
|
||||
#include "timer.h"
|
||||
#include "TPinballTable.h"
|
||||
#include "TZmapList.h"
|
||||
|
||||
TPlunger::TPlunger(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true)
|
||||
{
|
||||
@@ -27,7 +26,7 @@ TPlunger::TPlunger(TPinballTable* table, int groupIndex) : TCollisionComponent(t
|
||||
MaxPullback = 100;
|
||||
Elasticity = 0.5f;
|
||||
Smoothness = 0.5f;
|
||||
PullbackIncrement = static_cast<int>(100.0 / (ListBitmap->Count() * 8.0));
|
||||
PullbackIncrement = static_cast<int>(100.0 / (ListBitmap->size() * 8.0));
|
||||
Unknown4F = 0.025f;
|
||||
float* floatArr = loader::query_float_attribute(groupIndex, 0, 601);
|
||||
table->PlungerPositionX = floatArr[0];
|
||||
@@ -38,7 +37,7 @@ void TPlunger::Collision(TBall* ball, vector_type* nextPosition, vector_type* di
|
||||
{
|
||||
if (PinballTable->TiltLockFlag)
|
||||
Message(1017, 0.0);
|
||||
coef = static_cast<float>(rand()) * 0.00003051850947599719f * Boost * 0.1f + Boost;
|
||||
coef = RandFloat() * Boost * 0.1f + Boost; // it is intended that the passed in coef is never used!
|
||||
maths::basic_collision(ball, nextPosition, direction, Elasticity, Smoothness, Threshold, coef);
|
||||
}
|
||||
|
||||
@@ -55,31 +54,9 @@ int TPlunger::Message(int code, float value)
|
||||
PullbackTimer(0, this);
|
||||
}
|
||||
return 0;
|
||||
case 1005:
|
||||
case 1009:
|
||||
case 1010:
|
||||
{
|
||||
Threshold = 0.0;
|
||||
if (PullbackTimer_)
|
||||
timer::kill(PullbackTimer_);
|
||||
PullbackTimer_ = 0;
|
||||
if (code == 1005)
|
||||
loader::play_sound(SoundIndexP2);
|
||||
auto bmp = static_cast<gdrv_bitmap8*>(ListBitmap->Get(0));
|
||||
auto zMap = static_cast<zmap_header_type*>(ListZMap->Get(0));
|
||||
render::sprite_set(
|
||||
RenderSprite,
|
||||
bmp,
|
||||
zMap,
|
||||
bmp->XPosition - PinballTable->XOffset,
|
||||
bmp->YPosition - PinballTable->YOffset);
|
||||
|
||||
timer::set(Unknown4F, this, PlungerReleasedTimer);
|
||||
break;
|
||||
}
|
||||
case 1015:
|
||||
{
|
||||
auto ball = static_cast<TBall*>(PinballTable->ComponentList->Get(0));
|
||||
auto ball = PinballTable->BallList.at(0);
|
||||
ball->Message(1024, 0.0);
|
||||
ball->Position.X = PinballTable->PlungerPositionX;
|
||||
ball->Position.Y = PinballTable->PlungerPositionY;
|
||||
@@ -101,19 +78,26 @@ int TPlunger::Message(int code, float value)
|
||||
Boost = static_cast<float>(MaxPullback);
|
||||
timer::set(0.2f, this, PlungerReleasedTimer);
|
||||
break;
|
||||
case 1005:
|
||||
case 1009:
|
||||
case 1010:
|
||||
case 1024:
|
||||
{
|
||||
if (BallFeedTimer_)
|
||||
timer::kill(BallFeedTimer_);
|
||||
BallFeedTimer_ = 0;
|
||||
if (code == 1024)
|
||||
{
|
||||
if (BallFeedTimer_)
|
||||
timer::kill(BallFeedTimer_);
|
||||
BallFeedTimer_ = 0;
|
||||
}
|
||||
|
||||
Threshold = 0.0;
|
||||
if (PullbackTimer_)
|
||||
timer::kill(PullbackTimer_);
|
||||
PullbackTimer_ = 0;
|
||||
if (code == 1005)
|
||||
loader::play_sound(SoundIndexP2);
|
||||
auto bmp = static_cast<gdrv_bitmap8*>(ListBitmap->Get(0));
|
||||
auto zMap = static_cast<zmap_header_type*>(ListZMap->Get(0));
|
||||
auto bmp = ListBitmap->at(0);
|
||||
auto zMap = ListZMap->at(0);
|
||||
render::sprite_set(
|
||||
RenderSprite,
|
||||
bmp,
|
||||
@@ -151,10 +135,10 @@ void TPlunger::PullbackTimer(int timerId, void* caller)
|
||||
plunger->Boost = static_cast<float>(plunger->MaxPullback);
|
||||
}
|
||||
int index = static_cast<int>(floor(
|
||||
static_cast<float>(plunger->ListBitmap->Count() - 1) *
|
||||
static_cast<float>(plunger->ListBitmap->size() - 1) *
|
||||
(plunger->Boost / static_cast<float>(plunger->MaxPullback))));
|
||||
auto bmp = static_cast<gdrv_bitmap8*>(plunger->ListBitmap->Get(index));
|
||||
auto zMap = static_cast<zmap_header_type*>(plunger->ListZMap->Get(index));
|
||||
auto bmp = plunger->ListBitmap->at(index);
|
||||
auto zMap = plunger->ListZMap->at(index);
|
||||
render::sprite_set(
|
||||
plunger->RenderSprite,
|
||||
bmp,
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#include "render.h"
|
||||
#include "timer.h"
|
||||
#include "TPinballTable.h"
|
||||
#include "TZmapList.h"
|
||||
|
||||
TPopupTarget::TPopupTarget(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true)
|
||||
{
|
||||
@@ -91,7 +90,7 @@ void TPopupTarget::TimerExpired(int timerId, void* caller)
|
||||
auto target = static_cast<TPopupTarget*>(caller);
|
||||
target->Timer = 0;
|
||||
target->ActiveFlag = 1;
|
||||
render::sprite_set_bitmap(target->RenderSprite, static_cast<gdrv_bitmap8*>(target->ListBitmap->Get(0)));
|
||||
render::sprite_set_bitmap(target->RenderSprite, target->ListBitmap->at(0));
|
||||
if (timerId)
|
||||
{
|
||||
if (target->SoftHitSoundId)
|
||||
|
||||
@@ -16,6 +16,6 @@ public:
|
||||
|
||||
int Timer;
|
||||
float TimerTime;
|
||||
int Scores[3];
|
||||
int PlayerMessagefieldBackup[4];
|
||||
int Scores[3]{};
|
||||
int PlayerMessagefieldBackup[4]{};
|
||||
};
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
#include "control.h"
|
||||
#include "loader.h"
|
||||
#include "objlist_class.h"
|
||||
#include "TBall.h"
|
||||
#include "TEdgeSegment.h"
|
||||
#include "TLine.h"
|
||||
@@ -22,16 +21,8 @@ TRamp::TRamp(TPinballTable* table, int groupIndex) : TCollisionComponent(table,
|
||||
loader::query_visual(groupIndex, 0, &visual);
|
||||
CollisionGroup = visual.CollisionGroup;
|
||||
|
||||
auto floatArr1 = loader::query_float_attribute(groupIndex, 0, 701);
|
||||
if (floatArr1)
|
||||
BallFieldMult = *floatArr1;
|
||||
else
|
||||
BallFieldMult = 0.2f;
|
||||
auto floatArr2 = loader::query_float_attribute(groupIndex, 0, 1305);
|
||||
if (floatArr2)
|
||||
RampFlag1 = static_cast<int>(floor(*floatArr2));
|
||||
else
|
||||
RampFlag1 = 0;
|
||||
BallFieldMult = loader::query_float_attribute(groupIndex, 0, 701, 0.2f);
|
||||
RampFlag1 = static_cast<int>(loader::query_float_attribute(groupIndex, 0, 1305, 0));
|
||||
|
||||
auto floatArr3Plane = loader::query_float_attribute(groupIndex, 0, 1300);
|
||||
RampPlaneCount = static_cast<int>(floor(*floatArr3Plane));
|
||||
@@ -43,7 +34,7 @@ TRamp::TRamp(TPinballTable* table, int groupIndex) : TCollisionComponent(table,
|
||||
start.X = floatArr4[4];
|
||||
start.Y = floatArr4[5];
|
||||
Line1 = new TLine(this, &ActiveFlag, 1 << static_cast<int>(floor(floatArr4[0])), &start, &end);
|
||||
EdgeList->Add(Line1);
|
||||
EdgeList.push_back(Line1);
|
||||
if (Line1)
|
||||
{
|
||||
Line1->WallValue = nullptr;
|
||||
@@ -61,7 +52,7 @@ TRamp::TRamp(TPinballTable* table, int groupIndex) : TCollisionComponent(table,
|
||||
&end2,
|
||||
&start2);
|
||||
Line2 = new TLine(this, &ActiveFlag, CollisionGroup, start2, end2);
|
||||
EdgeList->Add(Line2);
|
||||
EdgeList.push_back(Line2);
|
||||
if (Line2)
|
||||
{
|
||||
Line2->WallValue = nullptr;
|
||||
@@ -79,7 +70,7 @@ TRamp::TRamp(TPinballTable* table, int groupIndex) : TCollisionComponent(table,
|
||||
&end3,
|
||||
&start3);
|
||||
Line3 = new TLine(this, &ActiveFlag, CollisionGroup, start3, end3);
|
||||
EdgeList->Add(Line3);
|
||||
EdgeList.push_back(Line3);
|
||||
if (Line3)
|
||||
{
|
||||
Line3->WallValue = nullptr;
|
||||
@@ -98,10 +89,10 @@ TRamp::TRamp(TPinballTable* table, int groupIndex) : TCollisionComponent(table,
|
||||
auto pVec2 = reinterpret_cast<vector_type*>(&plane->V2);
|
||||
auto pVec3 = reinterpret_cast<vector_type*>(&plane->V3);
|
||||
|
||||
xMin = min(min(min(plane->V3.X, plane->V1.X), plane->V2.X), xMin);
|
||||
yMin = min(min(min(plane->V3.Y, plane->V1.Y), plane->V2.Y), xMin); // Sic
|
||||
xMax = max(max(max(plane->V3.X, plane->V1.X), plane->V2.X), xMin);
|
||||
yMax = max(max(max(plane->V3.Y, plane->V1.Y), plane->V2.Y), xMin);
|
||||
xMin = std::min(std::min(std::min(plane->V3.X, plane->V1.X), plane->V2.X), xMin);
|
||||
yMin = std::min(std::min(std::min(plane->V3.Y, plane->V1.Y), plane->V2.Y), xMin); // Sic
|
||||
xMax = std::max(std::max(std::max(plane->V3.X, plane->V1.X), plane->V2.X), xMin);
|
||||
yMax = std::max(std::max(std::max(plane->V3.Y, plane->V1.Y), plane->V2.Y), xMin);
|
||||
|
||||
vector_type* pointOrder[4] = {pVec1, pVec2, pVec3, pVec1};
|
||||
for (auto pt = 0; pt < 3; pt++)
|
||||
@@ -126,7 +117,7 @@ TRamp::TRamp(TPinballTable* table, int groupIndex) : TCollisionComponent(table,
|
||||
if (collisionGroup)
|
||||
{
|
||||
auto line = new TLine(this, &ActiveFlag, collisionGroup, point1, point2);
|
||||
EdgeList->Add(line);
|
||||
EdgeList.push_back(line);
|
||||
if (line)
|
||||
{
|
||||
line->WallValue = plane;
|
||||
|
||||
@@ -17,8 +17,8 @@ public:
|
||||
int FieldEffect(TBall* ball, vector_type* vecDst) override;
|
||||
void port_draw() override;
|
||||
|
||||
int Scores[4];
|
||||
field_effect_type Field;
|
||||
int Scores[4]{};
|
||||
field_effect_type Field{};
|
||||
int CollisionGroup;
|
||||
int RampFlag1;
|
||||
int RampPlaneCount;
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#include "TEdgeSegment.h"
|
||||
#include "timer.h"
|
||||
#include "TPinballTable.h"
|
||||
#include "TZmapList.h"
|
||||
|
||||
TRollover::TRollover(TPinballTable* table, int groupIndex, bool createWall) : TCollisionComponent(
|
||||
table, groupIndex, createWall)
|
||||
@@ -20,9 +19,8 @@ TRollover::TRollover(TPinballTable* table, int groupIndex, bool createWall) : TC
|
||||
|
||||
TRollover::TRollover(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, false)
|
||||
{
|
||||
RolloverFlag = 0;
|
||||
if (ListBitmap)
|
||||
render::sprite_set_bitmap(RenderSprite, static_cast<gdrv_bitmap8*>(ListBitmap->Get(0)));
|
||||
render::sprite_set_bitmap(RenderSprite, ListBitmap->at(0));
|
||||
build_walls(groupIndex);
|
||||
}
|
||||
|
||||
@@ -34,7 +32,7 @@ int TRollover::Message(int code, float value)
|
||||
this->ActiveFlag = 1;
|
||||
this->RolloverFlag = 0;
|
||||
if (this->ListBitmap)
|
||||
render::sprite_set_bitmap(this->RenderSprite, static_cast<gdrv_bitmap8*>(this->ListBitmap->Get(0)));
|
||||
render::sprite_set_bitmap(this->RenderSprite, this->ListBitmap->at(0));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -63,7 +61,7 @@ void TRollover::Collision(TBall* ball, vector_type* nextPosition, vector_type* d
|
||||
if (ListBitmap)
|
||||
{
|
||||
if (!RolloverFlag)
|
||||
bmp = static_cast<gdrv_bitmap8*>(ListBitmap->Get(0));
|
||||
bmp = ListBitmap->at(0);
|
||||
render::sprite_set_bitmap(RenderSprite, bmp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,6 @@ public:
|
||||
|
||||
static void TimerExpired(int timerId, void* caller);
|
||||
|
||||
char RolloverFlag;
|
||||
int Scores[2];
|
||||
char RolloverFlag{};
|
||||
int Scores[2]{};
|
||||
};
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
#include "control.h"
|
||||
#include "loader.h"
|
||||
#include "objlist_class.h"
|
||||
#include "render.h"
|
||||
#include "TPinballTable.h"
|
||||
#include "TBall.h"
|
||||
@@ -34,7 +33,7 @@ int TSink::Message(int code, float value)
|
||||
switch (code)
|
||||
{
|
||||
case 56:
|
||||
if (value < 0.0)
|
||||
if (value < 0.0f)
|
||||
value = TimerTime;
|
||||
Timer = timer::set(value, this, TimerExpired);
|
||||
break;
|
||||
@@ -95,7 +94,7 @@ void TSink::Collision(TBall* ball, vector_type* nextPosition, vector_type* direc
|
||||
void TSink::TimerExpired(int timerId, void* caller)
|
||||
{
|
||||
auto sink = static_cast<TSink*>(caller);
|
||||
auto ball = static_cast<TBall*>(sink->PinballTable->BallList->Get(0));
|
||||
auto ball = sink->PinballTable->BallList.at(0);
|
||||
ball->CollisionComp = nullptr;
|
||||
ball->ActiveFlag = 1;
|
||||
ball->Position.X = sink->BallPosition.X;
|
||||
|
||||
@@ -17,13 +17,13 @@ public:
|
||||
|
||||
int Timer;
|
||||
float TimerTime;
|
||||
vector_type BallPosition;
|
||||
vector_type BallAcceleration;
|
||||
vector_type BallPosition{};
|
||||
vector_type BallAcceleration{};
|
||||
float ThrowAngleMult;
|
||||
float ThrowSpeedMult1;
|
||||
float ThrowSpeedMult2;
|
||||
int SoundIndex4;
|
||||
int SoundIndex3;
|
||||
int Scores[3];
|
||||
int PlayerMessagefieldBackup[4];
|
||||
int Scores[3]{};
|
||||
int PlayerMessagefieldBackup[4]{};
|
||||
};
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#include "render.h"
|
||||
#include "timer.h"
|
||||
#include "TPinballTable.h"
|
||||
#include "TZmapList.h"
|
||||
|
||||
TSoloTarget::TSoloTarget(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true)
|
||||
{
|
||||
@@ -41,8 +40,8 @@ int TSoloTarget::Message(int code, float value)
|
||||
if (ListBitmap)
|
||||
{
|
||||
auto index = 1 - ActiveFlag;
|
||||
auto bmp = static_cast<gdrv_bitmap8*>(ListBitmap->Get(index));
|
||||
auto zMap = static_cast<zmap_header_type*>(ListZMap->Get(index));
|
||||
auto bmp = ListBitmap->at(index);
|
||||
auto zMap = ListZMap->at(index);
|
||||
render::sprite_set(
|
||||
RenderSprite,
|
||||
bmp,
|
||||
|
||||
@@ -13,10 +13,9 @@ public:
|
||||
TEdgeSegment* edge) override;
|
||||
|
||||
static void TimerExpired(int timerId, void* caller);
|
||||
|
||||
int Unknown0;
|
||||
|
||||
int Timer;
|
||||
float TimerTime;
|
||||
int SoundIndex4;
|
||||
int Scores[1];
|
||||
int Scores[1]{};
|
||||
};
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
#include "pch.h"
|
||||
#include "TTableLayer.h"
|
||||
|
||||
|
||||
#include "fullscrn.h"
|
||||
#include "loader.h"
|
||||
#include "objlist_class.h"
|
||||
#include "pb.h"
|
||||
#include "proj.h"
|
||||
#include "render.h"
|
||||
#include "TBall.h"
|
||||
@@ -19,7 +21,8 @@ TTableLayer::TTableLayer(TPinballTable* table): TCollisionComponent(table, -1, f
|
||||
auto groupIndex = loader::query_handle("table");
|
||||
loader::query_visual(groupIndex, 0, &visual);
|
||||
|
||||
auto projCenter = loader::query_float_attribute(groupIndex, 0, 700);
|
||||
/*Full tilt: proj center first value is offset by resolution*/
|
||||
auto projCenter = loader::query_float_attribute(groupIndex, 0, 700 + fullscrn::GetResolution());
|
||||
proj::recenter(projCenter[0], projCenter[1]);
|
||||
render::set_background_zmap(visual.ZMap, 0, 0);
|
||||
|
||||
@@ -29,7 +32,7 @@ TTableLayer::TTableLayer(TPinballTable* table): TCollisionComponent(table, -1, f
|
||||
rect.YPosition = 0;
|
||||
rect.Width = bmp->Width;
|
||||
rect.Height = bmp->Height;
|
||||
render::create_sprite(VisualType::None, bmp, visual.ZMap, 0, 0, &rect);
|
||||
render::create_sprite(VisualTypes::None, bmp, visual.ZMap, 0, 0, &rect);
|
||||
|
||||
PinballTable->SoundIndex1 = visual.SoundIndex4;
|
||||
PinballTable->SoundIndex2 = visual.SoundIndex3;
|
||||
@@ -49,11 +52,12 @@ TTableLayer::TTableLayer(TPinballTable* table): TCollisionComponent(table, -1, f
|
||||
PinballTable->GravityAnglY = 1.570796f;
|
||||
}
|
||||
|
||||
auto table3 = PinballTable;
|
||||
GraityDirX = cos(table3->GravityAnglY) * sin(table3->GravityAngleX) * table3->GravityDirVectMult;
|
||||
GraityDiY = sin(table3->GravityAnglY) * sin(table3->GravityAngleX) * table3->GravityDirVectMult;
|
||||
GraityDirX = cos(PinballTable->GravityAnglY) * sin(PinballTable->GravityAngleX) * PinballTable->GravityDirVectMult;
|
||||
GraityDirY = sin(PinballTable->GravityAnglY) * sin(PinballTable->GravityAngleX) * PinballTable->GravityDirVectMult;
|
||||
auto angleMultArr = loader::query_float_attribute(groupIndex, 0, 701);
|
||||
if (angleMultArr)
|
||||
|
||||
/*Full tilt hack - GraityMult should be 0.2*/
|
||||
if (angleMultArr && !pb::FullTiltMode)
|
||||
GraityMult = *angleMultArr;
|
||||
else
|
||||
GraityMult = 0.2f;
|
||||
@@ -66,10 +70,10 @@ TTableLayer::TTableLayer(TPinballTable* table): TCollisionComponent(table, -1, f
|
||||
Boost = 15.0f;
|
||||
|
||||
auto visArrPtr = visual.FloatArr;
|
||||
Unknown1F = min(visArrPtr[0], min(visArrPtr[2], visArrPtr[4]));
|
||||
Unknown2F = min(visArrPtr[1], min(visArrPtr[3], visArrPtr[5]));
|
||||
Unknown3F = max(visArrPtr[0], max(visArrPtr[2], visArrPtr[4]));
|
||||
Unknown4F = max(visArrPtr[1], max(visArrPtr[3], visArrPtr[5]));
|
||||
Unknown1F = std::min(visArrPtr[0], std::min(visArrPtr[2], visArrPtr[4]));
|
||||
Unknown2F = std::min(visArrPtr[1], std::min(visArrPtr[3], visArrPtr[5]));
|
||||
Unknown3F = std::max(visArrPtr[0], std::max(visArrPtr[2], visArrPtr[4]));
|
||||
Unknown4F = std::max(visArrPtr[1], std::max(visArrPtr[3], visArrPtr[5]));
|
||||
auto a2 = Unknown4F - Unknown2F;
|
||||
auto a1 = Unknown3F - Unknown1F;
|
||||
edge_manager = new TEdgeManager(Unknown1F, Unknown2F, a1, a2);
|
||||
@@ -86,7 +90,7 @@ TTableLayer::TTableLayer(TPinballTable* table): TCollisionComponent(table, -1, f
|
||||
if (line)
|
||||
{
|
||||
line->place_in_grid();
|
||||
EdgeList->Add(line);
|
||||
EdgeList.push_back(line);
|
||||
}
|
||||
|
||||
visArrPtr += 2;
|
||||
@@ -107,9 +111,9 @@ TTableLayer::~TTableLayer()
|
||||
|
||||
int TTableLayer::FieldEffect(TBall* ball, vector_type* vecDst)
|
||||
{
|
||||
vecDst->X = GraityDirX - (0.5f - static_cast<float>(rand()) * 0.00003051850947599719f + ball->Acceleration.X) *
|
||||
vecDst->X = GraityDirX - (0.5f - RandFloat() + ball->Acceleration.X) *
|
||||
ball->Speed * GraityMult;
|
||||
vecDst->Y = GraityDiY - ball->Acceleration.Y * ball->Speed * GraityMult;
|
||||
vecDst->Y = GraityDirY - ball->Acceleration.Y * ball->Speed * GraityMult;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -214,47 +218,47 @@ void TTableLayer::edges_insert_circle(circle_type* circle, TEdgeSegment* edge, f
|
||||
ray.Direction.X = 1.0;
|
||||
ray.Direction.Y = 0.0;
|
||||
ray.MaxDistance = edge_manager->AdvanceX;
|
||||
if (maths::ray_intersect_circle(&ray, circle) < 1000000000.0)
|
||||
if (maths::ray_intersect_circle(&ray, circle) < 1000000000.0f)
|
||||
break;
|
||||
|
||||
ray.Direction.X = -1.0;
|
||||
ray.Origin.X = ray.Origin.X + edge_manager->AdvanceX;
|
||||
if (maths::ray_intersect_circle(&ray, circle) < 1000000000.0)
|
||||
if (maths::ray_intersect_circle(&ray, circle) < 1000000000.0f)
|
||||
break;
|
||||
|
||||
ray.Direction.X = 0.0;
|
||||
ray.Direction.Y = 1.0;
|
||||
ray.MaxDistance = edge_manager->AdvanceY;
|
||||
if (maths::ray_intersect_circle(&ray, circle) < 1000000000.0)
|
||||
if (maths::ray_intersect_circle(&ray, circle) < 1000000000.0f)
|
||||
break;
|
||||
|
||||
ray.Direction.Y = -1.0;
|
||||
ray.Origin.Y = ray.Origin.Y + edge_manager->AdvanceY;
|
||||
if (maths::ray_intersect_circle(&ray, circle) < 1000000000.0)
|
||||
if (maths::ray_intersect_circle(&ray, circle) < 1000000000.0f)
|
||||
break;
|
||||
|
||||
ray.Direction.Y = 0.0;
|
||||
ray.Direction.X = -1.0;
|
||||
ray.MaxDistance = edge_manager->AdvanceX;
|
||||
if (maths::ray_intersect_circle(&ray, circle) < 1000000000.0)
|
||||
if (maths::ray_intersect_circle(&ray, circle) < 1000000000.0f)
|
||||
break;
|
||||
|
||||
ray.Direction.X = 1.0;
|
||||
ray.Origin.X = ray.Origin.X - edge_manager->AdvanceX;
|
||||
if (maths::ray_intersect_circle(&ray, circle) < 1000000000.0)
|
||||
if (maths::ray_intersect_circle(&ray, circle) < 1000000000.0f)
|
||||
break;
|
||||
|
||||
ray.Direction.X = 0.0;
|
||||
ray.Direction.Y = -1.0;
|
||||
ray.MaxDistance = edge_manager->AdvanceY;
|
||||
if (maths::ray_intersect_circle(&ray, circle) < 1000000000.0)
|
||||
if (maths::ray_intersect_circle(&ray, circle) < 1000000000.0f)
|
||||
break;
|
||||
|
||||
ray.Direction.Y = 1.0;
|
||||
ray.Origin.Y = ray.Origin.Y - edge_manager->AdvanceY;
|
||||
if (maths::ray_intersect_circle(&ray, circle) < 1000000000.0)
|
||||
if (maths::ray_intersect_circle(&ray, circle) < 1000000000.0f)
|
||||
break;
|
||||
|
||||
|
||||
collision = false;
|
||||
}
|
||||
while (false);
|
||||
|
||||
@@ -26,10 +26,9 @@ public:
|
||||
float Unknown3F;
|
||||
float Unknown4F;
|
||||
float GraityDirX;
|
||||
float GraityDiY;
|
||||
int Unknown7;
|
||||
float GraityDirY;
|
||||
float GraityMult;
|
||||
field_effect_type Field;
|
||||
field_effect_type Field{};
|
||||
|
||||
static TEdgeManager* edge_manager;
|
||||
};
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "TTextBox.h"
|
||||
|
||||
#include "control.h"
|
||||
#include "fullscrn.h"
|
||||
#include "loader.h"
|
||||
#include "render.h"
|
||||
#include "score.h"
|
||||
@@ -22,8 +23,9 @@ TTextBox::TTextBox(TPinballTable* table, int groupIndex) : TPinballComponent(tab
|
||||
|
||||
if (groupIndex > 0)
|
||||
{
|
||||
/*Full tilt: text box dimensions index is offset by resolution*/
|
||||
int arrLength;
|
||||
auto dimensions = loader::query_iattribute(groupIndex, 1500, &arrLength);
|
||||
auto dimensions = loader::query_iattribute(groupIndex + fullscrn::GetResolution(), 1500, &arrLength);
|
||||
OffsetX = dimensions[0];
|
||||
OffsetY = dimensions[1];
|
||||
Width = dimensions[2];
|
||||
@@ -73,7 +75,7 @@ void TTextBox::Clear()
|
||||
gdrv_bitmap8* bmp = BgBmp;
|
||||
if (bmp)
|
||||
gdrv::copy_bitmap(
|
||||
&render::vscreen,
|
||||
render::vscreen,
|
||||
Width,
|
||||
Height,
|
||||
OffsetX,
|
||||
@@ -82,15 +84,7 @@ void TTextBox::Clear()
|
||||
OffsetX,
|
||||
OffsetY);
|
||||
else
|
||||
gdrv::fill_bitmap(&render::vscreen, Width, Height, OffsetX, OffsetY, 0);
|
||||
gdrv::blit(
|
||||
&render::vscreen,
|
||||
OffsetX,
|
||||
OffsetY,
|
||||
OffsetX + render::vscreen.XPosition,
|
||||
OffsetY + render::vscreen.YPosition,
|
||||
Width,
|
||||
Height);
|
||||
gdrv::fill_bitmap(render::vscreen, Width, Height, OffsetX, OffsetY, 0);
|
||||
if (Timer)
|
||||
{
|
||||
if (Timer != -1)
|
||||
@@ -106,7 +100,7 @@ void TTextBox::Clear()
|
||||
}
|
||||
}
|
||||
|
||||
void TTextBox::Display(char* text, float time)
|
||||
void TTextBox::Display(const char* text, float time)
|
||||
{
|
||||
if (!text)
|
||||
return;
|
||||
@@ -118,7 +112,7 @@ void TTextBox::Display(char* text, float time)
|
||||
{
|
||||
if (Timer && Timer != -1)
|
||||
timer::kill(Timer);
|
||||
if (time == -1.0)
|
||||
if (time == -1.0f)
|
||||
Timer = -1;
|
||||
else
|
||||
Timer = timer::set(time, this, TimerExpired);
|
||||
@@ -152,12 +146,10 @@ void TTextBox::Display(char* text, float time)
|
||||
|
||||
void TTextBox::Draw()
|
||||
{
|
||||
TTextBoxMessage* nextMessage = nullptr;
|
||||
|
||||
auto bmp = BgBmp;
|
||||
if (bmp)
|
||||
gdrv::copy_bitmap(
|
||||
&render::vscreen,
|
||||
render::vscreen,
|
||||
Width,
|
||||
Height,
|
||||
OffsetX,
|
||||
@@ -166,129 +158,105 @@ void TTextBox::Draw()
|
||||
OffsetX,
|
||||
OffsetY);
|
||||
else
|
||||
gdrv::fill_bitmap(&render::vscreen, Width, Height, OffsetX, OffsetY, 0);
|
||||
gdrv::fill_bitmap(render::vscreen, Width, Height, OffsetX, OffsetY, 0);
|
||||
|
||||
bool display = false;
|
||||
while (Message1)
|
||||
{
|
||||
auto message = Message1;
|
||||
if (message->Time == -1.0)
|
||||
if (Message1->Time == -1.0f)
|
||||
{
|
||||
nextMessage = message->NextMessage;
|
||||
if (!message->NextMessage)
|
||||
if (!Message1->NextMessage)
|
||||
{
|
||||
Timer = -1;
|
||||
LABEL_18:
|
||||
auto font = Font;
|
||||
if (!font)
|
||||
{
|
||||
gdrv::blit(
|
||||
&render::vscreen,
|
||||
OffsetX,
|
||||
OffsetY,
|
||||
OffsetX + render::vscreen.XPosition,
|
||||
OffsetY + render::vscreen.YPosition,
|
||||
Width,
|
||||
Height);
|
||||
gdrv::grtext_draw_ttext_in_box(
|
||||
Message1->Text,
|
||||
render::vscreen.XPosition + OffsetX,
|
||||
render::vscreen.YPosition + OffsetY,
|
||||
Width,
|
||||
Height,
|
||||
255);
|
||||
return;
|
||||
}
|
||||
auto text = Message1->Text;
|
||||
for (auto y = OffsetY; ; y += font->Height)
|
||||
{
|
||||
auto curChar = *text;
|
||||
if (!curChar || y + font->Height > OffsetY + Height)
|
||||
break;
|
||||
|
||||
auto totalWidth = 0;
|
||||
char* textEndSpace = nullptr;
|
||||
auto textEnd = text;
|
||||
while (true)
|
||||
{
|
||||
auto maskedChar = curChar & 0x7F;
|
||||
if (!maskedChar || maskedChar == '\n')
|
||||
break;
|
||||
auto charBmp = font->Chars[maskedChar];
|
||||
if (charBmp)
|
||||
{
|
||||
auto width = charBmp->Width + font->GapWidth + totalWidth;
|
||||
if (width > Width)
|
||||
{
|
||||
if (textEndSpace)
|
||||
textEnd = textEndSpace;
|
||||
break;
|
||||
}
|
||||
if (*textEnd == ' ')
|
||||
textEndSpace = textEnd;
|
||||
curChar = *(textEnd + 1);
|
||||
totalWidth = width;
|
||||
++textEnd;
|
||||
}
|
||||
else
|
||||
{
|
||||
curChar = *textEnd;
|
||||
}
|
||||
}
|
||||
|
||||
auto offX = OffsetX;
|
||||
while (text < textEnd)
|
||||
{
|
||||
auto charBmp = font->Chars[*text++ & 0x7F];
|
||||
if (charBmp)
|
||||
{
|
||||
auto height = charBmp->Height;
|
||||
auto width = charBmp->Width;
|
||||
if (render::background_bitmap)
|
||||
gdrv::copy_bitmap_w_transparency(&render::vscreen, width, height, offX, y, charBmp, 0,
|
||||
0);
|
||||
else
|
||||
gdrv::copy_bitmap(&render::vscreen, width, height, offX, y, charBmp, 0, 0);
|
||||
font = Font;
|
||||
offX += charBmp->Width + font->GapWidth;
|
||||
}
|
||||
}
|
||||
while ((*text & 0x7F) == ' ')
|
||||
++text;
|
||||
if ((*text & 0x7F) == '\n')
|
||||
++text;
|
||||
}
|
||||
display = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (Message1->TimeLeft() >= -2.0f)
|
||||
{
|
||||
auto timeLeft = (Message1->TimeLeft());
|
||||
if (timeLeft >= -2.0f)
|
||||
Timer = timer::set(std::max(Message1->TimeLeft(), 0.25f), this, TimerExpired);
|
||||
display = true;
|
||||
break;
|
||||
}
|
||||
|
||||
auto tmp = Message1;
|
||||
Message1 = Message1->NextMessage;
|
||||
delete tmp;
|
||||
}
|
||||
|
||||
if (display)
|
||||
{
|
||||
auto font = Font;
|
||||
if (!font)
|
||||
{
|
||||
gdrv::grtext_draw_ttext_in_box(
|
||||
Message1->Text,
|
||||
render::vscreen->XPosition + OffsetX,
|
||||
render::vscreen->YPosition + OffsetY,
|
||||
Width,
|
||||
Height,
|
||||
255);
|
||||
return;
|
||||
}
|
||||
|
||||
auto text = Message1->Text;
|
||||
for (auto y = OffsetY; ; y += font->Height)
|
||||
{
|
||||
auto curChar = *text;
|
||||
if (!curChar || y + font->Height > OffsetY + Height)
|
||||
break;
|
||||
|
||||
auto totalWidth = 0;
|
||||
char* textEndSpace = nullptr;
|
||||
auto textEnd = text;
|
||||
while (true)
|
||||
{
|
||||
int timer;
|
||||
if (timeLeft >= 0.25f)
|
||||
auto maskedChar = curChar & 0x7F;
|
||||
if (!maskedChar || maskedChar == '\n')
|
||||
break;
|
||||
auto charBmp = font->Chars[maskedChar];
|
||||
if (charBmp)
|
||||
{
|
||||
timer = timer::set(timeLeft, this, TimerExpired);
|
||||
auto width = charBmp->Width + font->GapWidth + totalWidth;
|
||||
if (width > Width)
|
||||
{
|
||||
if (textEndSpace)
|
||||
textEnd = textEndSpace;
|
||||
break;
|
||||
}
|
||||
if (*textEnd == ' ')
|
||||
textEndSpace = textEnd;
|
||||
curChar = *(textEnd + 1);
|
||||
totalWidth = width;
|
||||
++textEnd;
|
||||
}
|
||||
else
|
||||
{
|
||||
timer = timer::set(0.25, this, TimerExpired);
|
||||
curChar = *textEnd;
|
||||
}
|
||||
Timer = timer;
|
||||
goto LABEL_18;
|
||||
}
|
||||
nextMessage = message->NextMessage;
|
||||
}
|
||||
delete message;
|
||||
Message1 = nextMessage;
|
||||
}
|
||||
|
||||
gdrv::blit(
|
||||
&render::vscreen,
|
||||
OffsetX,
|
||||
OffsetY,
|
||||
OffsetX + render::vscreen.XPosition,
|
||||
OffsetY + render::vscreen.YPosition,
|
||||
Width,
|
||||
Height);
|
||||
auto offX = OffsetX;
|
||||
while (text < textEnd)
|
||||
{
|
||||
auto charBmp = font->Chars[*text++ & 0x7F];
|
||||
if (charBmp)
|
||||
{
|
||||
auto height = charBmp->Height;
|
||||
auto width = charBmp->Width;
|
||||
if (render::background_bitmap)
|
||||
gdrv::copy_bitmap_w_transparency(render::vscreen, width, height, offX, y, charBmp, 0,
|
||||
0);
|
||||
else
|
||||
gdrv::copy_bitmap(render::vscreen, width, height, offX, y, charBmp, 0, 0);
|
||||
font = Font;
|
||||
offX += charBmp->Width + font->GapWidth;
|
||||
}
|
||||
}
|
||||
while ((*text & 0x7F) == ' ')
|
||||
++text;
|
||||
if ((*text & 0x7F) == '\n')
|
||||
++text;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ public:
|
||||
~TTextBox() override;
|
||||
int Message(int code, float value) override;
|
||||
void Clear();
|
||||
void Display(char* text, float time);
|
||||
void Display(const char* text, float time);
|
||||
void Draw();
|
||||
|
||||
static void TimerExpired(int timerId, void* tb);
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
#include "pch.h"
|
||||
#include "TTextBoxMessage.h"
|
||||
#include "memory.h"
|
||||
#include "pb.h"
|
||||
|
||||
TTextBoxMessage::TTextBoxMessage(char* text, float time)
|
||||
TTextBoxMessage::TTextBoxMessage(const char* text, float time)
|
||||
{
|
||||
NextMessage = nullptr;
|
||||
Time = time;
|
||||
@@ -11,9 +10,9 @@ TTextBoxMessage::TTextBoxMessage(char* text, float time)
|
||||
if (text)
|
||||
{
|
||||
const auto textLen = strlen(text) + 1;
|
||||
Text = memory::allocate(textLen);
|
||||
Text = new char[textLen];
|
||||
if (Text)
|
||||
strcpy_s(Text, textLen, text);
|
||||
strncpy(Text, text, textLen);
|
||||
}
|
||||
else
|
||||
Text = nullptr;
|
||||
@@ -21,8 +20,7 @@ TTextBoxMessage::TTextBoxMessage(char* text, float time)
|
||||
|
||||
TTextBoxMessage::~TTextBoxMessage()
|
||||
{
|
||||
if (Text)
|
||||
memory::free(Text);
|
||||
delete[] Text;
|
||||
}
|
||||
|
||||
float TTextBoxMessage::TimeLeft() const
|
||||
|
||||
@@ -7,7 +7,7 @@ public:
|
||||
float Time;
|
||||
int EndTicks;
|
||||
|
||||
TTextBoxMessage(char* text, float time);
|
||||
TTextBoxMessage(const char* text, float time);
|
||||
~TTextBoxMessage();
|
||||
float TimeLeft() const;
|
||||
void Refresh(float time);
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include "TBall.h"
|
||||
#include "TPinballTable.h"
|
||||
|
||||
TTripwire::TTripwire(TPinballTable* table, int groupIndex) : TRollover(table, groupIndex, 1)
|
||||
TTripwire::TTripwire(TPinballTable* table, int groupIndex) : TRollover(table, groupIndex, true)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -5,15 +5,13 @@
|
||||
#include "control.h"
|
||||
#include "render.h"
|
||||
#include "timer.h"
|
||||
#include "TZmapList.h"
|
||||
|
||||
TWall::TWall(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true)
|
||||
{
|
||||
if (RenderSprite)
|
||||
render::sprite_set_bitmap(RenderSprite, nullptr);
|
||||
if (ListBitmap)
|
||||
BmpPtr = static_cast<gdrv_bitmap8*>(ListBitmap->Get(0));
|
||||
Timer = 0;
|
||||
BmpPtr = ListBitmap->at(0);
|
||||
}
|
||||
|
||||
int TWall::Message(int code, float value)
|
||||
|
||||
@@ -11,13 +11,13 @@ public:
|
||||
TWall(TPinballTable* table, int groupIndex);
|
||||
int Message(int code, float value) override;
|
||||
void Collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float coef,
|
||||
TEdgeSegment* edge) override;
|
||||
TEdgeSegment* edge) override;
|
||||
void put_scoring(int index, int score) override;
|
||||
int get_scoring(int index) override;
|
||||
int get_scoring(int index) override;
|
||||
|
||||
static void TimerExpired(int timerId, void* caller);
|
||||
|
||||
int Timer;
|
||||
gdrv_bitmap8* BmpPtr;
|
||||
int Scores[1];
|
||||
int Timer{};
|
||||
gdrv_bitmap8* BmpPtr{};
|
||||
int Scores[1]{};
|
||||
};
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
#pragma once
|
||||
#include "objlist_class.h"
|
||||
|
||||
class TZmapList : // TImageList, template?
|
||||
public objlist_class
|
||||
{
|
||||
public:
|
||||
TZmapList(int SizeInt, int growSize): objlist_class(SizeInt, growSize)
|
||||
{
|
||||
};
|
||||
|
||||
~TZmapList()
|
||||
{
|
||||
};
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,243 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
/* flag values for play params */
|
||||
#define WMIX_QUEUEWAVE 0x00
|
||||
#define WMIX_CLEARQUEUE 0x01
|
||||
#define WMIX_USELRUCHANNEL 0x02
|
||||
#define WMIX_HIPRIORITY 0x04
|
||||
#define WMIX_WAIT 0x08
|
||||
#define WMIX_CustomVolume 0x10
|
||||
|
||||
#define MAXCHANNELS 16
|
||||
#define MAXQUEUEDWAVES 100
|
||||
|
||||
struct GLOBALS;
|
||||
|
||||
struct volume_struct
|
||||
{
|
||||
unsigned __int16 L;
|
||||
unsigned __int16 R;
|
||||
};
|
||||
|
||||
|
||||
struct MIXWAVE
|
||||
{
|
||||
PCMWAVEFORMAT pcm;
|
||||
WAVEHDR wh;
|
||||
char szWaveFilename[16];
|
||||
short wMagic;
|
||||
};
|
||||
|
||||
struct MIXPLAYPARAMS
|
||||
{
|
||||
WORD wSize;
|
||||
HANDLE hMixSession;
|
||||
int iChannel;
|
||||
MIXWAVE* lpMixWave;
|
||||
HWND hWndNotify;
|
||||
DWORD dwFlags;
|
||||
WORD wLoops;
|
||||
volume_struct Volume;
|
||||
};
|
||||
|
||||
struct CHANNELNODE
|
||||
{
|
||||
CHANNELNODE* next;
|
||||
MIXPLAYPARAMS PlayParams;
|
||||
MIXWAVE* lpMixWave;
|
||||
DWORD dwNumSamples;
|
||||
DWORD dwStartPos;
|
||||
DWORD dwEndPos;
|
||||
unsigned char* lpPos;
|
||||
unsigned char* lpEnd;
|
||||
volume_struct Volume;
|
||||
};
|
||||
|
||||
struct MIXCONFIG
|
||||
{
|
||||
WORD wSize;
|
||||
DWORD dwFlags;
|
||||
WORD wChannels;
|
||||
WORD wSamplingRate;
|
||||
unsigned __int16 WaveBlockCount;
|
||||
unsigned __int16 WaveBlockLen;
|
||||
__int16 CmixPtrDefaultFlag;
|
||||
unsigned __int16 ResetMixDefaultFlag;
|
||||
unsigned __int16 GoodWavePos;
|
||||
unsigned __int16 wDeviceID;
|
||||
unsigned __int16 PauseBlocks;
|
||||
__int16 ShowDebugDialogs;
|
||||
HKEY RegistryKey;
|
||||
};
|
||||
|
||||
struct XWAVEHDR
|
||||
{
|
||||
WAVEHDR wh;
|
||||
BOOL fAvailable;
|
||||
DWORD dwWavePos;
|
||||
GLOBALS* g;
|
||||
struct XWAVEHDR* QNext;
|
||||
};
|
||||
|
||||
struct PLAYQUEUE
|
||||
{
|
||||
XWAVEHDR* first;
|
||||
XWAVEHDR* last;
|
||||
};
|
||||
|
||||
struct GLOBALS
|
||||
{
|
||||
WORD wMagic1;
|
||||
__int16 unknown0;
|
||||
HWND hWndApp;
|
||||
int unknown2;
|
||||
HWAVEOUT hWaveOut;
|
||||
int fActive;
|
||||
int SettingsDialogActiveFlag;
|
||||
unsigned int wDeviceID;
|
||||
char szDevicePName[96];
|
||||
WAVEOUTCAPSA WaveoutCaps;
|
||||
volume_struct DefaultVolume;
|
||||
volume_struct ChannelVolume[MAXCHANNELS];
|
||||
CHANNELNODE* aChannel[MAXCHANNELS];
|
||||
int iChannels;
|
||||
DWORD MRUChannel[MAXCHANNELS];
|
||||
DWORD dwMRU;
|
||||
PCMWAVEFORMAT PCM;
|
||||
DWORD dwWaveBlockLen;
|
||||
int WaveBlockCount;
|
||||
int PauseBlocks;
|
||||
XWAVEHDR** WaveBlockArray;
|
||||
DWORD dwCurrentSample;
|
||||
DWORD dwBaseTime;
|
||||
int fGoodGetPos;
|
||||
DWORD dwWaveOutPos;
|
||||
void (*CmixPtr)(unsigned __int8* lpDest, unsigned __int8** rgWaveSrc, volume_struct* volume, int iNumWaves,
|
||||
unsigned __int16 length);
|
||||
int (* pfnRemix)(DWORD, CHANNELNODE*);
|
||||
DWORD (* pfnSampleAdjust)(DWORD, DWORD);
|
||||
CHANNELNODE* pWaitList;
|
||||
__int16 wMagic2;
|
||||
__int16 unknown112;
|
||||
};
|
||||
|
||||
struct dialog_template
|
||||
{
|
||||
DLGTEMPLATE Dialog;
|
||||
WORD menu;
|
||||
WORD windowClass;
|
||||
WCHAR Header[1];
|
||||
};
|
||||
|
||||
struct dialog_item_template
|
||||
{
|
||||
DLGITEMTEMPLATE Item;
|
||||
WORD sysClass;
|
||||
WORD idClass;
|
||||
WCHAR Header[1];
|
||||
};
|
||||
|
||||
|
||||
class WaveMix
|
||||
{
|
||||
public:
|
||||
static HANDLE Init();
|
||||
static HANDLE ConfigureInit(MIXCONFIG* lpConfig);
|
||||
static int CloseSession(HANDLE hMixSession);
|
||||
static int OpenChannel(HANDLE hMixSession, int iChannel, unsigned int dwFlags);
|
||||
static int CloseChannel(HANDLE hMixSession, int iChannel, unsigned int dwFlags);
|
||||
static int FlushChannel(HANDLE hMixSession, int iChannel, unsigned int dwFlags);
|
||||
static MIXWAVE* OpenWave(HANDLE hMixSession, LPCSTR szWaveFilename, HINSTANCE hInst, unsigned int dwFlags);
|
||||
static int FreeWave(HANDLE hMixSession, MIXWAVE* lpMixWave);
|
||||
static int Activate(HANDLE hMixSession, bool fActivate);
|
||||
static void Pump();
|
||||
static int Play(MIXPLAYPARAMS* lpMixPlayParams);
|
||||
|
||||
private:
|
||||
static GLOBALS* SessionToGlobalDataPtr(HANDLE hMixSession);
|
||||
static int Startup(HMODULE hModule);
|
||||
static int SetIniFileName(HMODULE hModule);
|
||||
static void InitChannelNodes();
|
||||
static void InitVolumeTable();
|
||||
static void ShowWaveOutDevices();
|
||||
static int RemoveInvalidIniNameCharacters(char* lpString);
|
||||
static int ReadConfigSettings(MIXCONFIG* lpConfig);
|
||||
static int ReadRegistryForAppSpecificConfigs(MIXCONFIG* lpConfig);
|
||||
static int ReadRegistryInt(HKEY hKey, LPCSTR lpSubKey, int defaultValue);
|
||||
static int DefaultGoodWavePos(unsigned int uDeviceID);
|
||||
static int DefaultPauseBlocks(int waveBlocks);
|
||||
static int Configure(GLOBALS* hMixSession, HWND hWndParent, MIXCONFIG* lpConfig, int* flag1Ptr, int saveConfigFlag);
|
||||
static int GetConfig(HANDLE hMixSession, MIXCONFIG* lpConfig);
|
||||
static unsigned MyWaveOutGetPosition(HWAVEOUT hWaveOut, int fGoodGetPos);
|
||||
static void FreeChannelNode(CHANNELNODE* channel);
|
||||
static int ResetRemix(DWORD dwRemixSamplePos, CHANNELNODE* channel);
|
||||
static XWAVEHDR* RemoveFromPlayingQueue(XWAVEHDR* lpXWH);
|
||||
static void DestroyPlayQueue();
|
||||
static void SwapWaveBlocks();
|
||||
static XWAVEHDR* GetWaveBlock();
|
||||
static int MixerPlay(XWAVEHDR* lpXWH, int fWriteBlocks);
|
||||
static XWAVEHDR* AddToPlayingQueue(XWAVEHDR* lpXWH);
|
||||
static void MyWaveOutReset(HWAVEOUT hWaveOut);
|
||||
static void SetWaveOutPosition(unsigned int newPosition);
|
||||
static DWORD SubFactor(DWORD a1, DWORD a2);
|
||||
static DWORD AddFactor(DWORD a1, DWORD a2);
|
||||
static dialog_template* MakeSettingsDlgTemplate();
|
||||
static dialog_template* MakeDlgTemplate(unsigned* totalSize, unsigned style, __int16 x, __int16 y, __int16 cx,
|
||||
__int16 cy,
|
||||
const wchar_t* String);
|
||||
static dialog_template* AddDlgControl(unsigned int* totalSize, dialog_template* dlgTemplate, __int16 idClass,
|
||||
unsigned style,
|
||||
WORD id, __int16 x, __int16 y, __int16 cx, __int16 cy,
|
||||
const wchar_t* String);
|
||||
static void DestroySettingsDlgTemplate(LPCVOID pMem);
|
||||
static int Settings_OnInitDialog(HWND hWnd, int wParam, MIXCONFIG* lpMixconfig);
|
||||
static int Settings_OnCommand(HWND hWnd, int command, int lParam, int wParam);
|
||||
static int ReadRegistryToGetMachineSpecificInfSection(unsigned wDeviceId, LPSTR lpString1, int maxLength);
|
||||
static const char* GetOperatingSystemPrefix();
|
||||
static unsigned int FigureOutDMABufferSize(unsigned int waveBlockLen, PCMWAVEFORMAT* pcm);
|
||||
static int NoResetRemix(DWORD dwRemixSamplePos, CHANNELNODE* channel);
|
||||
static void SaveConfigSettings(unsigned dwFlags);
|
||||
static void ShowCurrentSettings();
|
||||
static unsigned int GetWaveDevice();
|
||||
static void FreeWaveBlocks(HWAVEOUT hwo, XWAVEHDR** waveBlocks);
|
||||
static int AllocWaveBlocks(HWAVEOUT hwo, XWAVEHDR** waveBlocks);
|
||||
static void ReleaseWaveDevice(GLOBALS* globals);
|
||||
static HPSTR WaveFormatConvert(PCMWAVEFORMAT* lpOutWF, PCMWAVEFORMAT* lpInWF, HPSTR lpInData, DWORD* dwDataSize);
|
||||
static HPSTR BitsPerSampleAlign(HPSTR lpInData, WORD nInBPS, WORD nOutBPS, DWORD* dwDataSize);
|
||||
static HPSTR ChannelAlign(HPSTR lpInData, WORD nInChannels, WORD nOutChannels, WORD nBytesPerSample,
|
||||
DWORD* dwDataSize);
|
||||
static HPSTR SamplesPerSecAlign(HPSTR lpInData, DWORD nInSamplesPerSec, DWORD nOutSamplesPerSec,
|
||||
WORD nBytesPerSample, WORD nChannels, DWORD* dwDataSize);
|
||||
static void AvgSample(HPSTR lpOutData, HPSTR lpInData, unsigned nSkip, int nBytesPerSample, int nChannels);
|
||||
static void RepSample(HPSTR lpOutData, HPSTR lpInData, unsigned nRep, int nBytesPerSample, int nChannels);
|
||||
static bool IsValidLPMIXWAVE(MIXWAVE* lpMixWave);
|
||||
static void FreePlayedBlocks();
|
||||
static int HasCurrentOutputFormat(MIXWAVE* lpMixWave);
|
||||
static CHANNELNODE* GetChannelNode();
|
||||
static void ResetWavePosIfNoChannelData();
|
||||
static void cmixit(unsigned __int8* lpDest, unsigned __int8** rgWaveSrc, volume_struct* volumeArr, int iNumWaves,
|
||||
unsigned __int16 length);
|
||||
static LRESULT __stdcall WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
|
||||
static INT_PTR __stdcall SettingsDlgProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
static int initialized_flag;
|
||||
static char FileName[276];
|
||||
static CHANNELNODE channel_nodes[MAXQUEUEDWAVES];
|
||||
static CHANNELNODE* free_channel_nodes;
|
||||
static unsigned char volume_table[11][256];
|
||||
static int debug_flag;
|
||||
static void (*cmixit_ptr)(unsigned __int8* lpDest, unsigned __int8** rgWaveSrc, volume_struct* volume,
|
||||
int iNumWaves, unsigned __int16 length);
|
||||
static HMODULE HModule;
|
||||
static GLOBALS *Globals, *GlobalsActive;
|
||||
static PCMWAVEFORMAT gpFormat;
|
||||
static int ShowDebugDialogs;
|
||||
static char string_buffer[256];
|
||||
static PLAYQUEUE play_queue;
|
||||
static CHANNELNODE* play_channel_array[MAXCHANNELS];
|
||||
static XWAVEHDR* block_array1[10];
|
||||
static XWAVEHDR* block_array2[10];
|
||||
static unsigned char* play_data[MAXCHANNELS];
|
||||
static volume_struct play_volume[MAXCHANNELS];
|
||||
static int play_counter;
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -26,7 +26,7 @@ struct component_tag : component_tag_base
|
||||
static_assert(std::is_base_of<TPinballComponent, T>::value, "T must inherit from TPinballComponent");
|
||||
T* Component;
|
||||
|
||||
component_tag(LPCSTR name, TPinballComponent* component): component_tag_base(name)
|
||||
component_tag(LPCSTR name, TPinballComponent* component): component_tag_base(name), Component(nullptr)
|
||||
{
|
||||
component_tag::SetComponent(component);
|
||||
}
|
||||
@@ -65,14 +65,16 @@ public:
|
||||
static TPinballTable* TableG;
|
||||
static component_info score_components[88];
|
||||
static component_tag_base* simple_components[142];
|
||||
static int table_unlimited_balls, waiting_deployment_flag;
|
||||
static int waiting_deployment_flag;
|
||||
static bool table_unlimited_balls;
|
||||
static int RankRcArray[9], MissionRcArray[17], mission_select_scores[17];
|
||||
static component_tag_base *wormhole_tag_array1[3], *wormhole_tag_array2[3], *wormhole_tag_array3[3];
|
||||
|
||||
static void make_links(TPinballTable* table);
|
||||
static void ClearLinks();
|
||||
static TPinballComponent* make_component_link(component_tag_base* tag);
|
||||
static void handler(int code, TPinballComponent* cmp);
|
||||
static void pbctrl_bdoor_controller(int key);
|
||||
static void pbctrl_bdoor_controller(char key);
|
||||
static void table_add_extra_ball(float count);
|
||||
static void table_set_bonus_hold();
|
||||
static void table_set_bonus();
|
||||
@@ -81,7 +83,7 @@ public:
|
||||
static void table_set_multiball();
|
||||
static void table_bump_ball_sink_lock();
|
||||
static void table_set_replay(float value);
|
||||
static int cheat_bump_rank();
|
||||
static void cheat_bump_rank();
|
||||
static bool light_on(component_tag<TLight>* tag);
|
||||
static int SpecialAddScore(int score);
|
||||
static int AddRankProgress(int rank);
|
||||
@@ -182,6 +184,5 @@ public:
|
||||
static void UnselectMissionController(int code, TPinballComponent* caller);
|
||||
static void WaitingDeploymentController(int code, TPinballComponent* caller);
|
||||
private:
|
||||
static int pbctrl_state;
|
||||
static int extraball_light_flag;
|
||||
};
|
||||
|
||||
@@ -1,50 +1,31 @@
|
||||
#include "pch.h"
|
||||
#include "fullscrn.h"
|
||||
|
||||
|
||||
#include "options.h"
|
||||
#include "pb.h"
|
||||
#include "render.h"
|
||||
#include "winmain.h"
|
||||
|
||||
|
||||
int fullscrn::screen_mode;
|
||||
HWND fullscrn::hWnd;
|
||||
tagRECT fullscrn::WindowRect1, fullscrn::WindowRect2;
|
||||
rectangle_type fullscrn::WHRect;
|
||||
int fullscrn::fullscrn_flag1;
|
||||
int fullscrn::display_changed;
|
||||
int fullscrn::ChangeDisplay, fullscrn::SmthFullScrnFlag2;
|
||||
int fullscrn::trick = 1;
|
||||
int fullscrn::MenuEnabled;
|
||||
HMENU fullscrn::MenuHandle;
|
||||
|
||||
void fullscrn::init(int width, int height, int isFullscreen, HWND winHandle, HMENU menuHandle, int changeDisplay)
|
||||
int fullscrn::resolution = 0;
|
||||
const resolution_info fullscrn::resolution_array[3] =
|
||||
{
|
||||
WHRect.XPosition = 0;
|
||||
WHRect.YPosition = 0;
|
||||
ChangeDisplay = changeDisplay;
|
||||
hWnd = winHandle;
|
||||
MenuHandle = menuHandle;
|
||||
WHRect.Width = width;
|
||||
WHRect.Height = height;
|
||||
{640, 480, 600, 416, 501},
|
||||
{800, 600, 752, 520, 502},
|
||||
{1024, 768, 960, 666, 503},
|
||||
};
|
||||
float fullscrn::ScaleX = 1;
|
||||
float fullscrn::ScaleY = 1;
|
||||
int fullscrn::OffsetX = 0;
|
||||
int fullscrn::OffsetY = 0;
|
||||
|
||||
GetWindowRect(GetDesktopWindow(), &fullscrn::WindowRect1);
|
||||
int widht2 = width + 2 * GetSystemMetrics(SM_CXBORDER);
|
||||
int height2 = height + 2 * GetSystemMetrics(SM_CYBORDER);
|
||||
int menuHeight = GetSystemMetrics(SM_CYMENU);
|
||||
int captionHeight = GetSystemMetrics(SM_CYCAPTION);
|
||||
int borderHeight = WindowRect1.bottom - WindowRect1.top - height2;
|
||||
|
||||
WindowRect2.bottom = borderHeight / 2 - 2 + height2 + 4;
|
||||
WindowRect2.right = (WindowRect1.right - WindowRect1.left - widht2) / 2 - 2 + widht2 + 4;
|
||||
WindowRect2.left = (WindowRect1.right - WindowRect1.left - widht2) / 2 - 2;
|
||||
WindowRect2.top = borderHeight / 2 - (captionHeight + menuHeight) - 2;
|
||||
MoveWindow(
|
||||
hWnd,
|
||||
(WindowRect1.right - WindowRect1.left - widht2) / 2 - 2,
|
||||
WindowRect2.top,
|
||||
widht2 + 4 + 10,
|
||||
WindowRect2.bottom - WindowRect2.top + 10,
|
||||
0);
|
||||
// Todo: WH + 10 hack: original request 640x480 window but somehow receives 650x490, even thought spyxx says it is 640x480
|
||||
fullscrn_flag1 = 0;
|
||||
void fullscrn::init()
|
||||
{
|
||||
window_size_changed();
|
||||
}
|
||||
|
||||
void fullscrn::shutdown()
|
||||
@@ -61,72 +42,27 @@ int fullscrn::set_screen_mode(int isFullscreen)
|
||||
screen_mode = isFullscreen;
|
||||
if (isFullscreen)
|
||||
{
|
||||
if (IsWindowVisible(hWnd))
|
||||
GetWindowRect(hWnd, &WindowRect2);
|
||||
enableFullscreen();
|
||||
BYTE1(fullscrn_flag1) |= 0x80u;
|
||||
InvalidateRect(hWnd, nullptr, 1);
|
||||
set_menu_mode(0);
|
||||
result = disableWindowFlagsDisDlg();
|
||||
result = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
disableFullscreen();
|
||||
BYTE1(fullscrn_flag1) |= 0x80u;
|
||||
InvalidateRect(hWnd, nullptr, 1);
|
||||
set_menu_mode(1);
|
||||
result = RedrawWindow(nullptr, nullptr, nullptr, 0x185u);
|
||||
result = 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
int fullscrn::disableWindowFlagsDisDlg()
|
||||
{
|
||||
long style = GetWindowLongA(hWnd, -16);
|
||||
return SetWindowLongA(hWnd, -16, style & 0xFF3FFFFF);
|
||||
}
|
||||
|
||||
int fullscrn::setWindowFlagsDisDlg()
|
||||
{
|
||||
int style = GetWindowLongA(hWnd, -16);
|
||||
return SetWindowLongA(hWnd, -16, style | 0xC00000);
|
||||
}
|
||||
|
||||
int fullscrn::enableFullscreen()
|
||||
{
|
||||
tagRECT Rect{};
|
||||
DEVMODEA DevMode{};
|
||||
|
||||
if (ChangeDisplay && !display_changed)
|
||||
if (!display_changed)
|
||||
{
|
||||
DevMode.dmSize = 156;
|
||||
DevMode.dmFields = 1835008;
|
||||
DevMode.dmPelsWidth = 640;
|
||||
DevMode.dmPelsHeight = 480;
|
||||
DevMode.dmBitsPerPel = 8;
|
||||
disableWindowFlagsDisDlg();
|
||||
if (trick)
|
||||
if (SDL_SetWindowFullscreen(winmain::MainWindow, SDL_WINDOW_FULLSCREEN_DESKTOP) == 0)
|
||||
{
|
||||
GetWindowRect(GetDesktopWindow(), &Rect);
|
||||
SetWindowPos(hWnd, (HWND)-1, 0, 0, Rect.right - Rect.left + 1,
|
||||
Rect.bottom - Rect.top + 1, 8u);
|
||||
}
|
||||
SmthFullScrnFlag2 = 1;
|
||||
LONG changeDispResult = ChangeDisplaySettingsA(&DevMode, 4u);
|
||||
if (changeDispResult == 1)
|
||||
{
|
||||
BYTE2(DevMode.dmFields) &= 0xFBu;
|
||||
SmthFullScrnFlag2 = 1;
|
||||
changeDispResult = ChangeDisplaySettingsA(&DevMode, 4u);
|
||||
}
|
||||
display_changed = changeDispResult == 0;
|
||||
if (changeDispResult == 0)
|
||||
display_changed = 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
GetWindowRect(GetDesktopWindow(), &Rect);
|
||||
disableWindowFlagsDisDlg();
|
||||
SetWindowPos(hWnd, (HWND)-1, 0, 0, Rect.right - Rect.left + 1, Rect.bottom - Rect.top + 1, 8u);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -134,152 +70,11 @@ int fullscrn::disableFullscreen()
|
||||
{
|
||||
if (display_changed)
|
||||
{
|
||||
display_changed = 0;
|
||||
SmthFullScrnFlag2 = 1;
|
||||
ChangeDisplaySettingsA(nullptr, 4u);
|
||||
if (trick)
|
||||
SetWindowPos(hWnd, (HWND)-1, 0, 0, 0, 0, 0x13u);
|
||||
}
|
||||
setWindowFlagsDisDlg();
|
||||
SetWindowPos(
|
||||
hWnd,
|
||||
nullptr,
|
||||
WindowRect2.left,
|
||||
WindowRect2.top,
|
||||
WindowRect2.right - WindowRect2.left,
|
||||
WindowRect2.bottom - WindowRect2.top,
|
||||
0x14u);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool fullscrn::set_menu_mode(int menuEnabled)
|
||||
{
|
||||
BOOL result;
|
||||
|
||||
MenuEnabled = menuEnabled;
|
||||
GetWindowCenter();
|
||||
if (MenuEnabled)
|
||||
{
|
||||
fullscrn_flag1 |= 2u;
|
||||
InvalidateRect(hWnd, nullptr, 1);
|
||||
result = SetMenu(hWnd, MenuHandle);
|
||||
}
|
||||
else
|
||||
{
|
||||
fullscrn_flag1 |= 1u;
|
||||
InvalidateRect(hWnd, nullptr, 1);
|
||||
result = SetMenu(hWnd, nullptr);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void fullscrn::GetWindowCenter()
|
||||
{
|
||||
int yPos;
|
||||
tagRECT Rect{};
|
||||
|
||||
if (screen_mode)
|
||||
{
|
||||
GetWindowRect(GetDesktopWindow(), &Rect);
|
||||
render::vscreen.XPosition = (Rect.right - render::vscreen.Width - Rect.left) / 2;
|
||||
yPos = (Rect.bottom - render::vscreen.Height - Rect.top) / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
render::vscreen.XPosition = 0;
|
||||
yPos = GetSystemMetrics(15);
|
||||
}
|
||||
render::vscreen.YPosition = yPos;
|
||||
if (MenuEnabled)
|
||||
render::vscreen.YPosition -= GetSystemMetrics(15);
|
||||
}
|
||||
|
||||
void fullscrn::force_redraw()
|
||||
{
|
||||
BYTE1(fullscrn_flag1) |= 0x80u;
|
||||
}
|
||||
|
||||
|
||||
void fullscrn::center_in(HWND parent, HWND child)
|
||||
{
|
||||
LONG right;
|
||||
tagRECT childRect{}, parentRect{}, desktopRect{};
|
||||
|
||||
GetWindowRect(parent, &parentRect);
|
||||
GetWindowRect(child, &childRect);
|
||||
GetWindowRect(GetDesktopWindow(), &desktopRect);
|
||||
if (display_changed)
|
||||
{
|
||||
desktopRect.bottom = 480;
|
||||
desktopRect.left = 0;
|
||||
desktopRect.top = 0;
|
||||
right = 640;
|
||||
desktopRect.right = 640;
|
||||
parentRect.left = 0;
|
||||
parentRect.top = 0;
|
||||
parentRect.right = 640;
|
||||
parentRect.bottom = 480;
|
||||
}
|
||||
else
|
||||
{
|
||||
right = desktopRect.right;
|
||||
}
|
||||
|
||||
int childHeight = childRect.bottom - childRect.top;
|
||||
int smthWidth = parentRect.left + (parentRect.right + childRect.left - childRect.right - parentRect.left) / 2;
|
||||
int smthHeight = parentRect.top + (parentRect.bottom + childRect.top - childRect.bottom - parentRect.top) / 2;
|
||||
if (childRect.right - childRect.left + smthWidth > right)
|
||||
smthWidth = right - (childRect.right - childRect.left);
|
||||
if (childHeight + smthHeight > desktopRect.bottom)
|
||||
smthHeight = desktopRect.bottom - childHeight;
|
||||
if (smthWidth < desktopRect.left)
|
||||
smthWidth = desktopRect.left;
|
||||
if (smthHeight < desktopRect.top)
|
||||
smthHeight = desktopRect.top;
|
||||
MoveWindow(child, smthWidth, smthHeight, childRect.right - childRect.left, childRect.bottom - childRect.top, 0);
|
||||
}
|
||||
|
||||
int fullscrn::displaychange()
|
||||
{
|
||||
int result = 0;
|
||||
if (SmthFullScrnFlag2)
|
||||
{
|
||||
SmthFullScrnFlag2 = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (screen_mode && display_changed)
|
||||
{
|
||||
if (SDL_SetWindowFullscreen(winmain::MainWindow, 0) == 0)
|
||||
display_changed = 0;
|
||||
screen_mode = 0;
|
||||
setWindowFlagsDisDlg();
|
||||
BYTE1(fullscrn_flag1) |= 0x80u;
|
||||
InvalidateRect(hWnd, nullptr, 1);
|
||||
set_menu_mode(1);
|
||||
SetWindowPos(
|
||||
hWnd,
|
||||
nullptr,
|
||||
WindowRect2.left,
|
||||
WindowRect2.top,
|
||||
WindowRect2.right - WindowRect2.left,
|
||||
WindowRect2.bottom - WindowRect2.top,
|
||||
0x1Cu);
|
||||
result = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetWindowPos(
|
||||
hWnd,
|
||||
nullptr,
|
||||
WindowRect2.left,
|
||||
WindowRect2.top,
|
||||
WindowRect2.right - WindowRect2.left,
|
||||
WindowRect2.bottom - WindowRect2.top,
|
||||
0x14u);
|
||||
}
|
||||
center_in(GetDesktopWindow(), hWnd);
|
||||
}
|
||||
return result;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void fullscrn::activate(int flag)
|
||||
@@ -289,74 +84,49 @@ void fullscrn::activate(int flag)
|
||||
if (!flag)
|
||||
{
|
||||
set_screen_mode(0);
|
||||
SetWindowPos(hWnd, (HWND)1, 0, 0, 0, 0, 0x13u);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fullscrn::fillRect(int right, int bottom)
|
||||
int fullscrn::GetResolution()
|
||||
{
|
||||
// Weird reg usage, should be zero
|
||||
int v2 = 0;
|
||||
int v3 = 0;
|
||||
return resolution;
|
||||
}
|
||||
|
||||
RECT rc;
|
||||
HGDIOBJ brush = CreateSolidBrush(0);
|
||||
if (brush)
|
||||
void fullscrn::SetResolution(int value)
|
||||
{
|
||||
if (!pb::FullTiltMode)
|
||||
value = 0;
|
||||
assertm(value >= 0 && value <= 2, "Resolution value out of bounds");
|
||||
resolution = value;
|
||||
}
|
||||
|
||||
int fullscrn::GetMaxResolution()
|
||||
{
|
||||
return pb::FullTiltMode ? 2 : 0;
|
||||
}
|
||||
|
||||
void fullscrn::window_size_changed()
|
||||
{
|
||||
int width, height;
|
||||
SDL_GetRendererOutputSize(winmain::Renderer, &width, &height);
|
||||
int menuHeight = options::Options.ShowMenu ? winmain::MainMenuHeight : 0;
|
||||
height -= menuHeight;
|
||||
auto res = &resolution_array[resolution];
|
||||
ScaleX = static_cast<float>(width) / res->TableWidth;
|
||||
ScaleY = static_cast<float>(height) / res->TableHeight;
|
||||
OffsetX = OffsetY = 0;
|
||||
|
||||
if (options::Options.UniformScaling)
|
||||
{
|
||||
HDC dc = winmain::_GetDC(hWnd);
|
||||
HGDIOBJ brushHandle = SelectObject(dc, brush);
|
||||
if (dc)
|
||||
{
|
||||
rc.right = right + v2 + 1;
|
||||
rc.bottom = bottom + v3 + 1;
|
||||
rc.left = v2;
|
||||
rc.top = v3;
|
||||
FillRect(dc, &rc, static_cast<HBRUSH>(brush));
|
||||
ReleaseDC(hWnd, dc);
|
||||
}
|
||||
SelectObject(dc, brushHandle);
|
||||
DeleteObject(brush);
|
||||
ScaleY = ScaleX = std::min(ScaleX, ScaleY);
|
||||
OffsetX = static_cast<int>(floor((width - res->TableWidth * ScaleX) / 2));
|
||||
OffsetY = static_cast<int>(floor((height - res->TableHeight * ScaleY) / 2));
|
||||
}
|
||||
}
|
||||
|
||||
unsigned fullscrn::convert_mouse_pos(unsigned int mouseXY)
|
||||
{
|
||||
unsigned __int16 x = mouseXY & 0xffFF - render::vscreen.XPosition;
|
||||
unsigned __int16 y = (mouseXY >> 16) - render::vscreen.YPosition;
|
||||
return x | y << 16;
|
||||
}
|
||||
|
||||
void fullscrn::getminmaxinfo(MINMAXINFO* maxMin)
|
||||
{
|
||||
maxMin->ptMaxSize.x = WindowRect2.right - WindowRect2.left;
|
||||
maxMin->ptMaxSize.y = WindowRect2.bottom - WindowRect2.top;
|
||||
maxMin->ptMaxPosition.x = WindowRect2.left;
|
||||
maxMin->ptMaxPosition.y = WindowRect2.top;
|
||||
}
|
||||
|
||||
void fullscrn::paint()
|
||||
{
|
||||
int menuHeight;
|
||||
if (screen_mode)
|
||||
render::DestinationRect = SDL_Rect
|
||||
{
|
||||
if ((fullscrn_flag1 & 0x8000) == 0 && fullscrn_flag1)
|
||||
{
|
||||
if (fullscrn_flag1 & 1)
|
||||
{
|
||||
menuHeight = GetSystemMetrics(SM_CYMENU);
|
||||
fillRect(WindowRect1.right - 1, menuHeight);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (MenuEnabled)
|
||||
menuHeight = GetSystemMetrics(SM_CYMENU);
|
||||
else
|
||||
menuHeight = 0;
|
||||
fillRect(WindowRect1.right, menuHeight + WindowRect1.bottom);
|
||||
}
|
||||
}
|
||||
render::paint();
|
||||
fullscrn_flag1 = 0;
|
||||
OffsetX, OffsetY + menuHeight,
|
||||
width - OffsetX * 2, height - OffsetY * 2
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,42 +1,36 @@
|
||||
#pragma once
|
||||
#include "maths.h"
|
||||
|
||||
#define BYTEn(x, n) (*((unsigned char*)&(x)+n))
|
||||
#define BYTE1(x) BYTEn(x, 1) // byte 1 (counting from 0)
|
||||
#define BYTE2(x) BYTEn(x, 2)
|
||||
struct resolution_info
|
||||
{
|
||||
int16_t ScreenWidth;
|
||||
int16_t ScreenHeight;
|
||||
int16_t TableWidth;
|
||||
int16_t TableHeight;
|
||||
int16_t ResolutionMenuId;
|
||||
};
|
||||
|
||||
class fullscrn
|
||||
{
|
||||
public:
|
||||
|
||||
static int screen_mode;
|
||||
static HWND hWnd;
|
||||
static tagRECT WindowRect1, WindowRect2;
|
||||
static rectangle_type WHRect;
|
||||
static int fullscrn_flag1;
|
||||
static int display_changed;
|
||||
static int ChangeDisplay, SmthFullScrnFlag2;
|
||||
static int trick;
|
||||
static const resolution_info resolution_array[3];
|
||||
static float ScaleX;
|
||||
static float ScaleY;
|
||||
static int OffsetX;
|
||||
static int OffsetY;
|
||||
|
||||
static void init(int width, int height, int isFullscreen, HWND winHandle, HMENU menuHandle, int changeDisplay);
|
||||
static void init();
|
||||
static void shutdown();
|
||||
static int set_screen_mode(int isFullscreen);
|
||||
static void force_redraw();
|
||||
static void center_in(HWND parent, HWND child);
|
||||
static int displaychange();
|
||||
static void activate(int flag);
|
||||
static unsigned convert_mouse_pos(unsigned int mouseXY);
|
||||
static void getminmaxinfo(MINMAXINFO* maxMin);
|
||||
static void paint();
|
||||
static bool set_menu_mode(int menuEnabled);
|
||||
static int GetResolution();
|
||||
static void SetResolution(int value);
|
||||
static int GetMaxResolution();
|
||||
static void window_size_changed();
|
||||
private :
|
||||
static int MenuEnabled;
|
||||
static HMENU MenuHandle;
|
||||
static int resolution;
|
||||
|
||||
static void GetWindowCenter();
|
||||
static int disableWindowFlagsDisDlg();
|
||||
static int setWindowFlagsDisDlg();
|
||||
static int enableFullscreen();
|
||||
static int disableFullscreen();
|
||||
static void fillRect(int right, int bottom);
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,73 +1,74 @@
|
||||
#pragma once
|
||||
|
||||
enum class BitmapType : char
|
||||
enum class BitmapTypes : uint8_t
|
||||
{
|
||||
None = 0,
|
||||
RawBitmap = 1,
|
||||
DibBitmap = 2,
|
||||
Spliced = 3,
|
||||
};
|
||||
|
||||
|
||||
struct Rgba
|
||||
{
|
||||
uint8_t Blue;
|
||||
uint8_t Green;
|
||||
uint8_t Red;
|
||||
uint8_t Alpha;
|
||||
};
|
||||
|
||||
union ColorRgba
|
||||
{
|
||||
ColorRgba() = default;
|
||||
|
||||
explicit ColorRgba(uint32_t color)
|
||||
: Color(color)
|
||||
{
|
||||
}
|
||||
|
||||
explicit ColorRgba(Rgba rgba)
|
||||
: rgba(rgba)
|
||||
{
|
||||
}
|
||||
|
||||
uint32_t Color;
|
||||
Rgba rgba;
|
||||
};
|
||||
|
||||
static_assert(sizeof(ColorRgba) == 4, "Wrong size of RGBA color");
|
||||
|
||||
struct gdrv_bitmap8
|
||||
{
|
||||
BITMAPINFO* Dib;
|
||||
char* BmpBufPtr2;
|
||||
char* BmpBufPtr1;
|
||||
gdrv_bitmap8(int width, int height, bool indexed);
|
||||
gdrv_bitmap8(const struct dat8BitBmpHeader& header);
|
||||
~gdrv_bitmap8();
|
||||
void ScaleIndexed(float scaleX, float scaleY);
|
||||
ColorRgba* BmpBufPtr1;
|
||||
char* IndexedBmpPtr;
|
||||
int Width;
|
||||
int Height;
|
||||
int Stride;
|
||||
BitmapType BitmapType;
|
||||
int Color6;
|
||||
int IndexedStride;
|
||||
BitmapTypes BitmapType;
|
||||
int XPosition;
|
||||
int YPosition;
|
||||
};
|
||||
|
||||
struct LOGPALETTEx256
|
||||
{
|
||||
WORD palVersion;
|
||||
WORD palNumEntries;
|
||||
PALETTEENTRY palPalEntry[256];
|
||||
|
||||
LOGPALETTEx256() : palVersion(0x300), palNumEntries(256), palPalEntry{}
|
||||
{
|
||||
}
|
||||
unsigned Resolution;
|
||||
SDL_Texture* Texture;
|
||||
};
|
||||
|
||||
|
||||
class gdrv
|
||||
{
|
||||
public:
|
||||
static HPALETTE palette_handle;
|
||||
static LOGPALETTEx256 current_palette;
|
||||
static int sequence_handle;
|
||||
static HDC sequence_hdc;
|
||||
static int use_wing;
|
||||
|
||||
static int init(HINSTANCE hInst, HWND hWnd);
|
||||
static int uninit();
|
||||
static void get_focus();
|
||||
static BITMAPINFO* DibCreate(__int16 bpp, int width, int height);
|
||||
static void DibSetUsage(BITMAPINFO* dib, HPALETTE hpal, int someFlag);
|
||||
static int create_bitmap_dib(gdrv_bitmap8* bmp, int width, int height);
|
||||
static int create_bitmap(gdrv_bitmap8* bmp, int width, int height);
|
||||
static int create_raw_bitmap(gdrv_bitmap8* bmp, int width, int height, int flag);
|
||||
static int destroy_bitmap(gdrv_bitmap8* bmp);
|
||||
static int display_palette(PALETTEENTRY* plt);
|
||||
static UINT start_blit_sequence();
|
||||
static void blit_sequence(gdrv_bitmap8* bmp, int xSrc, int ySrcOff, int xDest, int yDest, int DestWidth,
|
||||
int DestHeight);
|
||||
static void end_blit_sequence();
|
||||
static void blit(gdrv_bitmap8* bmp, int xSrc, int ySrcOff, int xDest, int yDest, int DestWidth, int DestHeight);
|
||||
static void blat(gdrv_bitmap8* bmp, int xDest, int yDest);
|
||||
static void fill_bitmap(gdrv_bitmap8* bmp, int width, int height, int xOff, int yOff, char fillChar);
|
||||
static int display_palette(ColorRgba* plt);
|
||||
static void fill_bitmap(gdrv_bitmap8* bmp, int width, int height, int xOff, int yOff, uint8_t fillChar);
|
||||
static void copy_bitmap(gdrv_bitmap8* dstBmp, int width, int height, int xOff, int yOff, gdrv_bitmap8* srcBmp,
|
||||
int srcXOff, int srcYOff);
|
||||
static void copy_bitmap_w_transparency(gdrv_bitmap8* dstBmp, int width, int height, int xOff, int yOff,
|
||||
gdrv_bitmap8* srcBmp, int srcXOff, int srcYOff);
|
||||
static void grtext_draw_ttext_in_box(LPCSTR text, int xOff, int yOff, int width, int height, int a6);
|
||||
static void ApplyPalette(gdrv_bitmap8& bmp);
|
||||
static void CreatePreview(gdrv_bitmap8& bmp);
|
||||
private:
|
||||
static HWND hwnd;
|
||||
static HINSTANCE hinst;
|
||||
static int grtext_blue;
|
||||
static int grtext_green;
|
||||
static int grtext_red;
|
||||
static ColorRgba current_palette[256];
|
||||
};
|
||||
|
||||
@@ -1,115 +1,73 @@
|
||||
#include "pch.h"
|
||||
#include "high_score.h"
|
||||
|
||||
#include "fullscrn.h"
|
||||
#include "memory.h"
|
||||
#include "options.h"
|
||||
#include "resource.h"
|
||||
#include "winmain.h"
|
||||
#include "pinball.h"
|
||||
#include "score.h"
|
||||
|
||||
int high_score::dlg_enter_name;
|
||||
int high_score::dlg_score;
|
||||
int high_score::position;
|
||||
LPCSTR high_score::default_name;
|
||||
int high_score::dlg_position;
|
||||
char high_score::default_name[32]{};
|
||||
high_score_struct* high_score::dlg_hst;
|
||||
bool high_score::ShowDialog = false;
|
||||
|
||||
winhelp_entry high_score::help[21]
|
||||
{
|
||||
winhelp_entry{0x70, 0x3E9},
|
||||
winhelp_entry{0x191, 0x3EB},
|
||||
winhelp_entry{0x1F5, 0x3EB},
|
||||
winhelp_entry{0x259, 0x3EB},
|
||||
winhelp_entry{0x192, 0x3EB},
|
||||
winhelp_entry{0x193, 0x3EB},
|
||||
winhelp_entry{0x194, 0x3EB},
|
||||
winhelp_entry{0x195, 0x3EB},
|
||||
winhelp_entry{0x1F6, 0x3EB},
|
||||
winhelp_entry{0x1F7, 0x3EB},
|
||||
winhelp_entry{0x1F8, 0x3EB},
|
||||
winhelp_entry{0x1F9, 0x3EB},
|
||||
winhelp_entry{0x2BD, 0x3EB},
|
||||
winhelp_entry{0x2BE, 0x3EB},
|
||||
winhelp_entry{0x2BF, 0x3EB},
|
||||
winhelp_entry{0x2C0, 0x3EB},
|
||||
winhelp_entry{0x2C1, 0x3EB},
|
||||
winhelp_entry{0x2C2, 0x3EB},
|
||||
winhelp_entry{0x2C3, 0x3EB},
|
||||
winhelp_entry{0x2C4, 0x3EB},
|
||||
winhelp_entry{0, 0},
|
||||
};
|
||||
|
||||
int high_score::read(high_score_struct* table, int* ptrToSmth)
|
||||
int high_score::read(high_score_struct* table)
|
||||
{
|
||||
char Buffer[20];
|
||||
|
||||
int scoreSum = 0;
|
||||
int checkSum = 0;
|
||||
clear_table(table);
|
||||
char* buf1 = memory::allocate(300u);
|
||||
if (!buf1)
|
||||
return 1;
|
||||
char* buf2 = memory::allocate(300u);
|
||||
int position = 0;
|
||||
high_score_struct* tablePtr = table;
|
||||
const CHAR* optPath = pinball::get_rc_string(166, 0);
|
||||
do
|
||||
for (auto position = 0; position < 5; ++position)
|
||||
{
|
||||
_itoa_s(position, Buffer, 10);
|
||||
lstrcatA(Buffer, ".Name");
|
||||
options::get_string(optPath, Buffer, buf1, pinball::WindowName, 32);
|
||||
buf1[32] = 0;
|
||||
lstrcpyA(tablePtr->Name, buf1);
|
||||
_itoa_s(position, Buffer, 10);
|
||||
lstrcatA(Buffer, ".Score");
|
||||
options::get_string(optPath, Buffer, buf1, pinball::WindowName, 300);
|
||||
tablePtr->Score = atol(buf1);
|
||||
for (int i = lstrlenA(tablePtr->Name); --i >= 0; scoreSum += tablePtr->Name[i])
|
||||
auto tablePtr = &table[position];
|
||||
|
||||
snprintf(Buffer, sizeof Buffer, "%d", position);
|
||||
strcat(Buffer, ".Name");
|
||||
auto name = options::get_string(Buffer, "");
|
||||
strncpy(tablePtr->Name, name.c_str(), sizeof tablePtr->Name);
|
||||
|
||||
snprintf(Buffer, sizeof Buffer, "%d", position);
|
||||
strcat(Buffer, ".Score");
|
||||
tablePtr->Score = options::get_int(Buffer, tablePtr->Score);
|
||||
|
||||
for (int i = static_cast<int>(strlen(tablePtr->Name)); --i >= 0; checkSum += tablePtr->Name[i])
|
||||
{
|
||||
}
|
||||
scoreSum += tablePtr->Score;
|
||||
++position;
|
||||
++tablePtr;
|
||||
checkSum += tablePtr->Score;
|
||||
}
|
||||
while (position < 5);
|
||||
scramble_number_string(scoreSum, buf1);
|
||||
options::get_string(optPath, "Verification", buf2, pinball::WindowName, 300);
|
||||
if (lstrcmpA(buf1, buf2))
|
||||
|
||||
auto verification = options::get_int("Verification", 7);
|
||||
if (checkSum != verification)
|
||||
clear_table(table);
|
||||
memory::free(buf1);
|
||||
memory::free(buf2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int high_score::write(high_score_struct* table, int* ptrToSmth)
|
||||
int high_score::write(high_score_struct* table)
|
||||
{
|
||||
char Buffer[20];
|
||||
|
||||
high_score_struct* tablePtr = table;
|
||||
int scoreSum = 0;
|
||||
CHAR* buf = memory::allocate(300u);
|
||||
if (!buf)
|
||||
return 1;
|
||||
int position = 0;
|
||||
const CHAR* optPath = pinball::get_rc_string(166, 0);
|
||||
do
|
||||
int checkSum = 0;
|
||||
for (auto position = 0; position < 5; ++position)
|
||||
{
|
||||
_itoa_s(position, Buffer, 10);
|
||||
lstrcatA(Buffer, ".Name");
|
||||
options::set_string(optPath, Buffer, tablePtr->Name);
|
||||
_itoa_s(position, Buffer, 10);
|
||||
lstrcatA(Buffer, ".Score");
|
||||
_ltoa_s(tablePtr->Score, buf, 300, 10);
|
||||
options::set_string(optPath, Buffer, buf);
|
||||
for (int i = lstrlenA(tablePtr->Name); --i >= 0; scoreSum += tablePtr->Name[i])
|
||||
auto tablePtr = &table[position];
|
||||
|
||||
snprintf(Buffer, sizeof Buffer, "%d", position);
|
||||
strcat(Buffer, ".Name");
|
||||
options::set_string(Buffer, tablePtr->Name);
|
||||
|
||||
snprintf(Buffer, sizeof Buffer, "%d", position);
|
||||
strcat(Buffer, ".Score");
|
||||
options::set_int(Buffer, tablePtr->Score);
|
||||
|
||||
for (int i = static_cast<int>(strlen(tablePtr->Name)); --i >= 0; checkSum += tablePtr->Name[i])
|
||||
{
|
||||
}
|
||||
scoreSum += tablePtr->Score;
|
||||
++position;
|
||||
++tablePtr;
|
||||
checkSum += tablePtr->Score;
|
||||
}
|
||||
while (position < 5);
|
||||
scramble_number_string(scoreSum, buf);
|
||||
options::set_string(optPath, "Verification", buf);
|
||||
memory::free(buf);
|
||||
|
||||
options::set_int("Verification", checkSum);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -154,153 +112,120 @@ int high_score::place_new_score_into(high_score_struct* table, int score, LPSTR
|
||||
}
|
||||
high_score_struct* posTable = &table[position];
|
||||
posTable->Score = score;
|
||||
if (lstrlenA(scoreStr) >= 31)
|
||||
if (strlen(scoreStr) >= 31)
|
||||
scoreStr[31] = 0;
|
||||
lstrcpyA(posTable->Name, scoreStr);
|
||||
strncpy(posTable->Name, scoreStr, sizeof posTable->Name);
|
||||
posTable->Name[31] = 0;
|
||||
}
|
||||
return position;
|
||||
}
|
||||
|
||||
void high_score::scramble_number_string(int Value, char* Buffer)
|
||||
{
|
||||
_ltoa_s(Value, Buffer, 300, 10);
|
||||
}
|
||||
|
||||
void high_score::show_high_score_dialog(high_score_struct* table)
|
||||
{
|
||||
dlg_enter_name = 0;
|
||||
dlg_score = 0;
|
||||
dlg_hst = table;
|
||||
DialogBoxParamA(winmain::hinst, "dlg_highscores", winmain::hwnd_frame, HighScore, 0);
|
||||
ShowDialog = true;
|
||||
}
|
||||
|
||||
void high_score::show_and_set_high_score_dialog(high_score_struct* table, int score, int pos, LPCSTR defaultName)
|
||||
{
|
||||
position = pos;
|
||||
dlg_position = pos;
|
||||
dlg_score = score;
|
||||
dlg_hst = table;
|
||||
dlg_enter_name = 1;
|
||||
default_name = defaultName;
|
||||
while (DialogBoxParamA(winmain::hinst, "dlg_highscores", winmain::hwnd_frame, HighScore, 0))
|
||||
{
|
||||
}
|
||||
strncpy(default_name, defaultName, sizeof default_name - 1);
|
||||
ShowDialog = true;
|
||||
}
|
||||
|
||||
INT_PTR high_score::HighScore(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
void high_score::RenderHighScoreDialog()
|
||||
{
|
||||
HWND parent;
|
||||
int nIDDlgItem;
|
||||
CHAR String1[256];
|
||||
CHAR name[32];
|
||||
|
||||
switch (msg)
|
||||
if (ShowDialog == true)
|
||||
{
|
||||
case WM_CLOSE:
|
||||
SendMessageA(hWnd, WM_COMMAND, WM_DESTROY, 0);
|
||||
break;
|
||||
case WM_HELP:
|
||||
WinHelpA(static_cast<HWND>(reinterpret_cast<HELPINFO*>(lParam)->hItemHandle), "pinball.hlp", HELP_WM_HELP,
|
||||
(ULONG_PTR)help);
|
||||
break;
|
||||
case WM_CONTEXTMENU:
|
||||
WinHelpA((HWND)wParam, "pinball.hlp", HELP_CONTEXTMENU, (ULONG_PTR)help);
|
||||
break;
|
||||
case WM_INITDIALOG:
|
||||
show_high_scores(hWnd, dlg_hst);
|
||||
for (nIDDlgItem = DLG_HIGHSCORES_EditName1; nIDDlgItem < 611; ++nIDDlgItem)
|
||||
ShowDialog = false;
|
||||
if (dlg_position == -1)
|
||||
{
|
||||
ShowWindow(GetDlgItem(hWnd, nIDDlgItem), 0);
|
||||
dlg_enter_name = 0;
|
||||
return;
|
||||
}
|
||||
if (dlg_enter_name == 1)
|
||||
ImGui::OpenPopup("High Scores");
|
||||
}
|
||||
|
||||
bool unused_open = true;
|
||||
if (ImGui::BeginPopupModal("High Scores", &unused_open, ImGuiWindowFlags_AlwaysAutoResize))
|
||||
{
|
||||
if (ImGui::BeginTable("table1", 3, 0))
|
||||
{
|
||||
if (position == -1)
|
||||
char buf[36];
|
||||
ImGui::TableSetupColumn("Rank");
|
||||
ImGui::TableSetupColumn("Name");
|
||||
ImGui::TableSetupColumn("Score");
|
||||
ImGui::TableHeadersRow();
|
||||
|
||||
for (int offset = 0, row = 0; row < 5; row++)
|
||||
{
|
||||
dlg_enter_name = 0;
|
||||
return 1;
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
snprintf(buf, sizeof buf, "%d", row);
|
||||
ImGui::TextUnformatted(buf);
|
||||
|
||||
auto currentRow = &dlg_hst[row + offset];
|
||||
auto score = currentRow->Score;
|
||||
ImGui::TableNextColumn();
|
||||
if (dlg_enter_name == 1 && dlg_position == row)
|
||||
{
|
||||
offset = -1;
|
||||
score = dlg_score;
|
||||
ImGui::PushItemWidth(200);
|
||||
ImGui::InputText("", default_name, IM_ARRAYSIZE(default_name));
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui::TextUnformatted(currentRow->Name);
|
||||
}
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
score::string_format(score, buf);
|
||||
ImGui::TextUnformatted(buf);
|
||||
}
|
||||
HWND nameTextBox = GetDlgItem(hWnd, position + DLG_HIGHSCORES_EditName1);
|
||||
ShowWindow(nameTextBox, 5);
|
||||
EnableWindow(nameTextBox, 1);
|
||||
SetFocus(nameTextBox);
|
||||
if (default_name)
|
||||
{
|
||||
SetWindowTextA(nameTextBox, default_name);
|
||||
SendMessageA(nameTextBox, EM_SETSEL, 0, -1);
|
||||
}
|
||||
SendMessageA(nameTextBox, EM_SETLIMITTEXT, 31u, 0);
|
||||
ImGui::EndTable();
|
||||
}
|
||||
else
|
||||
ImGui::Separator();
|
||||
|
||||
if (ImGui::Button("Ok"))
|
||||
{
|
||||
SetFocus(hWnd);
|
||||
}
|
||||
parent = GetParent(hWnd);
|
||||
if (parent)
|
||||
fullscrn::center_in(parent, hWnd);
|
||||
return 0;
|
||||
case WM_COMMAND:
|
||||
switch (wParam)
|
||||
{
|
||||
case DLG_HIGHSCORES_Ok:
|
||||
if (dlg_enter_name != 1)
|
||||
if (dlg_enter_name)
|
||||
{
|
||||
break;
|
||||
default_name[31] = 0;
|
||||
place_new_score_into(dlg_hst, dlg_score, default_name, dlg_position);
|
||||
}
|
||||
GetDlgItemTextA(hWnd, position + DLG_HIGHSCORES_EditName1, name, 32);
|
||||
name[31] = 0;
|
||||
place_new_score_into(dlg_hst, dlg_score, name, position);
|
||||
break;
|
||||
case DLG_HIGHSCORES_Cancel:
|
||||
break;
|
||||
case DLG_HIGHSCORES_Clear:
|
||||
lstrcpyA(String1, pinball::get_rc_string(41, 0));
|
||||
if (MessageBoxA(hWnd, pinball::get_rc_string(40, 0), String1, MB_DEFBUTTON2 | MB_OKCANCEL) == 1)
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Cancel"))
|
||||
ImGui::CloseCurrentPopup();
|
||||
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Clear"))
|
||||
ImGui::OpenPopup("Confirm");
|
||||
if (ImGui::BeginPopupModal("Confirm", nullptr, ImGuiWindowFlags_MenuBar))
|
||||
{
|
||||
ImGui::TextUnformatted(pinball::get_rc_string(40, 0));
|
||||
if (ImGui::Button("OK", ImVec2(120, 0)))
|
||||
{
|
||||
clear_table(dlg_hst);
|
||||
if (dlg_enter_name)
|
||||
EndDialog(hWnd, 1);
|
||||
else
|
||||
EndDialog(hWnd, 0);
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
return 0;
|
||||
default:
|
||||
return 0;
|
||||
ImGui::SetItemDefaultFocus();
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Cancel", ImVec2(120, 0)))
|
||||
{
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
dlg_enter_name = 0;
|
||||
EndDialog(hWnd, 0);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void high_score::show_high_scores(HWND hDlg, high_score_struct* table)
|
||||
{
|
||||
high_score_struct* tablePtr = table;
|
||||
int nextPosition = 0;
|
||||
for (int i = 0; i < 5; ++i)
|
||||
{
|
||||
if (dlg_enter_name == 1 && position == i)
|
||||
{
|
||||
hsdlg_show_score(hDlg, " ", dlg_score, i);
|
||||
nextPosition = 1;
|
||||
}
|
||||
hsdlg_show_score(hDlg, tablePtr->Name, tablePtr->Score, i + nextPosition);
|
||||
++tablePtr;
|
||||
}
|
||||
}
|
||||
|
||||
void high_score::hsdlg_show_score(HWND hDlg, LPCSTR name, int score, int position)
|
||||
{
|
||||
CHAR scoreStr[36];
|
||||
if (position < 5)
|
||||
{
|
||||
score::string_format(score, scoreStr);
|
||||
if (scoreStr[0])
|
||||
{
|
||||
SetWindowTextA(GetDlgItem(hDlg, position + DLG_HIGHSCORES_StaticName1), name);
|
||||
SetWindowTextA(GetDlgItem(hDlg, position + DLG_HIGHSCORES_Score1), scoreStr);
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#pragma once
|
||||
#include "pinball.h"
|
||||
|
||||
struct high_score_struct
|
||||
{
|
||||
@@ -11,23 +10,20 @@ struct high_score_struct
|
||||
class high_score
|
||||
{
|
||||
public:
|
||||
static int read(high_score_struct* table, int* ptrToSmth);
|
||||
static int write(high_score_struct* table, int* ptrToSmth);
|
||||
static int read(high_score_struct* table);
|
||||
static int write(high_score_struct* table);
|
||||
static void clear_table(high_score_struct* table);
|
||||
static int get_score_position(high_score_struct* table, int score);
|
||||
static int place_new_score_into(high_score_struct* table, int score, LPSTR scoreStr, int position);
|
||||
static void scramble_number_string(int Value, char* Buffer);
|
||||
|
||||
static void show_high_score_dialog(high_score_struct* table);
|
||||
static void show_and_set_high_score_dialog(high_score_struct* table, int score, int pos, LPCSTR defaultName);
|
||||
static INT_PTR __stdcall HighScore(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
static void show_high_scores(HWND hDlg, high_score_struct* table);
|
||||
static void hsdlg_show_score(HWND hDlg, LPCSTR name, int score, int position);
|
||||
static void RenderHighScoreDialog();
|
||||
private :
|
||||
static int dlg_enter_name;
|
||||
static int dlg_score;
|
||||
static int position;
|
||||
static LPCSTR default_name;
|
||||
static int dlg_position;
|
||||
static char default_name[32];
|
||||
static high_score_struct* dlg_hst;
|
||||
static winhelp_entry help[21];
|
||||
static bool ShowDialog;
|
||||
};
|
||||
|
||||
123
SpaceCadetPinball/imconfig.h
Normal file
123
SpaceCadetPinball/imconfig.h
Normal file
@@ -0,0 +1,123 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// COMPILE-TIME OPTIONS FOR DEAR IMGUI
|
||||
// Runtime options (clipboard callbacks, enabling various features, etc.) can generally be set via the ImGuiIO structure.
|
||||
// You can use ImGui::SetAllocatorFunctions() before calling ImGui::CreateContext() to rewire memory allocation functions.
|
||||
//-----------------------------------------------------------------------------
|
||||
// A) You may edit imconfig.h (and not overwrite it when updating Dear ImGui, or maintain a patch/rebased branch with your modifications to it)
|
||||
// B) or '#define IMGUI_USER_CONFIG "my_imgui_config.h"' in your project and then add directives in your own file without touching this template.
|
||||
//-----------------------------------------------------------------------------
|
||||
// You need to make sure that configuration settings are defined consistently _everywhere_ Dear ImGui is used, which include the imgui*.cpp
|
||||
// files but also _any_ of your code that uses Dear ImGui. This is because some compile-time options have an affect on data structures.
|
||||
// Defining those options in imconfig.h will ensure every compilation unit gets to see the same data structure layouts.
|
||||
// Call IMGUI_CHECKVERSION() from your .cpp files to verify that the data structures your files are using are matching the ones imgui.cpp is using.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
//---- Define assertion handler. Defaults to calling assert().
|
||||
// If your macro uses multiple statements, make sure is enclosed in a 'do { .. } while (0)' block so it can be used as a single statement.
|
||||
//#define IM_ASSERT(_EXPR) MyAssert(_EXPR)
|
||||
//#define IM_ASSERT(_EXPR) ((void)(_EXPR)) // Disable asserts
|
||||
|
||||
//---- Define attributes of all API symbols declarations, e.g. for DLL under Windows
|
||||
// Using Dear ImGui via a shared library is not recommended, because of function call overhead and because we don't guarantee backward nor forward ABI compatibility.
|
||||
// DLL users: heaps and globals are not shared across DLL boundaries! You will need to call SetCurrentContext() + SetAllocatorFunctions()
|
||||
// for each static/DLL boundary you are calling from. Read "Context and Memory Allocators" section of imgui.cpp for more details.
|
||||
//#define IMGUI_API __declspec( dllexport )
|
||||
//#define IMGUI_API __declspec( dllimport )
|
||||
|
||||
//---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to avoid using soon-to-be obsolete function/names.
|
||||
//#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
|
||||
//---- Disable all of Dear ImGui or don't implement standard windows.
|
||||
// It is very strongly recommended to NOT disable the demo windows during development. Please read comments in imgui_demo.cpp.
|
||||
//#define IMGUI_DISABLE // Disable everything: all headers and source files will be empty.
|
||||
//#define IMGUI_DISABLE_DEMO_WINDOWS // Disable demo windows: ShowDemoWindow()/ShowStyleEditor() will be empty. Not recommended.
|
||||
//#define IMGUI_DISABLE_METRICS_WINDOW // Disable metrics/debugger window: ShowMetricsWindow() will be empty.
|
||||
|
||||
//---- Don't implement some functions to reduce linkage requirements.
|
||||
//#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc. (user32.lib/.a, kernel32.lib/.a)
|
||||
//#define IMGUI_ENABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with Visual Studio] Implement default IME handler (require imm32.lib/.a, auto-link for Visual Studio, -limm32 on command-line for MinGW)
|
||||
//#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with non-Visual Studio compilers] Don't implement default IME handler (won't require imm32.lib/.a)
|
||||
//#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, ime).
|
||||
//#define IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS // [OSX] Implement default OSX clipboard handler (need to link with '-framework ApplicationServices', this is why this is not the default).
|
||||
//#define IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS // Don't implement ImFormatString/ImFormatStringV so you can implement them yourself (e.g. if you don't want to link with vsnprintf)
|
||||
//#define IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 so you can implement them yourself.
|
||||
//#define IMGUI_DISABLE_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle at all (replace them with dummies)
|
||||
//#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle so you can implement them yourself if you don't want to link with fopen/fclose/fread/fwrite. This will also disable the LogToTTY() function.
|
||||
//#define IMGUI_DISABLE_DEFAULT_ALLOCATORS // Don't implement default allocators calling malloc()/free() to avoid linking with them. You will need to call ImGui::SetAllocatorFunctions().
|
||||
//#define IMGUI_DISABLE_SSE // Disable use of SSE intrinsics even if available
|
||||
|
||||
//---- Include imgui_user.h at the end of imgui.h as a convenience
|
||||
//#define IMGUI_INCLUDE_IMGUI_USER_H
|
||||
|
||||
//---- Pack colors to BGRA8 instead of RGBA8 (to avoid converting from one to another)
|
||||
//#define IMGUI_USE_BGRA_PACKED_COLOR
|
||||
|
||||
//---- Use 32-bit for ImWchar (default is 16-bit) to support unicode planes 1-16. (e.g. point beyond 0xFFFF like emoticons, dingbats, symbols, shapes, ancient languages, etc...)
|
||||
//#define IMGUI_USE_WCHAR32
|
||||
|
||||
//---- Avoid multiple STB libraries implementations, or redefine path/filenames to prioritize another version
|
||||
// By default the embedded implementations are declared static and not available outside of Dear ImGui sources files.
|
||||
//#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h"
|
||||
//#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h"
|
||||
//#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION
|
||||
//#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION
|
||||
|
||||
//---- Use stb_printf's faster implementation of vsnprintf instead of the one from libc (unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined)
|
||||
// Requires 'stb_sprintf.h' to be available in the include path. Compatibility checks of arguments and formats done by clang and GCC will be disabled in order to support the extra formats provided by STB sprintf.
|
||||
// #define IMGUI_USE_STB_SPRINTF
|
||||
|
||||
//---- Use FreeType to build and rasterize the font atlas (instead of stb_truetype which is embedded by default in Dear ImGui)
|
||||
// Requires FreeType headers to be available in the include path. Requires program to be compiled with 'misc/freetype/imgui_freetype.cpp' (in this repository) + the FreeType library (not provided).
|
||||
// On Windows you may use vcpkg with 'vcpkg install freetype --triplet=x64-windows' + 'vcpkg integrate install'.
|
||||
//#define IMGUI_ENABLE_FREETYPE
|
||||
|
||||
//---- Use stb_truetype to build and rasterize the font atlas (default)
|
||||
// The only purpose of this define is if you want force compilation of the stb_truetype backend ALONG with the FreeType backend.
|
||||
//#define IMGUI_ENABLE_STB_TRUETYPE
|
||||
|
||||
//---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4.
|
||||
// This will be inlined as part of ImVec2 and ImVec4 class declarations.
|
||||
/*
|
||||
#define IM_VEC2_CLASS_EXTRA \
|
||||
ImVec2(const MyVec2& f) { x = f.x; y = f.y; } \
|
||||
operator MyVec2() const { return MyVec2(x,y); }
|
||||
|
||||
#define IM_VEC4_CLASS_EXTRA \
|
||||
ImVec4(const MyVec4& f) { x = f.x; y = f.y; z = f.z; w = f.w; } \
|
||||
operator MyVec4() const { return MyVec4(x,y,z,w); }
|
||||
*/
|
||||
|
||||
//---- Use 32-bit vertex indices (default is 16-bit) is one way to allow large meshes with more than 64K vertices.
|
||||
// Your renderer backend will need to support it (most example renderer backends support both 16/32-bit indices).
|
||||
// Another way to allow large meshes while keeping 16-bit indices is to handle ImDrawCmd::VtxOffset in your renderer.
|
||||
// Read about ImGuiBackendFlags_RendererHasVtxOffset for details.
|
||||
//#define ImDrawIdx unsigned int
|
||||
|
||||
//---- Override ImDrawCallback signature (will need to modify renderer backends accordingly)
|
||||
//struct ImDrawList;
|
||||
//struct ImDrawCmd;
|
||||
//typedef void (*MyImDrawCallback)(const ImDrawList* draw_list, const ImDrawCmd* cmd, void* my_renderer_user_data);
|
||||
//#define ImDrawCallback MyImDrawCallback
|
||||
|
||||
//---- Debug Tools: Macro to break in Debugger
|
||||
// (use 'Metrics->Tools->Item Picker' to pick widgets with the mouse and break into them for easy debugging.)
|
||||
//#define IM_DEBUG_BREAK IM_ASSERT(0)
|
||||
//#define IM_DEBUG_BREAK __debugbreak()
|
||||
|
||||
//---- Debug Tools: Have the Item Picker break in the ItemAdd() function instead of ItemHoverable(),
|
||||
// (which comes earlier in the code, will catch a few extra items, allow picking items other than Hovered one.)
|
||||
// This adds a small runtime cost which is why it is not enabled by default.
|
||||
//#define IMGUI_DEBUG_TOOL_ITEM_PICKER_EX
|
||||
|
||||
//---- Debug Tools: Enable slower asserts
|
||||
//#define IMGUI_DEBUG_PARANOID
|
||||
|
||||
//---- Tip: You can add extra functions within the ImGui:: namespace, here or in your own headers files.
|
||||
/*
|
||||
namespace ImGui
|
||||
{
|
||||
void MyFunction(const char* name, const MyMatrix44& v);
|
||||
}
|
||||
*/
|
||||
11866
SpaceCadetPinball/imgui.cpp
Normal file
11866
SpaceCadetPinball/imgui.cpp
Normal file
File diff suppressed because it is too large
Load Diff
2907
SpaceCadetPinball/imgui.h
Normal file
2907
SpaceCadetPinball/imgui.h
Normal file
File diff suppressed because it is too large
Load Diff
7652
SpaceCadetPinball/imgui_demo.cpp
Normal file
7652
SpaceCadetPinball/imgui_demo.cpp
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user