Compare commits
56 Commits
Release_1.
...
WindowsCla
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c7f5f8cd30 | ||
|
|
da4b99e983 | ||
|
|
2abcaac437 | ||
|
|
98da410251 | ||
|
|
e020c0fe33 | ||
|
|
33b8b29f11 | ||
|
|
84a46082ab | ||
|
|
a079117507 | ||
|
|
620ec011ec | ||
|
|
1af8bb67d7 | ||
|
|
089ccbf549 | ||
|
|
1428fb3770 | ||
|
|
1c1fbcb811 | ||
|
|
c0ec8ec932 | ||
|
|
71e25fd7fa | ||
|
|
b40b54ce51 | ||
|
|
b4a85bcf2f | ||
|
|
acc2725bbe | ||
|
|
68c2055ce6 | ||
|
|
09668f3468 | ||
|
|
4878b6a835 | ||
|
|
bd606436bd | ||
|
|
457a982f72 | ||
|
|
e2f10333d9 | ||
|
|
356977290e | ||
|
|
a65c40fe32 | ||
|
|
d0c1ac60b6 | ||
|
|
3c2fff9d07 | ||
|
|
09c62f5909 | ||
|
|
cf215aaa6a | ||
|
|
893d898d0a | ||
|
|
502fc71afc | ||
|
|
cf8b53de01 | ||
|
|
331f1dc125 | ||
|
|
0d9610ddb6 | ||
|
|
de76557325 | ||
|
|
b995b02fd1 | ||
|
|
de6c31802c | ||
|
|
86eaad5b79 | ||
|
|
60e9f63607 | ||
|
|
10c83e8bf5 | ||
|
|
d5b44e44e1 | ||
|
|
dcd488c48c | ||
|
|
db08631ab9 | ||
|
|
bad55d49cf | ||
|
|
98f234fce3 | ||
|
|
55984fbb08 | ||
|
|
5c3e9fea4c | ||
|
|
debe52c1e0 | ||
|
|
1c5256a4c6 | ||
|
|
d594f5fdb7 | ||
|
|
49f6132d23 | ||
|
|
6ff457eb68 | ||
|
|
5b9a1ff95d | ||
|
|
232f24a2a2 | ||
|
|
efc56e82d9 |
11
.gitignore
vendored
11
.gitignore
vendored
@@ -21,6 +21,9 @@ bld/
|
|||||||
[Bb]in/
|
[Bb]in/
|
||||||
[Oo]bj/
|
[Oo]bj/
|
||||||
[Ll]og/
|
[Ll]og/
|
||||||
|
ARM/
|
||||||
|
ARM64/
|
||||||
|
win32/
|
||||||
|
|
||||||
# Visual Studio 2015 cache/options directory
|
# Visual Studio 2015 cache/options directory
|
||||||
.vs/
|
.vs/
|
||||||
@@ -263,3 +266,11 @@ __pycache__/
|
|||||||
/Export
|
/Export
|
||||||
/DrMem
|
/DrMem
|
||||||
/Doc private
|
/Doc private
|
||||||
|
|
||||||
|
# Cmake stuff
|
||||||
|
/Libs
|
||||||
|
/out
|
||||||
|
|
||||||
|
# WinXp stuff
|
||||||
|
DebugWinXp/
|
||||||
|
ReleaseWinXp/
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
rc /Fo.\DrMem\SpaceCadetPinball.res ".\SpaceCadetPinball\SpaceCadetPinball.rc"
|
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"
|
cl /Zi /MT /MP /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)
|
9 String (content)
|
||||||
10 Array of 16bits integer values
|
10 Array of 16bits integer values
|
||||||
11 Array of 32bits floating point values (collision box, ...)
|
11 Array of 32bits floating point values (collision box, ...)
|
||||||
12 16 bpp bitmap (Heightmap?)
|
12 16 bpp bitmap (zMap)
|
||||||
|
|
||||||
|
|
||||||
//-- 8bpp bitmap data header --//
|
//-- 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
|
+1: Width WORD
|
||||||
+3: Height WORD
|
+3: Height WORD
|
||||||
+5: X position WORD
|
+5: X position WORD
|
||||||
+7 Y position WORD
|
+7 Y position WORD
|
||||||
+9: Size of bitmap DWORD
|
+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)
|
+14: Bitmap data BYTE*(DWORD@+9)
|
||||||
|
|
||||||
|
|
||||||
//-- 16bpp bitmap data header --//
|
//-- 16bpp zMap data header --//
|
||||||
+0: Width WORD
|
+0: Width WORD
|
||||||
+2: Height WORD
|
+2: Height WORD
|
||||||
+4: Pitch/2 WORD
|
+4: Pitch/2 WORD
|
||||||
@@ -62,6 +62,16 @@ Type Meaning/comments
|
|||||||
+12: Unknown (80) WORD
|
+12: Unknown (80) WORD
|
||||||
+14: Bitmap data BYTE*(DWORD@+9)
|
+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 --//
|
//-- 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.
|
||||||
39
README.md
Normal file
39
README.md
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
# SpaceCadetPinball
|
||||||
|
**Summary:** Reverse engineering of `3D Pinball for Windows – Space Cadet`, a game bundled with Windows.
|
||||||
|
|
||||||
|
**How to play:** Place compiled exe into a folder containing original game resources (not included).\
|
||||||
|
Supports data files from Windows and Full Tilt versions of the game.
|
||||||
|
\
|
||||||
|
\
|
||||||
|
\
|
||||||
|
\
|
||||||
|
\
|
||||||
|
\
|
||||||
|
**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` features and depends on Windows libs.\
|
||||||
|
Compile with Visual Studio; tested with 2017 and 2019.
|
||||||
|
|
||||||
|
**Plans:**
|
||||||
|
* ~~Decompile original game~~
|
||||||
|
* ~~Resizable window, scaled graphics~~
|
||||||
|
* ~~Loader for high-res sprites from CADET.DAT~~
|
||||||
|
* ~~Cross-platform port using SDL2, SDL2_mixer, ImGui~~
|
||||||
|
* Text translations
|
||||||
|
* Misc features of Full Tilt: 3 music tracks, multiball, centered textboxes, etc.
|
||||||
|
* 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,26 +1,50 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio 15
|
# Visual Studio Version 16
|
||||||
VisualStudioVersion = 15.0.28307.705
|
VisualStudioVersion = 16.0.31624.102
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SpaceCadetPinball", "SpaceCadetPinball\SpaceCadetPinball.vcxproj", "{F7B78CC7-6984-4F79-9486-ABCF87DF9F06}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SpaceCadetPinball", "SpaceCadetPinball\SpaceCadetPinball.vcxproj", "{F7B78CC7-6984-4F79-9486-ABCF87DF9F06}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|ARM = Debug|ARM
|
||||||
|
Debug|ARM64 = Debug|ARM64
|
||||||
Debug|x64 = Debug|x64
|
Debug|x64 = Debug|x64
|
||||||
Debug|x86 = Debug|x86
|
Debug|x86 = Debug|x86
|
||||||
|
Release|ARM = Release|ARM
|
||||||
|
Release|ARM64 = Release|ARM64
|
||||||
Release|x64 = Release|x64
|
Release|x64 = Release|x64
|
||||||
Release|x86 = Release|x86
|
Release|x86 = Release|x86
|
||||||
|
ReleaseWinXp|ARM = ReleaseWinXp|ARM
|
||||||
|
ReleaseWinXp|ARM64 = ReleaseWinXp|ARM64
|
||||||
|
ReleaseWinXp|x64 = ReleaseWinXp|x64
|
||||||
|
ReleaseWinXp|x86 = ReleaseWinXp|x86
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{F7B78CC7-6984-4F79-9486-ABCF87DF9F06}.Debug|ARM.ActiveCfg = Debug|ARM
|
||||||
|
{F7B78CC7-6984-4F79-9486-ABCF87DF9F06}.Debug|ARM.Build.0 = Debug|ARM
|
||||||
|
{F7B78CC7-6984-4F79-9486-ABCF87DF9F06}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||||
|
{F7B78CC7-6984-4F79-9486-ABCF87DF9F06}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||||
{F7B78CC7-6984-4F79-9486-ABCF87DF9F06}.Debug|x64.ActiveCfg = Debug|x64
|
{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|x64.Build.0 = Debug|x64
|
||||||
{F7B78CC7-6984-4F79-9486-ABCF87DF9F06}.Debug|x86.ActiveCfg = Debug|Win32
|
{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}.Debug|x86.Build.0 = Debug|Win32
|
||||||
|
{F7B78CC7-6984-4F79-9486-ABCF87DF9F06}.Release|ARM.ActiveCfg = Release|ARM
|
||||||
|
{F7B78CC7-6984-4F79-9486-ABCF87DF9F06}.Release|ARM.Build.0 = Release|ARM
|
||||||
|
{F7B78CC7-6984-4F79-9486-ABCF87DF9F06}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||||
|
{F7B78CC7-6984-4F79-9486-ABCF87DF9F06}.Release|ARM64.Build.0 = Release|ARM64
|
||||||
{F7B78CC7-6984-4F79-9486-ABCF87DF9F06}.Release|x64.ActiveCfg = Release|x64
|
{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|x64.Build.0 = Release|x64
|
||||||
{F7B78CC7-6984-4F79-9486-ABCF87DF9F06}.Release|x86.ActiveCfg = Release|Win32
|
{F7B78CC7-6984-4F79-9486-ABCF87DF9F06}.Release|x86.ActiveCfg = Release|Win32
|
||||||
{F7B78CC7-6984-4F79-9486-ABCF87DF9F06}.Release|x86.Build.0 = Release|Win32
|
{F7B78CC7-6984-4F79-9486-ABCF87DF9F06}.Release|x86.Build.0 = Release|Win32
|
||||||
|
{F7B78CC7-6984-4F79-9486-ABCF87DF9F06}.ReleaseWinXp|ARM.ActiveCfg = ReleaseWinXp|ARM
|
||||||
|
{F7B78CC7-6984-4F79-9486-ABCF87DF9F06}.ReleaseWinXp|ARM.Build.0 = ReleaseWinXp|ARM
|
||||||
|
{F7B78CC7-6984-4F79-9486-ABCF87DF9F06}.ReleaseWinXp|ARM64.ActiveCfg = ReleaseWinXp|ARM64
|
||||||
|
{F7B78CC7-6984-4F79-9486-ABCF87DF9F06}.ReleaseWinXp|ARM64.Build.0 = ReleaseWinXp|ARM64
|
||||||
|
{F7B78CC7-6984-4F79-9486-ABCF87DF9F06}.ReleaseWinXp|x64.ActiveCfg = ReleaseWinXp|x64
|
||||||
|
{F7B78CC7-6984-4F79-9486-ABCF87DF9F06}.ReleaseWinXp|x64.Build.0 = ReleaseWinXp|x64
|
||||||
|
{F7B78CC7-6984-4F79-9486-ABCF87DF9F06}.ReleaseWinXp|x86.ActiveCfg = ReleaseWinXp|Win32
|
||||||
|
{F7B78CC7-6984-4F79-9486-ABCF87DF9F06}.ReleaseWinXp|x86.Build.0 = ReleaseWinXp|Win32
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
#include "Sound.h"
|
#include "Sound.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "pb.h"
|
||||||
#include "pinball.h"
|
#include "pinball.h"
|
||||||
#include "WaveMix.h"
|
#include "WaveMix.h"
|
||||||
#include "winmain.h"
|
#include "winmain.h"
|
||||||
@@ -45,7 +47,9 @@ int Sound::Init(HINSTANCE hInstance, int voices, void (* someFuncPtr)(int, MIXWA
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MessageBoxA(winmain::hwnd_frame, pinball::get_rc_string(42, 0), pinball::WindowName, 0x2000u);
|
/*FT does not have the file, defaults work OK*/
|
||||||
|
if (!pb::FullTiltMode)
|
||||||
|
MessageBoxW(winmain::hwnd_frame, pinball::get_rc_Wstring(42, 0), L"", 0x2000u);
|
||||||
}
|
}
|
||||||
|
|
||||||
WndClass.style = 0;
|
WndClass.style = 0;
|
||||||
@@ -143,7 +147,7 @@ void Sound::Close()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sound::PlaySound(MIXWAVE* wavePtr, int minChannel, int maxChannel, unsigned int dwFlags, __int16 loops)
|
void Sound::PlaySound(MIXWAVE* wavePtr, int minChannel, int maxChannel, unsigned int dwFlags, int16_t loops)
|
||||||
{
|
{
|
||||||
MIXPLAYPARAMS mixParams{};
|
MIXPLAYPARAMS mixParams{};
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ public:
|
|||||||
static void Activate();
|
static void Activate();
|
||||||
static void Deactivate();
|
static void Deactivate();
|
||||||
static void Close();
|
static void Close();
|
||||||
static void PlaySound(MIXWAVE* wavePtr, int minChannel, int maxChannel, unsigned int dwFlags, __int16 loops);
|
static void PlaySound(MIXWAVE* wavePtr, int minChannel, int maxChannel, unsigned int dwFlags, int16_t loops);
|
||||||
static MIXWAVE* LoadWaveFile(LPCSTR lpName);
|
static MIXWAVE* LoadWaveFile(LPCSTR lpName);
|
||||||
static void FreeSound(MIXWAVE* wave);
|
static void FreeSound(MIXWAVE* wave);
|
||||||
static void Flush(int channelFrom, int channelTo);
|
static void Flush(int channelFrom, int channelTo);
|
||||||
|
|||||||
@@ -16,21 +16,21 @@
|
|||||||
#include "winmain.h"
|
#include "winmain.h"
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
// Testing with UI
|
// Testing with UI
|
||||||
char cmdLine[1]{};
|
char cmdLine[1]{};
|
||||||
WinMain(GetModuleHandleA(nullptr), 0, cmdLine, 10);
|
WinMain(GetModuleHandleA(nullptr), nullptr, cmdLine, 10);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
std::cout << "Hello World!\n";
|
||||||
for (int i = 0; i < 100; i++)
|
gdrv::init(nullptr, nullptr);
|
||||||
|
auto dib = gdrv::DibCreate(8, 1, 1);
|
||||||
|
gdrv::DibSetUsage(dib, nullptr, 1);
|
||||||
|
|
||||||
|
auto d = objlist_class<void>(2, 4);
|
||||||
|
for (size_t i = 0; i < 100; i++)
|
||||||
{
|
{
|
||||||
d.Add((void*)i);
|
d.Add((void*)i);
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
@@ -1,10 +1,42 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|ARM">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>ARM</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|ARM64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>ARM64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
<Configuration>Debug</Configuration>
|
<Configuration>Debug</Configuration>
|
||||||
<Platform>Win32</Platform>
|
<Platform>Win32</Platform>
|
||||||
</ProjectConfiguration>
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="ReleaseWinXp|ARM">
|
||||||
|
<Configuration>ReleaseWinXp</Configuration>
|
||||||
|
<Platform>ARM</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="ReleaseWinXp|ARM64">
|
||||||
|
<Configuration>ReleaseWinXp</Configuration>
|
||||||
|
<Platform>ARM64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="ReleaseWinXp|Win32">
|
||||||
|
<Configuration>ReleaseWinXp</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="ReleaseWinXp|x64">
|
||||||
|
<Configuration>ReleaseWinXp</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|ARM">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>ARM</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|ARM64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>ARM64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
<ProjectConfiguration Include="Release|Win32">
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
<Configuration>Release</Configuration>
|
<Configuration>Release</Configuration>
|
||||||
<Platform>Win32</Platform>
|
<Platform>Win32</Platform>
|
||||||
@@ -23,32 +55,86 @@
|
|||||||
<ProjectGuid>{F7B78CC7-6984-4F79-9486-ABCF87DF9F06}</ProjectGuid>
|
<ProjectGuid>{F7B78CC7-6984-4F79-9486-ABCF87DF9F06}</ProjectGuid>
|
||||||
<Keyword>Win32Proj</Keyword>
|
<Keyword>Win32Proj</Keyword>
|
||||||
<RootNamespace>SpaceCadetPinball</RootNamespace>
|
<RootNamespace>SpaceCadetPinball</RootNamespace>
|
||||||
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
|
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<PlatformToolset>v141</PlatformToolset>
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<CharacterSet>NotSet</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
<CharacterSet>NotSet</CharacterSet>
|
<CharacterSet>NotSet</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<PlatformToolset>v141</PlatformToolset>
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>NotSet</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>NotSet</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWinXp|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v141_xp</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>NotSet</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWinXp|ARM'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v141_xp</PlatformToolset>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
<CharacterSet>NotSet</CharacterSet>
|
<CharacterSet>NotSet</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<PlatformToolset>v141</PlatformToolset>
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<CharacterSet>NotSet</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
<CharacterSet>NotSet</CharacterSet>
|
<CharacterSet>NotSet</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<PlatformToolset>v141</PlatformToolset>
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>NotSet</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>NotSet</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWinXp|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v141_xp</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>NotSet</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWinXp|ARM64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v141_xp</PlatformToolset>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
<CharacterSet>NotSet</CharacterSet>
|
<CharacterSet>NotSet</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
@@ -60,29 +146,84 @@
|
|||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<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" />
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="PropertySheets">
|
||||||
|
<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'">
|
<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" />
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWinXp|Win32'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWinXp|ARM'" Label="PropertySheets">
|
||||||
|
<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'">
|
<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" />
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
|
||||||
|
<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'">
|
<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" />
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWinXp|x64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWinXp|ARM64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
<PropertyGroup Label="UserMacros" />
|
<PropertyGroup Label="UserMacros" />
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<LinkIncremental>true</LinkIncremental>
|
<LinkIncremental>true</LinkIncremental>
|
||||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||||
|
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||||
|
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
<LinkIncremental>true</LinkIncremental>
|
<LinkIncremental>true</LinkIncremental>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<LinkIncremental>false</LinkIncremental>
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWinXp|Win32'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWinXp|ARM'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
<LinkIncremental>false</LinkIncremental>
|
<LinkIncremental>false</LinkIncremental>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWinXp|x64'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWinXp|ARM64'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||||
@@ -94,6 +235,26 @@
|
|||||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||||
<PreprocessToFile>false</PreprocessToFile>
|
<PreprocessToFile>false</PreprocessToFile>
|
||||||
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalDependencies>Comctl32.lib;Winmm.lib;Htmlhelp.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
|
||||||
|
<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>
|
||||||
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
@@ -110,6 +271,24 @@
|
|||||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<ConformanceMode>true</ConformanceMode>
|
<ConformanceMode>true</ConformanceMode>
|
||||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||||
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalDependencies>Comctl32.lib;Winmm.lib;Htmlhelp.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||||
|
<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>
|
||||||
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
@@ -128,9 +307,73 @@
|
|||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<ConformanceMode>true</ConformanceMode>
|
<ConformanceMode>true</ConformanceMode>
|
||||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||||
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Windows</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|ARM'">
|
||||||
|
<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>
|
||||||
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</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)'=='ReleaseWinXp|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>false</ConformanceMode>
|
||||||
|
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||||
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</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)'=='ReleaseWinXp|ARM'">
|
||||||
|
<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>false</ConformanceMode>
|
||||||
|
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||||
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
@@ -148,9 +391,73 @@
|
|||||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<ConformanceMode>true</ConformanceMode>
|
<ConformanceMode>true</ConformanceMode>
|
||||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||||
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Windows</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|ARM64'">
|
||||||
|
<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>
|
||||||
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</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)'=='ReleaseWinXp|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>false</ConformanceMode>
|
||||||
|
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||||
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</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)'=='ReleaseWinXp|ARM64'">
|
||||||
|
<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>false</ConformanceMode>
|
||||||
|
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||||
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
@@ -219,7 +526,6 @@
|
|||||||
<ClInclude Include="TTimer.h" />
|
<ClInclude Include="TTimer.h" />
|
||||||
<ClInclude Include="TTripwire.h" />
|
<ClInclude Include="TTripwire.h" />
|
||||||
<ClInclude Include="TWall.h" />
|
<ClInclude Include="TWall.h" />
|
||||||
<ClInclude Include="TZmapList.h" />
|
|
||||||
<ClInclude Include="WaveMix.h" />
|
<ClInclude Include="WaveMix.h" />
|
||||||
<ClInclude Include="winmain.h" />
|
<ClInclude Include="winmain.h" />
|
||||||
<ClInclude Include="zdrv.h" />
|
<ClInclude Include="zdrv.h" />
|
||||||
@@ -234,15 +540,22 @@
|
|||||||
<ClCompile Include="memory.cpp" />
|
<ClCompile Include="memory.cpp" />
|
||||||
<ClCompile Include="midi.cpp" />
|
<ClCompile Include="midi.cpp" />
|
||||||
<ClCompile Include="nudge.cpp" />
|
<ClCompile Include="nudge.cpp" />
|
||||||
<ClCompile Include="objlist_class.cpp" />
|
|
||||||
<ClCompile Include="options.cpp" />
|
<ClCompile Include="options.cpp" />
|
||||||
<ClCompile Include="partman.cpp" />
|
<ClCompile Include="partman.cpp" />
|
||||||
<ClCompile Include="pb.cpp" />
|
<ClCompile Include="pb.cpp" />
|
||||||
<ClCompile Include="pch.cpp">
|
<ClCompile Include="pch.cpp">
|
||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">Create</PrecompiledHeader>
|
||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">Create</PrecompiledHeader>
|
||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">Create</PrecompiledHeader>
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseWinXp|Win32'">Create</PrecompiledHeader>
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseWinXp|ARM'">Create</PrecompiledHeader>
|
||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">Create</PrecompiledHeader>
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseWinXp|x64'">Create</PrecompiledHeader>
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseWinXp|ARM64'">Create</PrecompiledHeader>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="pinball.cpp" />
|
<ClCompile Include="pinball.cpp" />
|
||||||
<ClCompile Include="proj.cpp" />
|
<ClCompile Include="proj.cpp" />
|
||||||
|
|||||||
@@ -81,9 +81,6 @@
|
|||||||
<ClInclude Include="TTimer.h">
|
<ClInclude Include="TTimer.h">
|
||||||
<Filter>Header Files\TPinballComponent</Filter>
|
<Filter>Header Files\TPinballComponent</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="TZmapList.h">
|
|
||||||
<Filter>Header Files\TPinballComponent</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="memory.h">
|
<ClInclude Include="memory.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@@ -236,9 +233,6 @@
|
|||||||
<ClCompile Include="SpaceCadetPinball.cpp">
|
<ClCompile Include="SpaceCadetPinball.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="objlist_class.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="partman.cpp">
|
<ClCompile Include="partman.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
|||||||
@@ -2,17 +2,19 @@
|
|||||||
#include "TBall.h"
|
#include "TBall.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "fullscrn.h"
|
||||||
#include "loader.h"
|
#include "loader.h"
|
||||||
#include "maths.h"
|
#include "maths.h"
|
||||||
#include "objlist_class.h"
|
#include "objlist_class.h"
|
||||||
|
#include "pb.h"
|
||||||
#include "proj.h"
|
#include "proj.h"
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
#include "TPinballTable.h"
|
#include "TPinballTable.h"
|
||||||
#include "TZmapList.h"
|
|
||||||
|
|
||||||
TBall::TBall(TPinballTable* table) : TPinballComponent(table, -1, false)
|
TBall::TBall(TPinballTable* table) : TPinballComponent(table, -1, false)
|
||||||
{
|
{
|
||||||
visualStruct visual{};
|
visualStruct visual{};
|
||||||
|
char ballGroupName[10]{"ball"};
|
||||||
|
|
||||||
TimeNow = 0.0;
|
TimeNow = 0.0;
|
||||||
RayMaxDistance = 0.0;
|
RayMaxDistance = 0.0;
|
||||||
@@ -30,8 +32,13 @@ TBall::TBall(TPinballTable* table) : TPinballComponent(table, -1, false)
|
|||||||
Position.X = 0.0;
|
Position.X = 0.0;
|
||||||
Position.Y = 0.0;
|
Position.Y = 0.0;
|
||||||
|
|
||||||
ListBitmap = new TZmapList(0, 4);
|
ListBitmap = new objlist_class<gdrv_bitmap8>(0, 4);
|
||||||
auto groupIndex = loader::query_handle("ball");
|
|
||||||
|
/*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);
|
Offset = *loader::query_float_attribute(groupIndex, 0, 500);
|
||||||
auto visualCount = loader::query_visual_states(groupIndex);
|
auto visualCount = loader::query_visual_states(groupIndex);
|
||||||
auto index = 0;
|
auto index = 0;
|
||||||
@@ -73,12 +80,12 @@ void TBall::Repaint()
|
|||||||
|
|
||||||
auto zArrPtr = VisualZArray;
|
auto zArrPtr = VisualZArray;
|
||||||
int index;
|
int index;
|
||||||
for (index = 0; index < ListBitmap->Count() - 1; ++index, zArrPtr++)
|
for (index = 0; index < ListBitmap->GetCount() - 1; ++index, zArrPtr++)
|
||||||
{
|
{
|
||||||
if (*zArrPtr <= zDepth) break;
|
if (*zArrPtr <= zDepth) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto bmp = static_cast<gdrv_bitmap8*>(ListBitmap->Get(index));
|
auto bmp = ListBitmap->Get(index);
|
||||||
render::ball_set(
|
render::ball_set(
|
||||||
RenderSprite,
|
RenderSprite,
|
||||||
bmp,
|
bmp,
|
||||||
|
|||||||
@@ -4,9 +4,9 @@
|
|||||||
|
|
||||||
#include "control.h"
|
#include "control.h"
|
||||||
#include "loader.h"
|
#include "loader.h"
|
||||||
|
#include "objlist_class.h"
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include "TZmapList.h"
|
|
||||||
|
|
||||||
TBlocker::TBlocker(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true)
|
TBlocker::TBlocker(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true)
|
||||||
{
|
{
|
||||||
@@ -46,7 +46,7 @@ int TBlocker::Message(int code, float value)
|
|||||||
case 52:
|
case 52:
|
||||||
ActiveFlag = 1;
|
ActiveFlag = 1;
|
||||||
loader::play_sound(SoundIndex4);
|
loader::play_sound(SoundIndex4);
|
||||||
render::sprite_set_bitmap(RenderSprite, static_cast<gdrv_bitmap8*>(ListBitmap->Get(0)));
|
render::sprite_set_bitmap(RenderSprite, ListBitmap->Get(0));
|
||||||
break;
|
break;
|
||||||
case 59:
|
case 59:
|
||||||
break;
|
break;
|
||||||
@@ -57,7 +57,7 @@ int TBlocker::Message(int code, float value)
|
|||||||
timer::kill(Timer);
|
timer::kill(Timer);
|
||||||
|
|
||||||
float timerTime;
|
float timerTime;
|
||||||
if (value <= 0.0)
|
if (value <= 0.0f)
|
||||||
timerTime = 0.0;
|
timerTime = 0.0;
|
||||||
else
|
else
|
||||||
timerTime = value;
|
timerTime = value;
|
||||||
|
|||||||
@@ -4,10 +4,10 @@
|
|||||||
|
|
||||||
#include "control.h"
|
#include "control.h"
|
||||||
#include "loader.h"
|
#include "loader.h"
|
||||||
|
#include "objlist_class.h"
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include "TPinballTable.h"
|
#include "TPinballTable.h"
|
||||||
#include "TZmapList.h"
|
|
||||||
|
|
||||||
TBumper::TBumper(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true)
|
TBumper::TBumper(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true)
|
||||||
{
|
{
|
||||||
@@ -29,8 +29,8 @@ int TBumper::Message(int code, float value)
|
|||||||
case 11:
|
case 11:
|
||||||
{
|
{
|
||||||
auto nextBmp = static_cast<int>(floor(value));
|
auto nextBmp = static_cast<int>(floor(value));
|
||||||
if (2 * nextBmp > ListBitmap->Count() - 1)
|
if (2 * nextBmp > ListBitmap->GetCount() - 1)
|
||||||
nextBmp = (ListBitmap->Count() - 1) / 2;
|
nextBmp = (ListBitmap->GetCount() - 1) / 2;
|
||||||
if (nextBmp < 0)
|
if (nextBmp < 0)
|
||||||
nextBmp = 0;
|
nextBmp = 0;
|
||||||
if (nextBmp != BmpIndex)
|
if (nextBmp != BmpIndex)
|
||||||
@@ -48,7 +48,7 @@ int TBumper::Message(int code, float value)
|
|||||||
case 12:
|
case 12:
|
||||||
{
|
{
|
||||||
auto nextBmp = BmpIndex + 1;
|
auto nextBmp = BmpIndex + 1;
|
||||||
auto maxBmp = ListBitmap->Count() - 1;
|
auto maxBmp = ListBitmap->GetCount() - 1;
|
||||||
if (2 * nextBmp > maxBmp)
|
if (2 * nextBmp > maxBmp)
|
||||||
nextBmp = maxBmp / 2;
|
nextBmp = maxBmp / 2;
|
||||||
TBumper::Message(11, static_cast<float>(nextBmp));
|
TBumper::Message(11, static_cast<float>(nextBmp));
|
||||||
@@ -124,8 +124,8 @@ int TBumper::get_scoring(int index)
|
|||||||
void TBumper::TimerExpired(int timerId, void* caller)
|
void TBumper::TimerExpired(int timerId, void* caller)
|
||||||
{
|
{
|
||||||
auto bump = static_cast<TBumper*>(caller);
|
auto bump = static_cast<TBumper*>(caller);
|
||||||
auto bmp = static_cast<gdrv_bitmap8*>(bump->ListBitmap->Get(bump->BmpIndex * 2));
|
auto bmp = bump->ListBitmap->Get(bump->BmpIndex * 2);
|
||||||
auto zMap = static_cast<zmap_header_type*>(bump->ListZMap->Get(bump->BmpIndex * 2));
|
auto zMap = bump->ListZMap->Get(bump->BmpIndex * 2);
|
||||||
bump->Timer = 0;
|
bump->Timer = 0;
|
||||||
render::sprite_set(
|
render::sprite_set(
|
||||||
bump->RenderSprite,
|
bump->RenderSprite,
|
||||||
@@ -139,8 +139,8 @@ void TBumper::TimerExpired(int timerId, void* caller)
|
|||||||
void TBumper::Fire()
|
void TBumper::Fire()
|
||||||
{
|
{
|
||||||
int bmpIndex = 2 * BmpIndex + 1;
|
int bmpIndex = 2 * BmpIndex + 1;
|
||||||
auto bmp = static_cast<gdrv_bitmap8*>(ListBitmap->Get(bmpIndex));
|
auto bmp = ListBitmap->Get(bmpIndex);
|
||||||
auto zMap = static_cast<zmap_header_type*>(ListZMap->Get(bmpIndex));
|
auto zMap = ListZMap->Get(bmpIndex);
|
||||||
render::sprite_set(
|
render::sprite_set(
|
||||||
RenderSprite,
|
RenderSprite,
|
||||||
bmp,
|
bmp,
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ TCollisionComponent::TCollisionComponent(TPinballTable* table, int groupIndex, b
|
|||||||
{
|
{
|
||||||
visualStruct visual{};
|
visualStruct visual{};
|
||||||
|
|
||||||
EdgeList = new objlist_class(4, 4);
|
EdgeList = new objlist_class<TEdgeSegment>(4, 4);
|
||||||
ActiveFlag = 1;
|
ActiveFlag = 1;
|
||||||
if (GroupName != nullptr)
|
if (GroupName != nullptr)
|
||||||
UnusedBaseFlag = 1;
|
UnusedBaseFlag = 1;
|
||||||
@@ -42,9 +42,9 @@ TCollisionComponent::TCollisionComponent(TPinballTable* table, int groupIndex, b
|
|||||||
|
|
||||||
TCollisionComponent::~TCollisionComponent()
|
TCollisionComponent::~TCollisionComponent()
|
||||||
{
|
{
|
||||||
for (TEdgeSegment* edge; EdgeList->Count() > 0;)
|
for (TEdgeSegment* edge; EdgeList->GetCount() > 0;)
|
||||||
{
|
{
|
||||||
edge = static_cast<TEdgeSegment*>(EdgeList->Get(0));
|
edge = EdgeList->Get(0);
|
||||||
EdgeList->Delete(edge);
|
EdgeList->Delete(edge);
|
||||||
delete edge;
|
delete edge;
|
||||||
}
|
}
|
||||||
@@ -54,9 +54,9 @@ TCollisionComponent::~TCollisionComponent()
|
|||||||
|
|
||||||
void TCollisionComponent::port_draw()
|
void TCollisionComponent::port_draw()
|
||||||
{
|
{
|
||||||
for (int index = EdgeList->Count() - 1; index >= 0; index--)
|
for (int index = EdgeList->GetCount() - 1; index >= 0; index--)
|
||||||
{
|
{
|
||||||
static_cast<TEdgeSegment*>(EdgeList->Get(index))->port_draw();
|
EdgeList->Get(index)->port_draw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,7 +70,7 @@ int TCollisionComponent::DefaultCollision(TBall* ball, vector_type* nextPosition
|
|||||||
auto projSpeed = maths::basic_collision(ball, nextPosition, direction, Elasticity, Smoothness, Threshold, Boost);
|
auto projSpeed = maths::basic_collision(ball, nextPosition, direction, Elasticity, Smoothness, Threshold, Boost);
|
||||||
if (projSpeed <= Threshold)
|
if (projSpeed <= Threshold)
|
||||||
{
|
{
|
||||||
if (projSpeed > 0.2)
|
if (projSpeed > 0.2f)
|
||||||
{
|
{
|
||||||
if (SoftHitSoundId)
|
if (SoftHitSoundId)
|
||||||
loader::play_sound(SoftHitSoundId);
|
loader::play_sound(SoftHitSoundId);
|
||||||
@@ -92,7 +92,7 @@ void TCollisionComponent::Collision(TBall* ball, vector_type* nextPosition, vect
|
|||||||
maths::basic_collision(ball, nextPosition, direction, Elasticity, Smoothness, 1000000000.0, 0.0);
|
maths::basic_collision(ball, nextPosition, direction, Elasticity, Smoothness, 1000000000.0, 0.0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
double projSpeed = maths::basic_collision(
|
auto projSpeed = maths::basic_collision(
|
||||||
ball,
|
ball,
|
||||||
nextPosition,
|
nextPosition,
|
||||||
direction,
|
direction,
|
||||||
@@ -102,7 +102,7 @@ void TCollisionComponent::Collision(TBall* ball, vector_type* nextPosition, vect
|
|||||||
Boost);
|
Boost);
|
||||||
if (projSpeed <= Threshold)
|
if (projSpeed <= Threshold)
|
||||||
{
|
{
|
||||||
if (projSpeed <= 0.2)
|
if (projSpeed <= 0.2f)
|
||||||
return;
|
return;
|
||||||
soundIndex = SoftHitSoundId;
|
soundIndex = SoftHitSoundId;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "TPinballComponent.h"
|
#include "TPinballComponent.h"
|
||||||
|
|
||||||
class objlist_class;
|
|
||||||
struct vector_type;
|
struct vector_type;
|
||||||
class TEdgeSegment;
|
class TEdgeSegment;
|
||||||
class TBall;
|
class TBall;
|
||||||
@@ -9,7 +8,7 @@ class TBall;
|
|||||||
class TCollisionComponent : public TPinballComponent
|
class TCollisionComponent : public TPinballComponent
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
objlist_class* EdgeList;
|
objlist_class<TEdgeSegment>* EdgeList;
|
||||||
float Elasticity;
|
float Elasticity;
|
||||||
float Smoothness;
|
float Smoothness;
|
||||||
float Boost;
|
float Boost;
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
TComponentGroup::TComponentGroup(TPinballTable* table, int groupIndex) : TPinballComponent(table, groupIndex, false)
|
TComponentGroup::TComponentGroup(TPinballTable* table, int groupIndex) : TPinballComponent(table, groupIndex, false)
|
||||||
{
|
{
|
||||||
List = new objlist_class(4, 4);
|
List = new objlist_class<TPinballComponent>(4, 4);
|
||||||
Timer = 0;
|
Timer = 0;
|
||||||
if (groupIndex > 0)
|
if (groupIndex > 0)
|
||||||
{
|
{
|
||||||
@@ -45,14 +45,14 @@ int TComponentGroup::Message(int code, float value)
|
|||||||
timer::kill(this->Timer);
|
timer::kill(this->Timer);
|
||||||
this->Timer = 0;
|
this->Timer = 0;
|
||||||
}
|
}
|
||||||
if (value > 0.0)
|
if (value > 0.0f)
|
||||||
this->Timer = timer::set(value, this, NotifyTimerExpired);
|
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 (int i = 0; i < List->GetCount(); i++)
|
||||||
{
|
{
|
||||||
static_cast<TPinballComponent*>(List->Get(i))->Message(code, value);
|
List->Get(i)->Message(code, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "TPinballComponent.h"
|
#include "TPinballComponent.h"
|
||||||
|
|
||||||
class objlist_class;
|
|
||||||
|
|
||||||
class TComponentGroup :
|
class TComponentGroup :
|
||||||
public TPinballComponent
|
public TPinballComponent
|
||||||
@@ -12,6 +11,6 @@ public:
|
|||||||
int Message(int code, float value) override;
|
int Message(int code, float value) override;
|
||||||
static void NotifyTimerExpired(int timerId, void* caller);
|
static void NotifyTimerExpired(int timerId, void* caller);
|
||||||
|
|
||||||
objlist_class* List;
|
objlist_class<TPinballComponent>* List;
|
||||||
int Timer;
|
int Timer;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ void TDemo::Collision(TBall* ball, vector_type* nextPosition, vector_type* direc
|
|||||||
ball->Position.Y = nextPosition->Y;
|
ball->Position.Y = nextPosition->Y;
|
||||||
ball->RayMaxDistance -= coef;
|
ball->RayMaxDistance -= coef;
|
||||||
|
|
||||||
switch (reinterpret_cast<int>(edge->WallValue))
|
switch (reinterpret_cast<size_t>(edge->WallValue))
|
||||||
{
|
{
|
||||||
case 1400:
|
case 1400:
|
||||||
if (!FlipLeftTimer && !FlipLeftFlag)
|
if (!FlipLeftTimer && !FlipLeftFlag)
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
|
|
||||||
TEdgeBox::TEdgeBox()
|
TEdgeBox::TEdgeBox()
|
||||||
{
|
{
|
||||||
EdgeList = new objlist_class(0, 4);
|
EdgeList = new objlist_class<TEdgeSegment>(0, 4);
|
||||||
FieldList = new objlist_class(0, 1);
|
FieldList = new objlist_class<field_effect_type>(0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEdgeBox::~TEdgeBox()
|
TEdgeBox::~TEdgeBox()
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
class objlist_class;
|
#include "objlist_class.h"
|
||||||
|
|
||||||
|
|
||||||
|
struct field_effect_type;
|
||||||
|
class TEdgeSegment;
|
||||||
|
|
||||||
class TEdgeBox
|
class TEdgeBox
|
||||||
{
|
{
|
||||||
@@ -7,7 +11,7 @@ public:
|
|||||||
TEdgeBox();
|
TEdgeBox();
|
||||||
~TEdgeBox();
|
~TEdgeBox();
|
||||||
|
|
||||||
objlist_class* EdgeList;
|
objlist_class<TEdgeSegment>* EdgeList;
|
||||||
objlist_class* FieldList;
|
objlist_class<field_effect_type>* FieldList;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -64,9 +64,9 @@ int TEdgeManager::TestGridBox(int x, int y, float* distPtr, TEdgeSegment** edgeD
|
|||||||
{
|
{
|
||||||
TEdgeBox* edgeBox = &BoxArray[x + y * MaxBoxX];
|
TEdgeBox* edgeBox = &BoxArray[x + y * MaxBoxX];
|
||||||
TEdgeSegment** edgePtr = &EdgeArray[edgeIndex];
|
TEdgeSegment** edgePtr = &EdgeArray[edgeIndex];
|
||||||
for (auto index = edgeBox->EdgeList->Count() - 1; index >= 0; --index)
|
for (auto index = edgeBox->EdgeList->GetCount() - 1; index >= 0; --index)
|
||||||
{
|
{
|
||||||
auto edge = static_cast<TEdgeSegment*>(edgeBox->EdgeList->Get(index));
|
auto edge = edgeBox->EdgeList->Get(index);
|
||||||
if (!edge->ProcessedFlag && *edge->ActiveFlag && (edge->CollisionGroup & ray->FieldFlag))
|
if (!edge->ProcessedFlag && *edge->ActiveFlag && (edge->CollisionGroup & ray->FieldFlag))
|
||||||
{
|
{
|
||||||
if (!ball->already_hit(edge))
|
if (!ball->already_hit(edge))
|
||||||
@@ -94,9 +94,9 @@ void TEdgeManager::FieldEffects(TBall* ball, vector_type* dstVec)
|
|||||||
TEdgeBox* edgeBox = &BoxArray[box_x(ball->Position.X) + box_y(ball->Position.Y) *
|
TEdgeBox* edgeBox = &BoxArray[box_x(ball->Position.X) + box_y(ball->Position.Y) *
|
||||||
MaxBoxX];
|
MaxBoxX];
|
||||||
|
|
||||||
for (int index = edgeBox->FieldList->Count() - 1; index >= 0; --index)
|
for (int index = edgeBox->FieldList->GetCount() - 1; index >= 0; --index)
|
||||||
{
|
{
|
||||||
auto field = static_cast<field_effect_type*>(edgeBox->FieldList->Get(index));
|
auto field = edgeBox->FieldList->Get(index);
|
||||||
if (*field->Flag2Ptr && ball->FieldFlag & field->Mask)
|
if (*field->Flag2Ptr && ball->FieldFlag & field->Mask)
|
||||||
{
|
{
|
||||||
if (field->CollisionComp->FieldEffect(ball, &vec))
|
if (field->CollisionComp->FieldEffect(ball, &vec))
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ void TEdgeSegment::port_draw()
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEdgeSegment* TEdgeSegment::install_wall(float* floatArr, TCollisionComponent* collComp, char* activeFlagPtr,
|
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{};
|
vector_type center{}, start{}, end{}, prevCenter{}, vec1{}, vec2{}, dstVec{};
|
||||||
TEdgeSegment* edge = nullptr;
|
TEdgeSegment* edge = nullptr;
|
||||||
@@ -87,15 +87,15 @@ TEdgeSegment* TEdgeSegment::install_wall(float* floatArr, TCollisionComponent* c
|
|||||||
|
|
||||||
center.X = centerX1;
|
center.X = centerX1;
|
||||||
center.Y = centerY1;
|
center.Y = centerY1;
|
||||||
if (offset != 0.0)
|
if (offset != 0.0f)
|
||||||
{
|
{
|
||||||
vec1.X = centerX1 - prevCenter.X;
|
vec1.X = centerX1 - prevCenter.X;
|
||||||
vec1.Y = center.Y - prevCenter.Y;
|
vec1.Y = center.Y - prevCenter.Y;
|
||||||
vec2.X = centerX2 - centerX1;
|
vec2.X = centerX2 - centerX1;
|
||||||
vec2.Y = centerY2 - center.Y;
|
vec2.Y = centerY2 - center.Y;
|
||||||
maths::cross(&vec1, &vec2, &dstVec);
|
maths::cross(&vec1, &vec2, &dstVec);
|
||||||
if (dstVec.Z > 0.0 && offset > 0.0 ||
|
if (dstVec.Z > 0.0f && offset > 0.0f ||
|
||||||
dstVec.Z < 0.0 && offset < 0.0)
|
dstVec.Z < 0.0f && offset < 0.0f)
|
||||||
{
|
{
|
||||||
float radius = offset * 1.001f;
|
float radius = offset * 1.001f;
|
||||||
auto circle = new TCircle(collComp, activeFlagPtr, collisionGroup, ¢er, radius);
|
auto circle = new TCircle(collComp, activeFlagPtr, collisionGroup, ¢er, radius);
|
||||||
|
|||||||
@@ -28,5 +28,5 @@ public:
|
|||||||
virtual float FindCollisionDistance(ray_type* ray) = 0;
|
virtual float FindCollisionDistance(ray_type* ray) = 0;
|
||||||
|
|
||||||
static TEdgeSegment* install_wall(float* floatArr, TCollisionComponent* collComp, char* activeFlagPtr,
|
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);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -10,7 +10,6 @@
|
|||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include "TLine.h"
|
#include "TLine.h"
|
||||||
#include "TPinballTable.h"
|
#include "TPinballTable.h"
|
||||||
#include "TZmapList.h"
|
|
||||||
|
|
||||||
TFlagSpinner::TFlagSpinner(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, false)
|
TFlagSpinner::TFlagSpinner(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, false)
|
||||||
{
|
{
|
||||||
@@ -19,7 +18,7 @@ TFlagSpinner::TFlagSpinner(TPinballTable* table, int groupIndex) : TCollisionCom
|
|||||||
|
|
||||||
Timer = 0;
|
Timer = 0;
|
||||||
loader::query_visual(groupIndex, 0, &visual);
|
loader::query_visual(groupIndex, 0, &visual);
|
||||||
end.X = *visual.FloatArr;
|
end.X = visual.FloatArr[0];
|
||||||
end.Y = visual.FloatArr[1];
|
end.Y = visual.FloatArr[1];
|
||||||
start.X = visual.FloatArr[2];
|
start.X = visual.FloatArr[2];
|
||||||
start.Y = visual.FloatArr[3];
|
start.Y = visual.FloatArr[3];
|
||||||
@@ -62,8 +61,8 @@ int TFlagSpinner::Message(int code, float value)
|
|||||||
Timer = 0;
|
Timer = 0;
|
||||||
}
|
}
|
||||||
BmpIndex = 0;
|
BmpIndex = 0;
|
||||||
auto bmp = static_cast<gdrv_bitmap8*>(ListBitmap->Get(0));
|
auto bmp = ListBitmap->Get(0);
|
||||||
auto zMap = static_cast<zmap_header_type*>(ListZMap->Get(0));
|
auto zMap = ListZMap->Get(0);
|
||||||
render::sprite_set(
|
render::sprite_set(
|
||||||
RenderSprite,
|
RenderSprite,
|
||||||
bmp,
|
bmp,
|
||||||
@@ -83,7 +82,7 @@ void TFlagSpinner::Collision(TBall* ball, vector_type* nextPosition, vector_type
|
|||||||
ball->not_again(edge);
|
ball->not_again(edge);
|
||||||
|
|
||||||
SpinDirection = 2 * (PrevCollider != edge) - 1;
|
SpinDirection = 2 * (PrevCollider != edge) - 1;
|
||||||
if (ball->Speed == 0.0)
|
if (ball->Speed == 0.0f)
|
||||||
Speed = MinSpeed;
|
Speed = MinSpeed;
|
||||||
else
|
else
|
||||||
Speed = ball->Speed * 20.0f;
|
Speed = ball->Speed * 20.0f;
|
||||||
@@ -109,7 +108,7 @@ void TFlagSpinner::NextFrame()
|
|||||||
{
|
{
|
||||||
BmpIndex += SpinDirection;
|
BmpIndex += SpinDirection;
|
||||||
int bmpIndex = BmpIndex;
|
int bmpIndex = BmpIndex;
|
||||||
int bmpCount = ListBitmap->Count();
|
int bmpCount = ListBitmap->GetCount();
|
||||||
if (bmpIndex >= bmpCount)
|
if (bmpIndex >= bmpCount)
|
||||||
BmpIndex = 0;
|
BmpIndex = 0;
|
||||||
else if (bmpIndex < 0)
|
else if (bmpIndex < 0)
|
||||||
@@ -124,8 +123,8 @@ void TFlagSpinner::NextFrame()
|
|||||||
control::handler(62, this);
|
control::handler(62, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto bmp = static_cast<gdrv_bitmap8*>(ListBitmap->Get(BmpIndex));
|
auto bmp = ListBitmap->Get(BmpIndex);
|
||||||
auto zMap = static_cast<zmap_header_type*>(ListZMap->Get(BmpIndex));
|
auto zMap = ListZMap->Get(BmpIndex);
|
||||||
render::sprite_set(
|
render::sprite_set(
|
||||||
RenderSprite,
|
RenderSprite,
|
||||||
bmp,
|
bmp,
|
||||||
|
|||||||
@@ -4,11 +4,11 @@
|
|||||||
|
|
||||||
#include "control.h"
|
#include "control.h"
|
||||||
#include "loader.h"
|
#include "loader.h"
|
||||||
|
#include "objlist_class.h"
|
||||||
#include "pb.h"
|
#include "pb.h"
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
#include "TFlipperEdge.h"
|
#include "TFlipperEdge.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include "TZmapList.h"
|
|
||||||
|
|
||||||
TFlipper::TFlipper(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, false)
|
TFlipper::TFlipper(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, false)
|
||||||
{
|
{
|
||||||
@@ -21,12 +21,16 @@ TFlipper::TFlipper(TPinballTable* table, int groupIndex) : TCollisionComponent(t
|
|||||||
Timer = 0;
|
Timer = 0;
|
||||||
Smoothness = visual.Smoothness;
|
Smoothness = visual.Smoothness;
|
||||||
|
|
||||||
auto floatArr = loader::query_float_attribute(groupIndex, 0, 803);
|
auto collMult = *loader::query_float_attribute(groupIndex, 0, 803);
|
||||||
auto floatArr2 = loader::query_float_attribute(groupIndex, 0, 805);
|
auto retractTime = *loader::query_float_attribute(groupIndex, 0, 805);
|
||||||
auto floatArr3 = loader::query_float_attribute(groupIndex, 0, 804);
|
auto extendTime = *loader::query_float_attribute(groupIndex, 0, 804);
|
||||||
auto collMult = *floatArr;
|
|
||||||
auto bmpCoef2 = *floatArr2;
|
/*Full tilt hack: different flipper speed*/
|
||||||
auto bmpCoef1 = *floatArr3;
|
if (pb::FullTiltMode)
|
||||||
|
{
|
||||||
|
retractTime = 0.08f;
|
||||||
|
extendTime = 0.04f;
|
||||||
|
}
|
||||||
auto vecT2 = reinterpret_cast<vector_type*>(loader::query_float_attribute(groupIndex, 0, 802));
|
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 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));
|
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,
|
origin,
|
||||||
vecT1,
|
vecT1,
|
||||||
vecT2,
|
vecT2,
|
||||||
bmpCoef1,
|
extendTime,
|
||||||
bmpCoef2,
|
retractTime,
|
||||||
collMult,
|
collMult,
|
||||||
Elasticity,
|
Elasticity,
|
||||||
Smoothness);
|
Smoothness);
|
||||||
@@ -47,8 +51,8 @@ TFlipper::TFlipper(TPinballTable* table, int groupIndex) : TCollisionComponent(t
|
|||||||
FlipperEdge = flipperEdge;
|
FlipperEdge = flipperEdge;
|
||||||
if (flipperEdge)
|
if (flipperEdge)
|
||||||
{
|
{
|
||||||
BmpCoef1 = flipperEdge->BmpCoef1 / static_cast<float>(ListBitmap->Count() - 1);
|
ExtendAnimationFrameTime = flipperEdge->ExtendTime / static_cast<float>(ListBitmap->GetCount() - 1);
|
||||||
BmpCoef2 = flipperEdge->BmpCoef2 / static_cast<float>(ListBitmap->Count() - 1);
|
RetractAnimationFrameTime = flipperEdge->RetractTime / static_cast<float>(ListBitmap->GetCount() - 1);
|
||||||
}
|
}
|
||||||
BmpIndex = 0;
|
BmpIndex = 0;
|
||||||
InputTime = 0.0;
|
InputTime = 0.0;
|
||||||
@@ -64,46 +68,44 @@ 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;
|
float timerTime;
|
||||||
int soundIndex = 0, code2 = code;
|
int command = code;
|
||||||
if (code == 1)
|
if (code == 1)
|
||||||
{
|
{
|
||||||
control::handler(1, this);
|
control::handler(1, this);
|
||||||
TimerTime = BmpCoef1;
|
TimerTime = ExtendAnimationFrameTime;
|
||||||
soundIndex = HardHitSoundId;
|
loader::play_sound(HardHitSoundId);
|
||||||
}
|
}
|
||||||
else if (code == 2)
|
else if (code == 2)
|
||||||
{
|
{
|
||||||
TimerTime = BmpCoef2;
|
TimerTime = RetractAnimationFrameTime;
|
||||||
soundIndex = SoftHitSoundId;
|
loader::play_sound(SoftHitSoundId);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
code2 = 2;
|
// Retract for all non-input messages
|
||||||
TimerTime = BmpCoef2;
|
command = 2;
|
||||||
|
TimerTime = RetractAnimationFrameTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (soundIndex)
|
|
||||||
loader::play_sound(soundIndex);
|
|
||||||
if (Timer)
|
|
||||||
{
|
|
||||||
timer::kill(Timer);
|
|
||||||
Timer = 0;
|
|
||||||
}
|
|
||||||
if (MessageField)
|
if (MessageField)
|
||||||
{
|
{
|
||||||
auto v10 = value - FlipperEdge->InputTime;
|
// Message arrived before animation is finished
|
||||||
timerTime = v10 - floor(v10 / TimerTime) * TimerTime;
|
auto inputDt = value - FlipperEdge->InputTime;
|
||||||
if (timerTime < 0.0)
|
timerTime = inputDt - floor(inputDt / TimerTime) * TimerTime;
|
||||||
|
if (timerTime < 0.0f)
|
||||||
timerTime = 0.0;
|
timerTime = 0.0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
timerTime = TimerTime;
|
timerTime = TimerTime;
|
||||||
}
|
}
|
||||||
MessageField = code2;
|
|
||||||
|
MessageField = command;
|
||||||
InputTime = value;
|
InputTime = value;
|
||||||
|
if (Timer)
|
||||||
|
timer::kill(Timer);
|
||||||
Timer = timer::set(timerTime, this, TimerExpired);
|
Timer = timer::set(timerTime, this, TimerExpired);
|
||||||
FlipperEdge->SetMotion(code2, value);
|
FlipperEdge->SetMotion(command, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (code == 1020 || code == 1024)
|
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)
|
void TFlipper::TimerExpired(int timerId, void* caller)
|
||||||
{
|
{
|
||||||
auto flip = static_cast<TFlipper*>(caller);
|
auto flip = static_cast<TFlipper*>(caller);
|
||||||
int timer; // eax
|
int bmpCountSub1 = flip->ListBitmap->GetCount() - 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;
|
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)
|
if (flip->MessageField == 1)
|
||||||
{
|
{
|
||||||
flip->BmpIndex += bmpIndexAdvance;
|
flip->BmpIndex = newBmpIndex;
|
||||||
int countSub1 = flip->ListBitmap->Count() - 1;
|
if (flip->BmpIndex >= bmpCountSub1)
|
||||||
if (flip->BmpIndex >= countSub1)
|
|
||||||
{
|
{
|
||||||
flip->BmpIndex = countSub1;
|
flip->BmpIndex = bmpCountSub1;
|
||||||
bmpIndexOutOfBounds = true;
|
bmpIndexOutOfBounds = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (flip->MessageField == 2)
|
if (flip->MessageField == 2)
|
||||||
{
|
{
|
||||||
flip->BmpIndex -= bmpIndexAdvance;
|
flip->BmpIndex = bmpCountSub1 - newBmpIndex;
|
||||||
timer = 0;
|
|
||||||
if (flip->BmpIndex <= 0)
|
if (flip->BmpIndex <= 0)
|
||||||
{
|
{
|
||||||
flip->BmpIndex = 0;
|
flip->BmpIndex = 0;
|
||||||
bmpIndexOutOfBounds = true;
|
bmpIndexOutOfBounds = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
timer = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bmpIndexOutOfBounds)
|
if (bmpIndexOutOfBounds)
|
||||||
|
{
|
||||||
flip->MessageField = 0;
|
flip->MessageField = 0;
|
||||||
|
flip->Timer = 0;
|
||||||
|
}
|
||||||
else
|
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 bmp = flip->ListBitmap->Get(flip->BmpIndex);
|
||||||
auto zMap = static_cast<zmap_header_type*>(flip->ListZMap->Get(flip->BmpIndex));
|
auto zMap = flip->ListZMap->Get(flip->BmpIndex);
|
||||||
render::sprite_set(
|
render::sprite_set(
|
||||||
flip->RenderSprite,
|
flip->RenderSprite,
|
||||||
bmp,
|
bmp,
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ public:
|
|||||||
int BmpIndex;
|
int BmpIndex;
|
||||||
TFlipperEdge* FlipperEdge;
|
TFlipperEdge* FlipperEdge;
|
||||||
int Timer;
|
int Timer;
|
||||||
float BmpCoef1;
|
float ExtendAnimationFrameTime;
|
||||||
float BmpCoef2;
|
float RetractAnimationFrameTime;
|
||||||
float TimerTime;
|
float TimerTime;
|
||||||
float InputTime;
|
float InputTime;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -12,15 +12,15 @@ line_type TFlipperEdge::lineA, TFlipperEdge::lineB;
|
|||||||
circle_type TFlipperEdge::circlebase, TFlipperEdge::circleT1;
|
circle_type TFlipperEdge::circlebase, TFlipperEdge::circleT1;
|
||||||
|
|
||||||
TFlipperEdge::TFlipperEdge(TCollisionComponent* collComp, char* activeFlag, unsigned int collisionGroup, TPinballTable* table,
|
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)
|
float collMult, float elasticity, float smoothness): TEdgeSegment(collComp, activeFlag, collisionGroup)
|
||||||
{
|
{
|
||||||
vector_type crossProd{}, vecDir1{}, vecDir2{};
|
vector_type crossProd{}, vecDir1{}, vecDir2{};
|
||||||
|
|
||||||
Elasticity = elasticity;
|
Elasticity = elasticity;
|
||||||
Smoothness = smoothness;
|
Smoothness = smoothness;
|
||||||
BmpCoef1 = bmpCoef1;
|
ExtendTime = extendTime;
|
||||||
BmpCoef2 = bmpCoef2;
|
RetractTime = retractTime;
|
||||||
CollisionMult = collMult;
|
CollisionMult = collMult;
|
||||||
|
|
||||||
T1Src = *vecT1;
|
T1Src = *vecT1;
|
||||||
@@ -48,7 +48,7 @@ TFlipperEdge::TFlipperEdge(TCollisionComponent* collComp, char* activeFlag, unsi
|
|||||||
|
|
||||||
AngleMax = acos(maths::DotProduct(&vecDir1, &vecDir2));
|
AngleMax = acos(maths::DotProduct(&vecDir1, &vecDir2));
|
||||||
maths::cross(&vecDir1, &vecDir2, &crossProd);
|
maths::cross(&vecDir1, &vecDir2, &crossProd);
|
||||||
if (crossProd.Z < 0.0)
|
if (crossProd.Z < 0.0f)
|
||||||
AngleMax = -AngleMax;
|
AngleMax = -AngleMax;
|
||||||
FlipperFlag = 0;
|
FlipperFlag = 0;
|
||||||
Angle1 = 0.0;
|
Angle1 = 0.0;
|
||||||
@@ -67,7 +67,7 @@ TFlipperEdge::TFlipperEdge(TCollisionComponent* collComp, char* activeFlag, unsi
|
|||||||
B2Src.X = dirY1 * CircleT1Radius + vecT1->X;
|
B2Src.X = dirY1 * CircleT1Radius + vecT1->X;
|
||||||
B2Src.Y = dirX1 * CircleT1Radius + vecT1->Y;
|
B2Src.Y = dirX1 * CircleT1Radius + vecT1->Y;
|
||||||
|
|
||||||
if (AngleMax < 0.0)
|
if (AngleMax < 0.0f)
|
||||||
{
|
{
|
||||||
maths::vswap(&A1Src, &B1Src);
|
maths::vswap(&A1Src, &B1Src);
|
||||||
maths::vswap(&A2Src, &B2Src);
|
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;
|
auto distance1 = sqrt(dy * dy + dx * dx) + table->CollisionCompOffset + vecT1->Z;
|
||||||
DistanceDivSq = distance1 * distance1;
|
DistanceDivSq = distance1 * distance1;
|
||||||
|
|
||||||
float bmpCoef = min(BmpCoef1, BmpCoef2);
|
float minMoveTime = min(ExtendTime, RetractTime);
|
||||||
auto distance = maths::Distance(vecT1, vecT2);
|
auto distance = maths::Distance(vecT1, vecT2);
|
||||||
CollisionTimeAdvance = bmpCoef / (distance / CircleT1Radius + distance / CircleT1Radius);
|
CollisionTimeAdvance = minMoveTime / (distance / CircleT1Radius + distance / CircleT1Radius);
|
||||||
|
|
||||||
TFlipperEdge::place_in_grid();
|
TFlipperEdge::place_in_grid();
|
||||||
EdgeCollisionFlag = 0;
|
EdgeCollisionFlag = 0;
|
||||||
@@ -122,7 +122,7 @@ float TFlipperEdge::FindCollisionDistance(ray_type* ray)
|
|||||||
srcRay.MaxDistance = ogRay->MaxDistance;
|
srcRay.MaxDistance = ogRay->MaxDistance;
|
||||||
srcRay.Origin = ogRay->Origin;
|
srcRay.Origin = ogRay->Origin;
|
||||||
auto distance = maths::distance_to_flipper(&srcRay, &dstRay);
|
auto distance = maths::distance_to_flipper(&srcRay, &dstRay);
|
||||||
if (distance == 0.0)
|
if (distance == 0.0f)
|
||||||
{
|
{
|
||||||
NextBallPosition = dstRay.Origin;
|
NextBallPosition = dstRay.Origin;
|
||||||
NextBallPosition.X -= srcRay.Direction.X * 1e-05f;
|
NextBallPosition.X -= srcRay.Direction.X * 1e-05f;
|
||||||
@@ -167,14 +167,14 @@ float TFlipperEdge::FindCollisionDistance(ray_type* ray)
|
|||||||
srcRay.Origin.X = ogRay->Origin.X - srcRay.Direction.X * 5.0f;
|
srcRay.Origin.X = ogRay->Origin.X - srcRay.Direction.X * 5.0f;
|
||||||
srcRay.Origin.Y = ogRay->Origin.Y - srcRay.Direction.Y * 5.0f;
|
srcRay.Origin.Y = ogRay->Origin.Y - srcRay.Direction.Y * 5.0f;
|
||||||
srcRay.MaxDistance = ogRay->MaxDistance + 10.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.X = RotOrigin.X - ogRay->Origin.X;
|
||||||
srcRay.Direction.Y = RotOrigin.Y - ogRay->Origin.Y;
|
srcRay.Direction.Y = RotOrigin.Y - ogRay->Origin.Y;
|
||||||
maths::normalize_2d(&srcRay.Direction);
|
maths::normalize_2d(&srcRay.Direction);
|
||||||
srcRay.Origin.X = ogRay->Origin.X - srcRay.Direction.X * 5.0f;
|
srcRay.Origin.X = ogRay->Origin.X - srcRay.Direction.X * 5.0f;
|
||||||
srcRay.Origin.Y = ogRay->Origin.Y - srcRay.Direction.Y * 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;
|
return 1e+09;
|
||||||
}
|
}
|
||||||
@@ -221,7 +221,7 @@ float TFlipperEdge::FindCollisionDistance(ray_type* ray)
|
|||||||
srcRay.Origin.X = posX - srcRay.Direction.X * 5.0f;
|
srcRay.Origin.X = posX - srcRay.Direction.X * 5.0f;
|
||||||
srcRay.Origin.Y = posY - srcRay.Direction.Y * 5.0f;
|
srcRay.Origin.Y = posY - srcRay.Direction.Y * 5.0f;
|
||||||
srcRay.MaxDistance = ogRay->MaxDistance + 10.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.X = posX;
|
||||||
NextBallPosition.Y = posY;
|
NextBallPosition.Y = posY;
|
||||||
@@ -252,7 +252,7 @@ float TFlipperEdge::FindCollisionDistance(ray_type* ray)
|
|||||||
srcRay.MaxDistance = ogRay->MaxDistance + 10.0f;
|
srcRay.MaxDistance = ogRay->MaxDistance + 10.0f;
|
||||||
auto distance = maths::distance_to_flipper(&srcRay, &dstRay);
|
auto distance = maths::distance_to_flipper(&srcRay, &dstRay);
|
||||||
CollisionDirection = dstRay.Direction;
|
CollisionDirection = dstRay.Direction;
|
||||||
if (distance >= 1e+09)
|
if (distance >= 1e+09f)
|
||||||
{
|
{
|
||||||
return 1e+09;
|
return 1e+09;
|
||||||
}
|
}
|
||||||
@@ -267,7 +267,7 @@ float TFlipperEdge::FindCollisionDistance(ray_type* ray)
|
|||||||
srcRay.Origin = ogRay->Origin;
|
srcRay.Origin = ogRay->Origin;
|
||||||
srcRay.MaxDistance = rayMaxDistance;
|
srcRay.MaxDistance = rayMaxDistance;
|
||||||
auto distance = maths::distance_to_flipper(&srcRay, &dstRay);
|
auto distance = maths::distance_to_flipper(&srcRay, &dstRay);
|
||||||
if (distance < 1e+09)
|
if (distance < 1e+09f)
|
||||||
{
|
{
|
||||||
NextBallPosition = dstRay.Origin;
|
NextBallPosition = dstRay.Origin;
|
||||||
NextBallPosition.X -= srcRay.Direction.X * 1e-05f;
|
NextBallPosition.X -= srcRay.Direction.X * 1e-05f;
|
||||||
@@ -276,11 +276,11 @@ float TFlipperEdge::FindCollisionDistance(ray_type* ray)
|
|||||||
if (FlipperFlag == 2)
|
if (FlipperFlag == 2)
|
||||||
{
|
{
|
||||||
linePtr = &lineB.PerpendicularL;
|
linePtr = &lineB.PerpendicularL;
|
||||||
CollisionFlag1 = AngleMax <= 0.0;
|
CollisionFlag1 = AngleMax <= 0.0f;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CollisionFlag1 = AngleMax > 0.0;
|
CollisionFlag1 = AngleMax > 0.0f;
|
||||||
linePtr = &lineA.PerpendicularL;
|
linePtr = &lineA.PerpendicularL;
|
||||||
}
|
}
|
||||||
CollisionLinePerp = *linePtr;
|
CollisionLinePerp = *linePtr;
|
||||||
@@ -310,12 +310,12 @@ void TFlipperEdge::EdgeCollision(TBall* ball, float coef)
|
|||||||
float dx = NextBallPosition.X - RotOrigin.X;
|
float dx = NextBallPosition.X - RotOrigin.X;
|
||||||
float dy = NextBallPosition.Y - RotOrigin.Y;
|
float dy = NextBallPosition.Y - RotOrigin.Y;
|
||||||
float distance = dy * dy + dx * dx;
|
float distance = dy * dy + dx * dx;
|
||||||
if (circlebase.RadiusSq * 1.01 < distance)
|
if (circlebase.RadiusSq * 1.01f < distance)
|
||||||
{
|
{
|
||||||
float v11;
|
float v11;
|
||||||
float v20 = sqrt(distance / DistanceDivSq) * (fabs(AngleMax) / AngleMult);
|
float v20 = sqrt(distance / DistanceDivSq) * (fabs(AngleMax) / AngleMult);
|
||||||
float dot1 = maths::DotProduct(&CollisionLinePerp, &CollisionDirection);
|
float dot1 = maths::DotProduct(&CollisionLinePerp, &CollisionDirection);
|
||||||
if (dot1 >= 0.0)
|
if (dot1 >= 0.0f)
|
||||||
v11 = dot1 * v20;
|
v11 = dot1 * v20;
|
||||||
else
|
else
|
||||||
v11 = 0.0;
|
v11 = 0.0;
|
||||||
@@ -323,7 +323,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(
|
maths::basic_collision(
|
||||||
ball,
|
ball,
|
||||||
&NextBallPosition,
|
&NextBallPosition,
|
||||||
@@ -339,7 +339,7 @@ void TFlipperEdge::EdgeCollision(TBall* ball, float coef)
|
|||||||
float dx = NextBallPosition.X - RotOrigin.X;
|
float dx = NextBallPosition.X - RotOrigin.X;
|
||||||
float dy = NextBallPosition.Y - RotOrigin.Y;
|
float dy = NextBallPosition.Y - RotOrigin.Y;
|
||||||
float distance = dy * dy + dx * dx;
|
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;
|
elasticity = (1.0f - sqrt(distance / DistanceDivSq)) * Elasticity;
|
||||||
else
|
else
|
||||||
elasticity = Elasticity;
|
elasticity = Elasticity;
|
||||||
@@ -420,10 +420,10 @@ float TFlipperEdge::flipper_angle(float timeNow)
|
|||||||
if (!FlipperFlag)
|
if (!FlipperFlag)
|
||||||
return Angle1;
|
return Angle1;
|
||||||
float angle = (Angle1 - Angle2) / AngleMax * AngleMult;
|
float angle = (Angle1 - Angle2) / AngleMax * AngleMult;
|
||||||
if (angle < 0.0)
|
if (angle < 0.0f)
|
||||||
angle = -angle;
|
angle = -angle;
|
||||||
|
|
||||||
if (angle >= 0.0000001)
|
if (angle >= 0.0000001f)
|
||||||
angle = (timeNow - InputTime) / angle;
|
angle = (timeNow - InputTime) / angle;
|
||||||
else
|
else
|
||||||
angle = 1.0;
|
angle = 1.0;
|
||||||
@@ -439,23 +439,23 @@ int TFlipperEdge::is_ball_inside(float x, float y)
|
|||||||
vector_type testPoint{};
|
vector_type testPoint{};
|
||||||
float dx = RotOrigin.X - x;
|
float dx = RotOrigin.X - x;
|
||||||
float dy = RotOrigin.Y - y;
|
float dy = RotOrigin.Y - y;
|
||||||
if ((A2.X - A1.X) * (y - A1.Y) - (A2.Y - A1.Y) * (x - A1.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.0 &&
|
(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.0 &&
|
(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.0 ||
|
(A1.X - B2.X) * (y - B2.Y) - (A1.Y - B2.Y) * (x - B2.X) >= 0.0f ||
|
||||||
dy * dy + dx * dx <= CirclebaseRadiusSq ||
|
dy * dy + dx * dx <= CirclebaseRadiusSq ||
|
||||||
(T1.Y - y) * (T1.Y - y) + (T1.X - x) * (T1.X - x) < CircleT1RadiusSq)
|
(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)
|
if (FlipperFlag == 1)
|
||||||
testPoint = AngleMax < 0.0 ? B1 : B2;
|
testPoint = AngleMax < 0.0f ? B1 : B2;
|
||||||
else if (FlipperFlag == 2)
|
else if (FlipperFlag == 2)
|
||||||
testPoint = AngleMax < 0.0 ? A2 : A1;
|
testPoint = AngleMax < 0.0f ? A2 : A1;
|
||||||
else
|
else
|
||||||
testPoint = T1;
|
testPoint = T1;
|
||||||
|
|
||||||
if (((y - testPoint.Y) * (RotOrigin.X - testPoint.X) -
|
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 4;
|
||||||
return 5;
|
return 5;
|
||||||
}
|
}
|
||||||
@@ -469,12 +469,12 @@ void TFlipperEdge::SetMotion(int code, float value)
|
|||||||
case 1:
|
case 1:
|
||||||
Angle2 = flipper_angle(value);
|
Angle2 = flipper_angle(value);
|
||||||
Angle1 = AngleMax;
|
Angle1 = AngleMax;
|
||||||
AngleMult = BmpCoef1;
|
AngleMult = ExtendTime;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
Angle2 = flipper_angle(value);
|
Angle2 = flipper_angle(value);
|
||||||
Angle1 = 0.0;
|
Angle1 = 0.0;
|
||||||
AngleMult = BmpCoef2;
|
AngleMult = RetractTime;
|
||||||
break;
|
break;
|
||||||
case 1024:
|
case 1024:
|
||||||
FlipperFlag = 0;
|
FlipperFlag = 0;
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ class TFlipperEdge : public TEdgeSegment
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TFlipperEdge(TCollisionComponent* collComp, char* activeFlag, unsigned int collisionGroup, TPinballTable* table,
|
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);
|
float elasticity, float smoothness);
|
||||||
void port_draw() override;
|
void port_draw() override;
|
||||||
float FindCollisionDistance(ray_type* ray) override;
|
float FindCollisionDistance(ray_type* ray) override;
|
||||||
@@ -50,8 +50,8 @@ public:
|
|||||||
float InputTime;
|
float InputTime;
|
||||||
float AngleStopTime;
|
float AngleStopTime;
|
||||||
float AngleMult;
|
float AngleMult;
|
||||||
float BmpCoef1;
|
float ExtendTime;
|
||||||
float BmpCoef2;
|
float RetractTime;
|
||||||
vector_type NextBallPosition;
|
vector_type NextBallPosition;
|
||||||
|
|
||||||
static float flipper_sin_angle, flipper_cos_angle;
|
static float flipper_sin_angle, flipper_cos_angle;
|
||||||
|
|||||||
@@ -4,8 +4,8 @@
|
|||||||
|
|
||||||
#include "control.h"
|
#include "control.h"
|
||||||
#include "loader.h"
|
#include "loader.h"
|
||||||
|
#include "objlist_class.h"
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
#include "TZmapList.h"
|
|
||||||
|
|
||||||
TGate::TGate(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true)
|
TGate::TGate(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true)
|
||||||
{
|
{
|
||||||
@@ -15,7 +15,7 @@ TGate::TGate(TPinballTable* table, int groupIndex) : TCollisionComponent(table,
|
|||||||
SoundIndex4 = visual.SoundIndex4;
|
SoundIndex4 = visual.SoundIndex4;
|
||||||
SoundIndex3 = visual.SoundIndex3;
|
SoundIndex3 = visual.SoundIndex3;
|
||||||
ActiveFlag = 1;
|
ActiveFlag = 1;
|
||||||
render::sprite_set_bitmap(RenderSprite, static_cast<gdrv_bitmap8*>(ListBitmap->Get(0)));
|
render::sprite_set_bitmap(RenderSprite, ListBitmap->Get(0));
|
||||||
control::handler(1024, this);
|
control::handler(1024, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,7 +32,7 @@ int TGate::Message(int code, float value)
|
|||||||
else if (code == 54 || code == 1024)
|
else if (code == 54 || code == 1024)
|
||||||
{
|
{
|
||||||
ActiveFlag = 1;
|
ActiveFlag = 1;
|
||||||
render::sprite_set_bitmap(RenderSprite, static_cast<gdrv_bitmap8*>(ListBitmap->Get(0)));
|
render::sprite_set_bitmap(RenderSprite, ListBitmap->Get(0));
|
||||||
if (code == 54)
|
if (code == 54)
|
||||||
loader::play_sound(SoundIndex4);
|
loader::play_sound(SoundIndex4);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include "control.h"
|
#include "control.h"
|
||||||
#include "loader.h"
|
#include "loader.h"
|
||||||
#include "objlist_class.h"
|
#include "objlist_class.h"
|
||||||
|
#include "pb.h"
|
||||||
#include "TBall.h"
|
#include "TBall.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include "TPinballTable.h"
|
#include "TPinballTable.h"
|
||||||
@@ -19,26 +20,19 @@ THole::THole(TPinballTable* table, int groupIndex) : TCollisionComponent(table,
|
|||||||
MessageField = 0;
|
MessageField = 0;
|
||||||
Timer = 0;
|
Timer = 0;
|
||||||
BallCapturedFlag = 0;
|
BallCapturedFlag = 0;
|
||||||
auto floatArr1 = loader::query_float_attribute(groupIndex, 0, 407);
|
Unknown3 = loader::query_float_attribute(groupIndex, 0, 407, 0.25f);
|
||||||
if (floatArr1)
|
GravityMult = loader::query_float_attribute(groupIndex, 0, 701, 0.2f);
|
||||||
Unknown3 = *floatArr1;
|
|
||||||
else
|
|
||||||
Unknown3 = 0.25;
|
|
||||||
auto floatArr2 = loader::query_float_attribute(groupIndex, 0, 701);
|
|
||||||
if (floatArr2)
|
|
||||||
GravityMult = *floatArr2;
|
|
||||||
else
|
|
||||||
GravityMult = 0.5;
|
|
||||||
GravityPull = *loader::query_float_attribute(groupIndex, 0, 305);
|
GravityPull = *loader::query_float_attribute(groupIndex, 0, 305);
|
||||||
|
|
||||||
loader::query_visual(groupIndex, 0, &visual);
|
loader::query_visual(groupIndex, 0, &visual);
|
||||||
Circle.Center.X = visual.FloatArr[0];
|
Circle.Center.X = visual.FloatArr[0];
|
||||||
Circle.Center.Y = visual.FloatArr[1];
|
Circle.Center.Y = visual.FloatArr[1];
|
||||||
Circle.RadiusSq = *loader::query_float_attribute(groupIndex, 0, 306) * visual.FloatArr[2];
|
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;
|
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);
|
Circle.RadiusSq);
|
||||||
if (tCircle)
|
if (tCircle)
|
||||||
{
|
{
|
||||||
@@ -49,6 +43,10 @@ THole::THole(TPinballTable* table, int groupIndex) : TCollisionComponent(table,
|
|||||||
ZSetValue = loader::query_float_attribute(groupIndex, 0, 408)[2];
|
ZSetValue = loader::query_float_attribute(groupIndex, 0, 408)[2];
|
||||||
FieldFlag = static_cast<int>(floor(*loader::query_float_attribute(groupIndex, 0, 1304)));
|
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 = visual.FloatArr[2] * visual.FloatArr[2];
|
||||||
circle.RadiusSq = Circle.RadiusSq;
|
circle.RadiusSq = Circle.RadiusSq;
|
||||||
circle.Center.X = Circle.Center.X;
|
circle.Center.X = Circle.Center.X;
|
||||||
@@ -84,7 +82,11 @@ void THole::Collision(TBall* ball, vector_type* nextPosition, vector_type* direc
|
|||||||
ball->Position.X = Circle.Center.X;
|
ball->Position.X = Circle.Center.X;
|
||||||
ball->Position.Y = Circle.Center.Y;
|
ball->Position.Y = Circle.Center.Y;
|
||||||
ball->Acceleration.Z = 0.0;
|
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)
|
if (!PinballTable->TiltLockFlag)
|
||||||
{
|
{
|
||||||
loader::play_sound(HardHitSoundId);
|
loader::play_sound(HardHitSoundId);
|
||||||
|
|||||||
@@ -5,10 +5,10 @@
|
|||||||
#include "control.h"
|
#include "control.h"
|
||||||
#include "loader.h"
|
#include "loader.h"
|
||||||
#include "maths.h"
|
#include "maths.h"
|
||||||
|
#include "objlist_class.h"
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include "TPinballTable.h"
|
#include "TPinballTable.h"
|
||||||
#include "TZmapList.h"
|
|
||||||
|
|
||||||
TKickback::TKickback(TPinballTable* table, int groupIndex): TCollisionComponent(table, groupIndex, true)
|
TKickback::TKickback(TPinballTable* table, int groupIndex): TCollisionComponent(table, groupIndex, true)
|
||||||
{
|
{
|
||||||
@@ -66,8 +66,8 @@ void TKickback::TimerExpired(int timerId, void* caller)
|
|||||||
loader::play_sound(kick->HardHitSoundId);
|
loader::play_sound(kick->HardHitSoundId);
|
||||||
if (kick->ListBitmap)
|
if (kick->ListBitmap)
|
||||||
{
|
{
|
||||||
auto bmp = static_cast<gdrv_bitmap8*>(kick->ListBitmap->Get(1));
|
auto bmp = kick->ListBitmap->Get(1);
|
||||||
auto zMap = static_cast<zmap_header_type*>(kick->ListZMap->Get(1));
|
auto zMap = kick->ListZMap->Get(1);
|
||||||
render::sprite_set(
|
render::sprite_set(
|
||||||
kick->RenderSprite,
|
kick->RenderSprite,
|
||||||
bmp,
|
bmp,
|
||||||
@@ -80,8 +80,8 @@ void TKickback::TimerExpired(int timerId, void* caller)
|
|||||||
{
|
{
|
||||||
if (kick->ListBitmap)
|
if (kick->ListBitmap)
|
||||||
{
|
{
|
||||||
auto bmp = static_cast<gdrv_bitmap8*>(kick->ListBitmap->Get(0));
|
auto bmp = kick->ListBitmap->Get(0);
|
||||||
auto zMap = static_cast<zmap_header_type*>(kick->ListZMap->Get(0));
|
auto zMap = kick->ListZMap->Get(0);
|
||||||
render::sprite_set(
|
render::sprite_set(
|
||||||
kick->RenderSprite,
|
kick->RenderSprite,
|
||||||
bmp,
|
bmp,
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include "control.h"
|
#include "control.h"
|
||||||
#include "loader.h"
|
#include "loader.h"
|
||||||
#include "objlist_class.h"
|
#include "objlist_class.h"
|
||||||
|
#include "pb.h"
|
||||||
#include "TBall.h"
|
#include "TBall.h"
|
||||||
#include "TCircle.h"
|
#include "TCircle.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
@@ -30,10 +31,10 @@ TKickout::TKickout(TPinballTable* table, int groupIndex, bool someFlag): TCollis
|
|||||||
SoftHitSoundId = visual.SoftHitSoundId;
|
SoftHitSoundId = visual.SoftHitSoundId;
|
||||||
HardHitSoundId = visual.Kicker.HardHitSoundId;
|
HardHitSoundId = visual.Kicker.HardHitSoundId;
|
||||||
|
|
||||||
Circle.Center.X = *visual.FloatArr;
|
Circle.Center.X = visual.FloatArr[0];
|
||||||
Circle.Center.Y = visual.FloatArr[1];
|
Circle.Center.Y = visual.FloatArr[1];
|
||||||
Circle.RadiusSq = *loader::query_float_attribute(groupIndex, 0, 306) * visual.FloatArr[2];
|
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;
|
Circle.RadiusSq = 0.001f;
|
||||||
auto tCircle = new TCircle(this, &ActiveFlag, visual.CollisionGroup,
|
auto tCircle = new TCircle(this, &ActiveFlag, visual.CollisionGroup,
|
||||||
reinterpret_cast<vector_type*>(visual.FloatArr), Circle.RadiusSq);
|
reinterpret_cast<vector_type*>(visual.FloatArr), Circle.RadiusSq);
|
||||||
@@ -44,7 +45,8 @@ TKickout::TKickout(TPinballTable* table, int groupIndex, bool someFlag): TCollis
|
|||||||
}
|
}
|
||||||
|
|
||||||
Circle.RadiusSq = visual.FloatArr[2] * visual.FloatArr[2];
|
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;
|
ThrowSpeedMult2 = visual.Kicker.ThrowBallMult * 0.01f;
|
||||||
BallAcceleration = visual.Kicker.ThrowBallAcceleration;
|
BallAcceleration = visual.Kicker.ThrowBallAcceleration;
|
||||||
ThrowAngleMult = visual.Kicker.ThrowBallAngleMult;
|
ThrowAngleMult = visual.Kicker.ThrowBallAngleMult;
|
||||||
@@ -67,7 +69,7 @@ int TKickout::Message(int code, float value)
|
|||||||
case 55:
|
case 55:
|
||||||
if (KickFlag1)
|
if (KickFlag1)
|
||||||
{
|
{
|
||||||
if (value < 0.0)
|
if (value < 0.0f)
|
||||||
value = TimerTime1;
|
value = TimerTime1;
|
||||||
Timer = timer::set(value, this, TimerExpired);
|
Timer = timer::set(value, this, TimerExpired);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,10 +4,10 @@
|
|||||||
|
|
||||||
#include "control.h"
|
#include "control.h"
|
||||||
#include "loader.h"
|
#include "loader.h"
|
||||||
|
#include "objlist_class.h"
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include "TPinballTable.h"
|
#include "TPinballTable.h"
|
||||||
#include "TZmapList.h"
|
|
||||||
|
|
||||||
TLight::TLight(TPinballTable* table, int groupIndex) : TPinballComponent(table, groupIndex, true)
|
TLight::TLight(TPinballTable* table, int groupIndex) : TPinballComponent(table, groupIndex, true)
|
||||||
{
|
{
|
||||||
@@ -144,13 +144,13 @@ int TLight::Message(int code, float value)
|
|||||||
break;
|
break;
|
||||||
case 11:
|
case 11:
|
||||||
BmpIndex2 = static_cast<int>(floor(value));
|
BmpIndex2 = static_cast<int>(floor(value));
|
||||||
if (BmpIndex2 > ListBitmap->Count())
|
if (BmpIndex2 > ListBitmap->GetCount())
|
||||||
BmpIndex2 = ListBitmap->Count();
|
BmpIndex2 = ListBitmap->GetCount();
|
||||||
bmpIndex = 0;
|
bmpIndex = 0;
|
||||||
if (BmpIndex2 < 0)
|
if (BmpIndex2 < 0)
|
||||||
BmpIndex2 = 0;
|
BmpIndex2 = 0;
|
||||||
Flasher.BmpArr[0] = nullptr;
|
Flasher.BmpArr[0] = nullptr;
|
||||||
Flasher.BmpArr[1] = static_cast<gdrv_bitmap8*>(ListBitmap->Get(BmpIndex2));
|
Flasher.BmpArr[1] = ListBitmap->Get(BmpIndex2);
|
||||||
if (FlasherActive == 0)
|
if (FlasherActive == 0)
|
||||||
{
|
{
|
||||||
if (!FlasherFlag1)
|
if (!FlasherFlag1)
|
||||||
@@ -169,8 +169,8 @@ int TLight::Message(int code, float value)
|
|||||||
break;
|
break;
|
||||||
case 12:
|
case 12:
|
||||||
bmpIndex = BmpIndex2 + 1;
|
bmpIndex = BmpIndex2 + 1;
|
||||||
if (bmpIndex > ListBitmap->Count())
|
if (bmpIndex > ListBitmap->GetCount())
|
||||||
bmpIndex = ListBitmap->Count();
|
bmpIndex = ListBitmap->GetCount();
|
||||||
Message(11, static_cast<float>(bmpIndex));
|
Message(11, static_cast<float>(bmpIndex));
|
||||||
break;
|
break;
|
||||||
case 13:
|
case 13:
|
||||||
@@ -257,7 +257,7 @@ void TLight::Reset()
|
|||||||
Flasher.Sprite = RenderSprite;
|
Flasher.Sprite = RenderSprite;
|
||||||
Flasher.BmpArr[0] = nullptr;
|
Flasher.BmpArr[0] = nullptr;
|
||||||
if (ListBitmap)
|
if (ListBitmap)
|
||||||
Flasher.BmpArr[1] = static_cast<gdrv_bitmap8*>(ListBitmap->Get(0));
|
Flasher.BmpArr[1] = ListBitmap->Get(0);
|
||||||
Flasher.Unknown4 = 0;
|
Flasher.Unknown4 = 0;
|
||||||
Flasher.Unknown3 = 0;
|
Flasher.Unknown3 = 0;
|
||||||
MessageField = 0;
|
MessageField = 0;
|
||||||
@@ -270,7 +270,7 @@ void TLight::schedule_timeout(float time)
|
|||||||
if (Timer1)
|
if (Timer1)
|
||||||
timer::kill(Timer1);
|
timer::kill(Timer1);
|
||||||
Timer1 = 0;
|
Timer1 = 0;
|
||||||
if (time > 0.0)
|
if (time > 0.0f)
|
||||||
Timer1 = timer::set(time, this, TimerExpired);
|
Timer1 = timer::set(time, this, TimerExpired);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ TLightBargraph::TLightBargraph(TPinballTable* table, int groupIndex) : TLightGro
|
|||||||
float* floatArr = loader::query_float_attribute(groupIndex, 0, 904);
|
float* floatArr = loader::query_float_attribute(groupIndex, 0, 904);
|
||||||
if (floatArr)
|
if (floatArr)
|
||||||
{
|
{
|
||||||
int count = 2 * List->Count();
|
int count = 2 * List->GetCount();
|
||||||
TimerTimeArray = reinterpret_cast<float*>(memory::allocate(count * sizeof(float)));
|
TimerTimeArray = memory::allocate<float>(count);
|
||||||
if (TimerTimeArray)
|
if (TimerTimeArray)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < count; ++floatArr)
|
for (int i = 0; i < count; ++floatArr)
|
||||||
@@ -49,7 +49,7 @@ int TLightBargraph::Message(int code, float value)
|
|||||||
TimerBargraph = 0;
|
TimerBargraph = 0;
|
||||||
}
|
}
|
||||||
auto timeIndex = static_cast<int>(floor(value));
|
auto timeIndex = static_cast<int>(floor(value));
|
||||||
auto maxCount = 2 * List->Count();
|
auto maxCount = 2 * List->GetCount();
|
||||||
if (timeIndex >= maxCount)
|
if (timeIndex >= maxCount)
|
||||||
timeIndex = maxCount - 1;
|
timeIndex = maxCount - 1;
|
||||||
if (timeIndex >= 0)
|
if (timeIndex >= 0)
|
||||||
@@ -57,9 +57,8 @@ int TLightBargraph::Message(int code, float value)
|
|||||||
TLightGroup::Message(45, static_cast<float>(timeIndex / 2));
|
TLightGroup::Message(45, static_cast<float>(timeIndex / 2));
|
||||||
if (!(timeIndex & 1))
|
if (!(timeIndex & 1))
|
||||||
TLightGroup::Message(46, 0.0);
|
TLightGroup::Message(46, 0.0);
|
||||||
float* timeArray = TimerTimeArray;
|
if (TimerTimeArray)
|
||||||
if (timeArray)
|
TimerBargraph = timer::set(TimerTimeArray[timeIndex], this, BargraphTimerExpired);
|
||||||
TimerBargraph = timer::set(timeArray[timeIndex], this, BargraphTimerExpired);
|
|
||||||
TimeIndex = timeIndex;
|
TimeIndex = timeIndex;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
TLightGroup::TLightGroup(TPinballTable* table, int groupIndex) : TPinballComponent(table, groupIndex, false)
|
TLightGroup::TLightGroup(TPinballTable* table, int groupIndex) : TPinballComponent(table, groupIndex, false)
|
||||||
{
|
{
|
||||||
List = new objlist_class(4, 4);
|
List = new objlist_class<TLight>(4, 4);
|
||||||
Timer = 0;
|
Timer = 0;
|
||||||
NotifyTimer = 0;
|
NotifyTimer = 0;
|
||||||
Reset();
|
Reset();
|
||||||
@@ -19,10 +19,10 @@ TLightGroup::TLightGroup(TPinballTable* table, int groupIndex) : TPinballCompone
|
|||||||
{
|
{
|
||||||
int count;
|
int count;
|
||||||
Timer1TimeDefault = *loader::query_float_attribute(groupIndex, 0, 903);
|
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)
|
for (int index = 0; index < count; ++groupIndArr)
|
||||||
{
|
{
|
||||||
auto comp = table->find_component(*groupIndArr);
|
auto comp = dynamic_cast<TLight*>(table->find_component(*groupIndArr));
|
||||||
if (comp)
|
if (comp)
|
||||||
List->Add(comp);
|
List->Add(comp);
|
||||||
++index;
|
++index;
|
||||||
@@ -71,8 +71,8 @@ int TLightGroup::Message(int code, float value)
|
|||||||
break;
|
break;
|
||||||
case 24:
|
case 24:
|
||||||
{
|
{
|
||||||
auto count = List->Count();
|
auto count = List->GetCount();
|
||||||
auto lastLight = static_cast<TLight*>(List->Get(count - 1));
|
auto lastLight = List->Get(count - 1);
|
||||||
if (lastLight->FlasherActive || lastLight->FlasherFlag2 || lastLight->FlasherFlag1)
|
if (lastLight->FlasherActive || lastLight->FlasherFlag2 || lastLight->FlasherFlag1)
|
||||||
break;
|
break;
|
||||||
if (MessageField2)
|
if (MessageField2)
|
||||||
@@ -85,12 +85,12 @@ int TLightGroup::Message(int code, float value)
|
|||||||
auto bmpIndex1 = lastLight->BmpIndex1;
|
auto bmpIndex1 = lastLight->BmpIndex1;
|
||||||
for (auto index = count - 1; index > 0; --index)
|
for (auto index = count - 1; index > 0; --index)
|
||||||
{
|
{
|
||||||
auto lightCur = static_cast<TLight*>(List->Get(index));
|
auto lightCur = List->Get(index);
|
||||||
auto lightPrev = static_cast<TLight*>(List->Get(index - 1));
|
auto lightPrev = List->Get(index - 1);
|
||||||
lightCur->Message(lightPrev->BmpIndex1 != 0, 0.0);
|
lightCur->Message(lightPrev->BmpIndex1 != 0, 0.0);
|
||||||
lightCur->MessageField = lightPrev->MessageField;
|
lightCur->MessageField = lightPrev->MessageField;
|
||||||
}
|
}
|
||||||
auto firstLight = static_cast<TLight*>(List->Get(0));
|
auto firstLight = List->Get(0);
|
||||||
firstLight->Message(bmpIndex1 != 0, 0.0);
|
firstLight->Message(bmpIndex1 != 0, 0.0);
|
||||||
firstLight->MessageField = lightMessageField;
|
firstLight->MessageField = lightMessageField;
|
||||||
reschedule_animation(value);
|
reschedule_animation(value);
|
||||||
@@ -98,23 +98,23 @@ int TLightGroup::Message(int code, float value)
|
|||||||
}
|
}
|
||||||
case 25:
|
case 25:
|
||||||
{
|
{
|
||||||
auto count = List->Count();
|
auto count = List->GetCount();
|
||||||
auto lastLight = static_cast<TLight*>(List->Get(count - 1));
|
auto lastLight = List->Get(count - 1);
|
||||||
if (lastLight->FlasherActive || lastLight->FlasherFlag2 || lastLight->FlasherFlag1)
|
if (lastLight->FlasherActive || lastLight->FlasherFlag2 || lastLight->FlasherFlag1)
|
||||||
break;
|
break;
|
||||||
if (MessageField2)
|
if (MessageField2)
|
||||||
{
|
{
|
||||||
TLightGroup::Message(34, 0.0);
|
TLightGroup::Message(34, 0.0);
|
||||||
}
|
}
|
||||||
auto firstLight = static_cast<TLight*>(List->Get(0));
|
auto firstLight = List->Get(0);
|
||||||
AnimationFlag = 1;
|
AnimationFlag = 1;
|
||||||
MessageField2 = code;
|
MessageField2 = code;
|
||||||
auto lightMessageField = firstLight->MessageField;
|
auto lightMessageField = firstLight->MessageField;
|
||||||
auto bmpIndex1 = firstLight->BmpIndex1;
|
auto bmpIndex1 = firstLight->BmpIndex1;
|
||||||
for (auto index = 0; index < count - 1; index++)
|
for (auto index = 0; index < count - 1; index++)
|
||||||
{
|
{
|
||||||
auto lightCur = static_cast<TLight*>(List->Get(index));
|
auto lightCur = List->Get(index);
|
||||||
auto lightNext = static_cast<TLight*>(List->Get(index + 1));
|
auto lightNext = List->Get(index + 1);
|
||||||
lightCur->Message(lightNext->BmpIndex1 != 0, 0.0);
|
lightCur->Message(lightNext->BmpIndex1 != 0, 0.0);
|
||||||
lightCur->MessageField = lightNext->MessageField;
|
lightCur->MessageField = lightNext->MessageField;
|
||||||
}
|
}
|
||||||
@@ -129,16 +129,16 @@ int TLightGroup::Message(int code, float value)
|
|||||||
start_animation();
|
start_animation();
|
||||||
MessageField2 = code;
|
MessageField2 = code;
|
||||||
AnimationFlag = 0;
|
AnimationFlag = 0;
|
||||||
auto count = List->Count();
|
auto count = List->GetCount();
|
||||||
auto lastLight = static_cast<TLight*>(List->Get(count - 1));
|
auto lastLight = List->Get(count - 1);
|
||||||
auto flasherFlag2 = lastLight->FlasherFlag2;
|
auto flasherFlag2 = lastLight->FlasherFlag2;
|
||||||
for (auto i = count - 1; i > 0; --i)
|
for (auto i = count - 1; i > 0; --i)
|
||||||
{
|
{
|
||||||
auto lightCur = static_cast<TLight*>(List->Get(i));
|
auto lightCur = List->Get(i);
|
||||||
auto lightPrev = static_cast<TLight*>(List->Get(i - 1));
|
auto lightPrev = List->Get(i - 1);
|
||||||
lightCur->Message((lightPrev->FlasherFlag2 != 0) + 8, 0.0);
|
lightCur->Message((lightPrev->FlasherFlag2 != 0) + 8, 0.0);
|
||||||
}
|
}
|
||||||
auto firstLight = static_cast<TLight*>(List->Get(0));
|
auto firstLight = List->Get(0);
|
||||||
firstLight->Message((flasherFlag2 != 0) + 8, 0);
|
firstLight->Message((flasherFlag2 != 0) + 8, 0);
|
||||||
reschedule_animation(value);
|
reschedule_animation(value);
|
||||||
break;
|
break;
|
||||||
@@ -149,16 +149,16 @@ int TLightGroup::Message(int code, float value)
|
|||||||
start_animation();
|
start_animation();
|
||||||
MessageField2 = code;
|
MessageField2 = code;
|
||||||
AnimationFlag = 0;
|
AnimationFlag = 0;
|
||||||
auto count = List->Count();
|
auto count = List->GetCount();
|
||||||
auto firstLight = static_cast<TLight*>(List->Get(0));
|
auto firstLight = List->Get(0);
|
||||||
auto flasherFlag2 = firstLight->FlasherFlag2;
|
auto flasherFlag2 = firstLight->FlasherFlag2;
|
||||||
for (auto i = 0; i < count - 1; i++)
|
for (auto i = 0; i < count - 1; i++)
|
||||||
{
|
{
|
||||||
auto lightCur = static_cast<TLight*>(List->Get(i));
|
auto lightCur = List->Get(i);
|
||||||
auto lightNext = static_cast<TLight*>(List->Get(i + 1));
|
auto lightNext = List->Get(i + 1);
|
||||||
lightCur->Message((lightNext->FlasherFlag2 != 0) + 8, 0.0);
|
lightCur->Message((lightNext->FlasherFlag2 != 0) + 8, 0.0);
|
||||||
}
|
}
|
||||||
auto lastLight = static_cast<TLight*>(List->Get(count - 1));
|
auto lastLight = List->Get(count - 1);
|
||||||
lastLight->Message((flasherFlag2 != 0) + 8, 0);
|
lastLight->Message((flasherFlag2 != 0) + 8, 0);
|
||||||
reschedule_animation(value);
|
reschedule_animation(value);
|
||||||
break;
|
break;
|
||||||
@@ -169,12 +169,12 @@ int TLightGroup::Message(int code, float value)
|
|||||||
start_animation();
|
start_animation();
|
||||||
MessageField2 = code;
|
MessageField2 = code;
|
||||||
AnimationFlag = 0;
|
AnimationFlag = 0;
|
||||||
auto count = List->Count();
|
auto count = List->GetCount();
|
||||||
for (auto i = 0; i < count - 1; i++)
|
for (auto i = 0; i < count - 1; i++)
|
||||||
{
|
{
|
||||||
if (rand() % 100 > 70)
|
if (rand() % 100 > 70)
|
||||||
{
|
{
|
||||||
auto light = static_cast<TLight*>(List->Get(i));
|
auto light = List->Get(i);
|
||||||
auto randVal = static_cast<float>(rand()) * 0.00003051850947599719f * value * 3.0f + 0.1f;
|
auto randVal = static_cast<float>(rand()) * 0.00003051850947599719f * value * 3.0f + 0.1f;
|
||||||
light->Message(9, randVal);
|
light->Message(9, randVal);
|
||||||
}
|
}
|
||||||
@@ -188,10 +188,10 @@ int TLightGroup::Message(int code, float value)
|
|||||||
start_animation();
|
start_animation();
|
||||||
MessageField2 = code;
|
MessageField2 = code;
|
||||||
AnimationFlag = 0;
|
AnimationFlag = 0;
|
||||||
auto count = List->Count();
|
auto count = List->GetCount();
|
||||||
for (auto i = 0; i < count - 1; i++)
|
for (auto i = 0; i < count - 1; i++)
|
||||||
{
|
{
|
||||||
auto light = static_cast<TLight*>(List->Get(i));
|
auto light = List->Get(i);
|
||||||
auto randVal = static_cast<float>(rand() % 100 > 70);
|
auto randVal = static_cast<float>(rand() % 100 > 70);
|
||||||
light->Message(18, randVal);
|
light->Message(18, randVal);
|
||||||
}
|
}
|
||||||
@@ -201,13 +201,13 @@ int TLightGroup::Message(int code, float value)
|
|||||||
case 30:
|
case 30:
|
||||||
{
|
{
|
||||||
auto noBmpInd1Count = 0;
|
auto noBmpInd1Count = 0;
|
||||||
auto countSub1 = List->Count() - 1;
|
auto countSub1 = List->GetCount() - 1;
|
||||||
if (countSub1 < 0)
|
if (countSub1 < 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
for (auto i = countSub1; i >= 0; i--)
|
for (auto i = countSub1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
if (!static_cast<TLight*>(List->Get(i))->BmpIndex1)
|
if (!List->Get(i)->BmpIndex1)
|
||||||
++noBmpInd1Count;
|
++noBmpInd1Count;
|
||||||
}
|
}
|
||||||
if (!noBmpInd1Count)
|
if (!noBmpInd1Count)
|
||||||
@@ -216,7 +216,7 @@ int TLightGroup::Message(int code, float value)
|
|||||||
auto randModCount = rand() % noBmpInd1Count;
|
auto randModCount = rand() % noBmpInd1Count;
|
||||||
for (auto i = countSub1; i >= 0; i--)
|
for (auto i = countSub1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
auto light = static_cast<TLight*>(List->Get(i));
|
auto light = List->Get(i);
|
||||||
if (!light->BmpIndex1 && randModCount-- == 0)
|
if (!light->BmpIndex1 && randModCount-- == 0)
|
||||||
{
|
{
|
||||||
light->Message(1, 0.0);
|
light->Message(1, 0.0);
|
||||||
@@ -231,13 +231,13 @@ int TLightGroup::Message(int code, float value)
|
|||||||
case 31:
|
case 31:
|
||||||
{
|
{
|
||||||
auto bmpInd1Count = 0;
|
auto bmpInd1Count = 0;
|
||||||
auto countSub1 = List->Count() - 1;
|
auto countSub1 = List->GetCount() - 1;
|
||||||
if (countSub1 < 0)
|
if (countSub1 < 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
for (auto i = countSub1; i >= 0; i--)
|
for (auto i = countSub1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
if (static_cast<TLight*>(List->Get(i))->BmpIndex1)
|
if (List->Get(i)->BmpIndex1)
|
||||||
++bmpInd1Count;
|
++bmpInd1Count;
|
||||||
}
|
}
|
||||||
if (!bmpInd1Count)
|
if (!bmpInd1Count)
|
||||||
@@ -246,7 +246,7 @@ int TLightGroup::Message(int code, float value)
|
|||||||
auto randModCount = rand() % bmpInd1Count;
|
auto randModCount = rand() % bmpInd1Count;
|
||||||
for (auto i = countSub1; i >= 0; i--)
|
for (auto i = countSub1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
auto light = static_cast<TLight*>(List->Get(i));
|
auto light = List->Get(i);
|
||||||
if (light->BmpIndex1 && randModCount-- == 0)
|
if (light->BmpIndex1 && randModCount-- == 0)
|
||||||
{
|
{
|
||||||
light->Message(0, 0.0);
|
light->Message(0, 0.0);
|
||||||
@@ -263,7 +263,7 @@ int TLightGroup::Message(int code, float value)
|
|||||||
auto index = next_light_up();
|
auto index = next_light_up();
|
||||||
if (index < 0)
|
if (index < 0)
|
||||||
break;
|
break;
|
||||||
static_cast<TLight*>(List->Get(index))->Message(1, 0.0);
|
List->Get(index)->Message(1, 0.0);
|
||||||
if (MessageField2)
|
if (MessageField2)
|
||||||
start_animation();
|
start_animation();
|
||||||
return 1;
|
return 1;
|
||||||
@@ -273,7 +273,7 @@ int TLightGroup::Message(int code, float value)
|
|||||||
auto index = next_light_down();
|
auto index = next_light_down();
|
||||||
if (index < 0)
|
if (index < 0)
|
||||||
break;
|
break;
|
||||||
static_cast<TLight*>(List->Get(index))->Message(0, 0.0);
|
List->Get(index)->Message(0, 0.0);
|
||||||
if (MessageField2)
|
if (MessageField2)
|
||||||
start_animation();
|
start_animation();
|
||||||
return 1;
|
return 1;
|
||||||
@@ -292,10 +292,10 @@ int TLightGroup::Message(int code, float value)
|
|||||||
case 35:
|
case 35:
|
||||||
{
|
{
|
||||||
auto index = static_cast<int>(floor(value));
|
auto index = static_cast<int>(floor(value));
|
||||||
if (index >= List->Count() || index < 0)
|
if (index >= List->GetCount() || index < 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
auto light = static_cast<TLight*>(List->Get(index));
|
auto light = List->Get(index);
|
||||||
light->Message(1, 0.0);
|
light->Message(1, 0.0);
|
||||||
if (MessageField2)
|
if (MessageField2)
|
||||||
start_animation();
|
start_animation();
|
||||||
@@ -304,10 +304,10 @@ int TLightGroup::Message(int code, float value)
|
|||||||
case 36:
|
case 36:
|
||||||
{
|
{
|
||||||
auto index = static_cast<int>(floor(value));
|
auto index = static_cast<int>(floor(value));
|
||||||
if (index >= List->Count() || index < 0)
|
if (index >= List->GetCount() || index < 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
auto light = static_cast<TLight*>(List->Get(index));
|
auto light = List->Get(index);
|
||||||
light->Message(0, 0.0);
|
light->Message(0, 0.0);
|
||||||
if (MessageField2)
|
if (MessageField2)
|
||||||
start_animation();
|
start_animation();
|
||||||
@@ -316,16 +316,16 @@ int TLightGroup::Message(int code, float value)
|
|||||||
case 37:
|
case 37:
|
||||||
{
|
{
|
||||||
auto bmp1Count = 0;
|
auto bmp1Count = 0;
|
||||||
auto countSub1 = List->Count() - 1;
|
auto countSub1 = List->GetCount() - 1;
|
||||||
for (auto i = countSub1; i >= 0; i--)
|
for (auto i = countSub1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
if (static_cast<TLight*>(List->Get(i))->BmpIndex1)
|
if (List->Get(i)->BmpIndex1)
|
||||||
++bmp1Count;
|
++bmp1Count;
|
||||||
}
|
}
|
||||||
return bmp1Count;
|
return bmp1Count;
|
||||||
}
|
}
|
||||||
case 38:
|
case 38:
|
||||||
return List->Count();
|
return List->GetCount();
|
||||||
case 39:
|
case 39:
|
||||||
return MessageField2;
|
return MessageField2;
|
||||||
case 40:
|
case 40:
|
||||||
@@ -337,7 +337,7 @@ int TLightGroup::Message(int code, float value)
|
|||||||
break;
|
break;
|
||||||
if (MessageField2 || AnimationFlag)
|
if (MessageField2 || AnimationFlag)
|
||||||
TLightGroup::Message(34, 0.0);
|
TLightGroup::Message(34, 0.0);
|
||||||
static_cast<TLight*>(List->Get(index))->Message(15, value);
|
List->Get(index)->Message(15, value);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
case 42:
|
case 42:
|
||||||
@@ -347,22 +347,22 @@ int TLightGroup::Message(int code, float value)
|
|||||||
break;
|
break;
|
||||||
if (MessageField2 || AnimationFlag)
|
if (MessageField2 || AnimationFlag)
|
||||||
TLightGroup::Message(34, 0.0);
|
TLightGroup::Message(34, 0.0);
|
||||||
static_cast<TLight*>(List->Get(index))->Message(16, value);
|
List->Get(index)->Message(16, value);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
case 43:
|
case 43:
|
||||||
if (NotifyTimer)
|
if (NotifyTimer)
|
||||||
timer::kill(NotifyTimer);
|
timer::kill(NotifyTimer);
|
||||||
NotifyTimer = 0;
|
NotifyTimer = 0;
|
||||||
if (value > 0.0)
|
if (value > 0.0f)
|
||||||
NotifyTimer = timer::set(value, this, NotifyTimerExpired);
|
NotifyTimer = timer::set(value, this, NotifyTimerExpired);
|
||||||
break;
|
break;
|
||||||
case 44:
|
case 44:
|
||||||
{
|
{
|
||||||
auto countSub1 = List->Count() - 1;
|
auto countSub1 = List->GetCount() - 1;
|
||||||
for (auto index = countSub1; index >= 0; index--)
|
for (auto index = countSub1; index >= 0; index--)
|
||||||
{
|
{
|
||||||
auto light = static_cast<TLight*>(List->Get(index));
|
auto light = List->Get(index);
|
||||||
if (light->BmpIndex1)
|
if (light->BmpIndex1)
|
||||||
{
|
{
|
||||||
light->Message(0, 0.0);
|
light->Message(0, 0.0);
|
||||||
@@ -374,31 +374,21 @@ int TLightGroup::Message(int code, float value)
|
|||||||
}
|
}
|
||||||
case 45:
|
case 45:
|
||||||
{
|
{
|
||||||
|
auto count = List->GetCount();
|
||||||
control::handler(code, this);
|
control::handler(code, this);
|
||||||
auto index = static_cast<int>(floor(value));
|
auto index = static_cast<int>(floor(value));
|
||||||
if (index >= 0)
|
if (index >= 0 && index < count)
|
||||||
{
|
{
|
||||||
auto count = List->Count();
|
// Turn off lights (index, end]
|
||||||
if (index <= count)
|
for (auto i = count - 1; i > index; i--)
|
||||||
{
|
{
|
||||||
auto countSub1 = count - 1;
|
List->Get(i)->Message(20, 0.0);
|
||||||
if (countSub1 > index)
|
}
|
||||||
{
|
|
||||||
countSub1 = index;
|
// Turn on lights [begin, index]
|
||||||
for (auto i = countSub1, k = countSub1 - index; k != 0; i--, k--)
|
for (auto i = index; i >= 0; i--)
|
||||||
{
|
{
|
||||||
auto light = static_cast<TLight*>(List->Get(i));
|
List->Get(i)->Message(19, 0.0);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -408,14 +398,14 @@ int TLightGroup::Message(int code, float value)
|
|||||||
auto index = next_light_down();
|
auto index = next_light_down();
|
||||||
if (index >= 0)
|
if (index >= 0)
|
||||||
{
|
{
|
||||||
static_cast<TLight*>(List->Get(index))->Message(4, 0.0);
|
List->Get(index)->Message(4, 0.0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
for (auto index = List->Count() - 1; index >= 0; index--)
|
for (auto index = List->GetCount() - 1; index >= 0; index--)
|
||||||
{
|
{
|
||||||
static_cast<TLight*>(List->Get(index))->Message(code, value);
|
List->Get(index)->Message(code, value);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -447,15 +437,15 @@ void TLightGroup::reschedule_animation(float time)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Timer1Time = time > 0.0 ? time : Timer1TimeDefault;
|
Timer1Time = time > 0.0f ? time : Timer1TimeDefault;
|
||||||
Timer = timer::set(Timer1Time, this, TimerExpired);
|
Timer = timer::set(Timer1Time, this, TimerExpired);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TLightGroup::start_animation()
|
void TLightGroup::start_animation()
|
||||||
{
|
{
|
||||||
for (int index = List->Count() - 1; index >= 0; --index)
|
for (int index = List->GetCount() - 1; index >= 0; --index)
|
||||||
{
|
{
|
||||||
auto light = static_cast<TLight*>(List->Get(index));
|
auto light = List->Get(index);
|
||||||
if (light->BmpIndex1)
|
if (light->BmpIndex1)
|
||||||
light->Message(9, 0.0);
|
light->Message(9, 0.0);
|
||||||
else
|
else
|
||||||
@@ -465,9 +455,9 @@ void TLightGroup::start_animation()
|
|||||||
|
|
||||||
int TLightGroup::next_light_up()
|
int TLightGroup::next_light_up()
|
||||||
{
|
{
|
||||||
for (int index = 0; index < List->Count(); ++index)
|
for (int index = 0; index < List->GetCount(); ++index)
|
||||||
{
|
{
|
||||||
if (!static_cast<TLight*>(List->Get(index))->BmpIndex1)
|
if (!List->Get(index)->BmpIndex1)
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
@@ -475,9 +465,9 @@ int TLightGroup::next_light_up()
|
|||||||
|
|
||||||
int TLightGroup::next_light_down()
|
int TLightGroup::next_light_down()
|
||||||
{
|
{
|
||||||
for (int index = List->Count() - 1; index >= 0; --index)
|
for (int index = List->GetCount() - 1; index >= 0; --index)
|
||||||
{
|
{
|
||||||
if (!static_cast<TLight*>(List->Get(index))->BmpIndex1)
|
if (List->Get(index)->BmpIndex1)
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "TPinballComponent.h"
|
#include "TPinballComponent.h"
|
||||||
class objlist_class;
|
|
||||||
|
|
||||||
|
class TLight;
|
||||||
|
|
||||||
struct TLightGroup_player_backup
|
struct TLightGroup_player_backup
|
||||||
{
|
{
|
||||||
@@ -27,7 +29,7 @@ public:
|
|||||||
static void TimerExpired(int timerId, void* caller);
|
static void TimerExpired(int timerId, void* caller);
|
||||||
static void NotifyTimerExpired(int timerId, void* caller);
|
static void NotifyTimerExpired(int timerId, void* caller);
|
||||||
|
|
||||||
objlist_class* List;
|
objlist_class<TLight>* List;
|
||||||
float Timer1Time;
|
float Timer1Time;
|
||||||
float Timer1TimeDefault;
|
float Timer1TimeDefault;
|
||||||
int MessageField2;
|
int MessageField2;
|
||||||
|
|||||||
@@ -4,11 +4,11 @@
|
|||||||
|
|
||||||
#include "control.h"
|
#include "control.h"
|
||||||
#include "loader.h"
|
#include "loader.h"
|
||||||
|
#include "objlist_class.h"
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
#include "TBall.h"
|
#include "TBall.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include "TPinballTable.h"
|
#include "TPinballTable.h"
|
||||||
#include "TZmapList.h"
|
|
||||||
|
|
||||||
TLightRollover::TLightRollover(TPinballTable* table, int groupIndex) : TRollover(table, groupIndex, false)
|
TLightRollover::TLightRollover(TPinballTable* table, int groupIndex) : TRollover(table, groupIndex, false)
|
||||||
{
|
{
|
||||||
@@ -58,7 +58,7 @@ void TLightRollover::Collision(TBall* ball, vector_type* nextPosition, vector_ty
|
|||||||
control::handler(63, this);
|
control::handler(63, this);
|
||||||
RolloverFlag = RolloverFlag == 0;
|
RolloverFlag = RolloverFlag == 0;
|
||||||
if (ListBitmap)
|
if (ListBitmap)
|
||||||
render::sprite_set_bitmap(RenderSprite, static_cast<gdrv_bitmap8*>(ListBitmap->Get(0)));
|
render::sprite_set_bitmap(RenderSprite, ListBitmap->Get(0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ void TOneway::Collision(TBall* ball, vector_type* nextPosition, vector_type* dir
|
|||||||
Elasticity,
|
Elasticity,
|
||||||
Smoothness,
|
Smoothness,
|
||||||
Threshold,
|
Threshold,
|
||||||
Boost) > 0.2)
|
Boost) > 0.2f)
|
||||||
{
|
{
|
||||||
if (SoftHitSoundId)
|
if (SoftHitSoundId)
|
||||||
loader::play_sound(SoftHitSoundId);
|
loader::play_sound(SoftHitSoundId);
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
#include "loader.h"
|
#include "loader.h"
|
||||||
#include "objlist_class.h"
|
#include "objlist_class.h"
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
#include "TZmapList.h"
|
|
||||||
#include "TPinballTable.h"
|
#include "TPinballTable.h"
|
||||||
|
|
||||||
TPinballComponent::TPinballComponent(TPinballTable* table, int groupIndex, bool loadVisuals)
|
TPinballComponent::TPinballComponent(TPinballTable* table, int groupIndex, bool loadVisuals)
|
||||||
@@ -32,32 +31,45 @@ TPinballComponent::TPinballComponent(TPinballTable* table, int groupIndex, bool
|
|||||||
if (visual.Bitmap)
|
if (visual.Bitmap)
|
||||||
{
|
{
|
||||||
if (!ListBitmap)
|
if (!ListBitmap)
|
||||||
ListBitmap = new TZmapList(visualCount, 4);
|
ListBitmap = new objlist_class<gdrv_bitmap8>(visualCount, 4);
|
||||||
if (ListBitmap)
|
if (ListBitmap)
|
||||||
ListBitmap->Add(visual.Bitmap);
|
ListBitmap->Add(visual.Bitmap);
|
||||||
}
|
}
|
||||||
if (visual.ZMap)
|
if (visual.ZMap)
|
||||||
{
|
{
|
||||||
if (!ListZMap)
|
if (!ListZMap)
|
||||||
ListZMap = new TZmapList(visualCount, 4);
|
ListZMap = new objlist_class<zmap_header_type>(visualCount, 4);
|
||||||
if (ListZMap)
|
if (ListZMap)
|
||||||
ListZMap->Add(visual.ZMap);
|
ListZMap->Add(visual.ZMap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
zmap_header_type* zMap = nullptr;
|
zmap_header_type* zMap = nullptr;
|
||||||
if (ListZMap)
|
if (ListZMap)
|
||||||
zMap = static_cast<zmap_header_type*>(ListZMap->Get(0));
|
zMap = ListZMap->Get(0);
|
||||||
if (ListBitmap)
|
if (ListBitmap)
|
||||||
{
|
{
|
||||||
|
/* Full tilt hack - spliced bitmap includes zMap
|
||||||
|
* Users access bitmap-zMap in pairs, pad zMap list with 0 for such users
|
||||||
|
* zdrv does not access zMap when drawing spliced bitmap*/
|
||||||
|
if (!ListZMap)
|
||||||
|
{
|
||||||
|
ListZMap = new objlist_class<zmap_header_type>(0, 4);
|
||||||
|
for (int index = 0; index < ListBitmap->GetCount(); index++)
|
||||||
|
{
|
||||||
|
assertm(ListBitmap->Get(index)->BitmapType == BitmapType::Spliced, "Wrong zMap padding");
|
||||||
|
ListZMap->Add(visual.ZMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rectangle_type bmp1Rect{}, tmpRect{};
|
rectangle_type bmp1Rect{}, tmpRect{};
|
||||||
auto rootBmp = static_cast<gdrv_bitmap8*>(ListBitmap->Get(0));
|
auto rootBmp = ListBitmap->Get(0);
|
||||||
bmp1Rect.XPosition = rootBmp->XPosition - table->XOffset;
|
bmp1Rect.XPosition = rootBmp->XPosition - table->XOffset;
|
||||||
bmp1Rect.YPosition = rootBmp->YPosition - table->YOffset;
|
bmp1Rect.YPosition = rootBmp->YPosition - table->YOffset;
|
||||||
bmp1Rect.Width = rootBmp->Width;
|
bmp1Rect.Width = rootBmp->Width;
|
||||||
bmp1Rect.Height = rootBmp->Height;
|
bmp1Rect.Height = rootBmp->Height;
|
||||||
for (int index = 1; index < ListBitmap->Count(); index++)
|
for (int index = 1; index < ListBitmap->GetCount(); index++)
|
||||||
{
|
{
|
||||||
auto bmp = static_cast<gdrv_bitmap8*>(ListBitmap->Get(index));
|
auto bmp = ListBitmap->Get(index);
|
||||||
tmpRect.XPosition = bmp->XPosition - table->XOffset;
|
tmpRect.XPosition = bmp->XPosition - table->XOffset;
|
||||||
tmpRect.YPosition = bmp->YPosition - table->YOffset;
|
tmpRect.YPosition = bmp->YPosition - table->YOffset;
|
||||||
tmpRect.Width = bmp->Width;
|
tmpRect.Width = bmp->Width;
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "objlist_class.h"
|
||||||
|
|
||||||
|
struct zmap_header_type;
|
||||||
|
struct gdrv_bitmap8;
|
||||||
struct render_sprite_type_struct;
|
struct render_sprite_type_struct;
|
||||||
struct component_control;
|
struct component_control;
|
||||||
class TPinballTable;
|
class TPinballTable;
|
||||||
class TZmapList;
|
|
||||||
|
|
||||||
enum class message_code
|
enum class message_code
|
||||||
{
|
{
|
||||||
@@ -26,8 +28,8 @@ public:
|
|||||||
void* operator new(size_t Size);
|
void* operator new(size_t Size);
|
||||||
void operator delete(void* p);
|
void operator delete(void* p);
|
||||||
|
|
||||||
__int8 UnusedBaseFlag;
|
char UnusedBaseFlag;
|
||||||
__int8 ActiveFlag;
|
char ActiveFlag;
|
||||||
int MessageField;
|
int MessageField;
|
||||||
char* GroupName;
|
char* GroupName;
|
||||||
int Unknown4;
|
int Unknown4;
|
||||||
@@ -35,6 +37,6 @@ public:
|
|||||||
int GroupIndex;
|
int GroupIndex;
|
||||||
render_sprite_type_struct* RenderSprite;
|
render_sprite_type_struct* RenderSprite;
|
||||||
TPinballTable* PinballTable;
|
TPinballTable* PinballTable;
|
||||||
TZmapList* ListBitmap;
|
objlist_class<gdrv_bitmap8>* ListBitmap;
|
||||||
TZmapList* ListZMap;
|
objlist_class<zmap_header_type>* ListZMap;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -48,8 +48,8 @@ TPinballTable::TPinballTable(): TPinballComponent(nullptr, -1, false)
|
|||||||
{
|
{
|
||||||
int shortArrLength;
|
int shortArrLength;
|
||||||
|
|
||||||
ComponentList = new objlist_class(32, 16);
|
ComponentList = new objlist_class<TPinballComponent>(32, 16);
|
||||||
BallList = new objlist_class(3, 1);
|
BallList = new objlist_class<TBall>(3, 1);
|
||||||
CurScoreStruct = nullptr;
|
CurScoreStruct = nullptr;
|
||||||
ScoreBallcount = nullptr;
|
ScoreBallcount = nullptr;
|
||||||
ScorePlayerNumber1 = nullptr;
|
ScorePlayerNumber1 = nullptr;
|
||||||
@@ -213,9 +213,9 @@ TPinballTable::~TPinballTable()
|
|||||||
ScoreBallcount = nullptr;
|
ScoreBallcount = nullptr;
|
||||||
}
|
}
|
||||||
delete LightGroup;
|
delete LightGroup;
|
||||||
while (ComponentList->Count() > 0)
|
while (ComponentList->GetCount() > 0)
|
||||||
{
|
{
|
||||||
delete static_cast<TPinballComponent*>(ComponentList->Get(0));
|
delete ComponentList->Get(0);
|
||||||
}
|
}
|
||||||
delete BallList;
|
delete BallList;
|
||||||
delete ComponentList;
|
delete ComponentList;
|
||||||
@@ -223,12 +223,12 @@ TPinballTable::~TPinballTable()
|
|||||||
|
|
||||||
TPinballComponent* TPinballTable::find_component(LPCSTR componentName)
|
TPinballComponent* TPinballTable::find_component(LPCSTR componentName)
|
||||||
{
|
{
|
||||||
int objCount = ComponentList->Count();
|
int objCount = ComponentList->GetCount();
|
||||||
if (objCount > 0)
|
if (objCount > 0)
|
||||||
{
|
{
|
||||||
for (int index = 0; index < objCount; ++index)
|
for (int index = 0; index < objCount; ++index)
|
||||||
{
|
{
|
||||||
TPinballComponent* obj = static_cast<TPinballComponent*>(ComponentList->Get(index));
|
TPinballComponent* obj = ComponentList->Get(index);
|
||||||
const CHAR* groupName = obj->GroupName;
|
const CHAR* groupName = obj->GroupName;
|
||||||
if (groupName && !lstrcmpA(groupName, componentName))
|
if (groupName && !lstrcmpA(groupName, componentName))
|
||||||
{
|
{
|
||||||
@@ -242,13 +242,13 @@ TPinballComponent* TPinballTable::find_component(LPCSTR componentName)
|
|||||||
|
|
||||||
TPinballComponent* TPinballTable::find_component(int groupIndex)
|
TPinballComponent* TPinballTable::find_component(int groupIndex)
|
||||||
{
|
{
|
||||||
char Buffer[40];
|
char Buffer[40]{};
|
||||||
int objCount = ComponentList->Count();
|
int objCount = ComponentList->GetCount();
|
||||||
if (objCount > 0)
|
if (objCount > 0)
|
||||||
{
|
{
|
||||||
for (int index = 0; index < objCount; ++index)
|
for (int index = 0; index < objCount; ++index)
|
||||||
{
|
{
|
||||||
TPinballComponent* obj = static_cast<TPinballComponent*>(ComponentList->Get(index));
|
TPinballComponent* obj = ComponentList->Get(index);
|
||||||
if (obj->GroupIndex == groupIndex)
|
if (obj->GroupIndex == groupIndex)
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
@@ -303,13 +303,13 @@ void TPinballTable::tilt(float time)
|
|||||||
{
|
{
|
||||||
pinball::InfoTextBox->Clear();
|
pinball::InfoTextBox->Clear();
|
||||||
pinball::MissTextBox->Clear();
|
pinball::MissTextBox->Clear();
|
||||||
pinball::InfoTextBox->Display(pinball::get_rc_string(35, 0), -1.0);
|
pinball::InfoTextBox->Display(pinball::get_rc_Wstring(35, 0), -1.0);
|
||||||
loader::play_sound(SoundIndex3);
|
loader::play_sound(SoundIndex3);
|
||||||
TiltTimeoutTimer = timer::set(30.0, this, tilt_timeout);
|
TiltTimeoutTimer = timer::set(30.0, this, tilt_timeout);
|
||||||
|
|
||||||
for (int i = 0; i < ComponentList->Count(); i++)
|
for (int i = 0; i < ComponentList->GetCount(); i++)
|
||||||
{
|
{
|
||||||
static_cast<TPinballComponent*>(ComponentList->Get(i))->Message(1011, time);
|
ComponentList->Get(i)->Message(1011, time);
|
||||||
}
|
}
|
||||||
LightGroup->Message(8, 0);
|
LightGroup->Message(8, 0);
|
||||||
TiltLockFlag = 1;
|
TiltLockFlag = 1;
|
||||||
@@ -320,15 +320,15 @@ void TPinballTable::tilt(float time)
|
|||||||
|
|
||||||
void TPinballTable::port_draw()
|
void TPinballTable::port_draw()
|
||||||
{
|
{
|
||||||
for (int index = ComponentList->Count() - 1; index >= 0; index--)
|
for (int index = ComponentList->GetCount() - 1; index >= 0; index--)
|
||||||
{
|
{
|
||||||
static_cast<TPinballComponent*>(ComponentList->Get(index))->port_draw();
|
ComponentList->Get(index)->port_draw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int TPinballTable::Message(int code, float value)
|
int TPinballTable::Message(int code, float value)
|
||||||
{
|
{
|
||||||
LPSTR rc_text;
|
LPWSTR rc_text;
|
||||||
switch (code)
|
switch (code)
|
||||||
{
|
{
|
||||||
case 1000:
|
case 1000:
|
||||||
@@ -362,9 +362,9 @@ int TPinballTable::Message(int code, float value)
|
|||||||
case 1008:
|
case 1008:
|
||||||
case 1009:
|
case 1009:
|
||||||
case 1010:
|
case 1010:
|
||||||
for (int i = 0; i < ComponentList->Count(); i++)
|
for (int i = 0; i < ComponentList->GetCount(); i++)
|
||||||
{
|
{
|
||||||
static_cast<TPinballComponent*>(ComponentList->Get(i))->Message(code, value);
|
ComponentList->Get(i)->Message(code, value);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 1012:
|
case 1012:
|
||||||
@@ -382,9 +382,9 @@ int TPinballTable::Message(int code, float value)
|
|||||||
LightGroup->Message(20, 0.0);
|
LightGroup->Message(20, 0.0);
|
||||||
Plunger->Message(1016, 0.0);
|
Plunger->Message(1016, 0.0);
|
||||||
if (Demo->ActiveFlag)
|
if (Demo->ActiveFlag)
|
||||||
rc_text = pinball::get_rc_string(30, 0);
|
rc_text = pinball::get_rc_Wstring(30, 0);
|
||||||
else
|
else
|
||||||
rc_text = pinball::get_rc_string(26, 0);
|
rc_text = pinball::get_rc_Wstring(26, 0);
|
||||||
pinball::InfoTextBox->Display(rc_text, -1.0);
|
pinball::InfoTextBox->Display(rc_text, -1.0);
|
||||||
if (Demo)
|
if (Demo)
|
||||||
Demo->Message(1014, 0.0);
|
Demo->Message(1014, 0.0);
|
||||||
@@ -406,7 +406,7 @@ int TPinballTable::Message(int code, float value)
|
|||||||
{
|
{
|
||||||
CheatsUsed = 0;
|
CheatsUsed = 0;
|
||||||
Message(1024, 0.0);
|
Message(1024, 0.0);
|
||||||
auto ball = static_cast<TBall*>(BallList->Get(0));
|
auto ball = BallList->Get(0);
|
||||||
ball->Position.Y = 0.0;
|
ball->Position.Y = 0.0;
|
||||||
ball->Position.X = 0.0;
|
ball->Position.X = 0.0;
|
||||||
ball->Position.Z = -0.8f;
|
ball->Position.Z = -0.8f;
|
||||||
@@ -477,11 +477,11 @@ int TPinballTable::Message(int code, float value)
|
|||||||
{
|
{
|
||||||
if (PlayerCount <= 1)
|
if (PlayerCount <= 1)
|
||||||
{
|
{
|
||||||
char* textboxText;
|
wchar_t* textboxText;
|
||||||
if (Demo->ActiveFlag)
|
if (Demo->ActiveFlag)
|
||||||
textboxText = pinball::get_rc_string(30, 0);
|
textboxText = pinball::get_rc_Wstring(30, 0);
|
||||||
else
|
else
|
||||||
textboxText = pinball::get_rc_string(26, 0);
|
textboxText = pinball::get_rc_Wstring(26, 0);
|
||||||
pinball::InfoTextBox->Display(textboxText, -1.0);
|
pinball::InfoTextBox->Display(textboxText, -1.0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -513,37 +513,37 @@ int TPinballTable::Message(int code, float value)
|
|||||||
score::set(ScorePlayerNumber1, nextPlayer + 1);
|
score::set(ScorePlayerNumber1, nextPlayer + 1);
|
||||||
score::update(ScorePlayerNumber1);
|
score::update(ScorePlayerNumber1);
|
||||||
|
|
||||||
for (int i = 0; i < ComponentList->Count(); i++)
|
for (int i = 0; i < ComponentList->GetCount(); i++)
|
||||||
{
|
{
|
||||||
static_cast<TPinballComponent*>(ComponentList->Get(i))->Message(1020, static_cast<float>(nextPlayer));
|
ComponentList->Get(i)->Message(1020, static_cast<float>(nextPlayer));
|
||||||
}
|
}
|
||||||
|
|
||||||
char* textboxText = nullptr;
|
wchar_t* textboxText = nullptr;
|
||||||
switch (nextPlayer)
|
switch (nextPlayer)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
if (Demo->ActiveFlag)
|
if (Demo->ActiveFlag)
|
||||||
textboxText = pinball::get_rc_string(30, 0);
|
textboxText = pinball::get_rc_Wstring(30, 0);
|
||||||
else
|
else
|
||||||
textboxText = pinball::get_rc_string(26, 0);
|
textboxText = pinball::get_rc_Wstring(26, 0);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
if (Demo->ActiveFlag)
|
if (Demo->ActiveFlag)
|
||||||
textboxText = pinball::get_rc_string(31, 0);
|
textboxText = pinball::get_rc_Wstring(31, 0);
|
||||||
else
|
else
|
||||||
textboxText = pinball::get_rc_string(27, 0);
|
textboxText = pinball::get_rc_Wstring(27, 0);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
if (Demo->ActiveFlag)
|
if (Demo->ActiveFlag)
|
||||||
textboxText = pinball::get_rc_string(32, 0);
|
textboxText = pinball::get_rc_Wstring(32, 0);
|
||||||
else
|
else
|
||||||
textboxText = pinball::get_rc_string(28, 0);
|
textboxText = pinball::get_rc_Wstring(28, 0);
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
if (Demo->ActiveFlag)
|
if (Demo->ActiveFlag)
|
||||||
textboxText = pinball::get_rc_string(33, 0);
|
textboxText = pinball::get_rc_Wstring(33, 0);
|
||||||
else
|
else
|
||||||
textboxText = pinball::get_rc_string(29, 0);
|
textboxText = pinball::get_rc_Wstring(29, 0);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -560,13 +560,13 @@ int TPinballTable::Message(int code, float value)
|
|||||||
case 1022:
|
case 1022:
|
||||||
loader::play_sound(SoundIndex2);
|
loader::play_sound(SoundIndex2);
|
||||||
pinball::MissTextBox->Clear();
|
pinball::MissTextBox->Clear();
|
||||||
pinball::InfoTextBox->Display(pinball::get_rc_string(34, 0), -1.0);
|
pinball::InfoTextBox->Display(pinball::get_rc_Wstring(34, 0), -1.0);
|
||||||
EndGameTimeoutTimer = timer::set(3.0, this, EndGame_timeout);
|
EndGameTimeoutTimer = timer::set(3.0, this, EndGame_timeout);
|
||||||
break;
|
break;
|
||||||
case 1024:
|
case 1024:
|
||||||
for (int i = 0; i < ComponentList->Count(); i++)
|
for (int i = 0; i < ComponentList->GetCount(); i++)
|
||||||
{
|
{
|
||||||
static_cast<TPinballComponent*>(ComponentList->Get(i))->Message(1024, 0);
|
ComponentList->Get(i)->Message(1024, 0);
|
||||||
}
|
}
|
||||||
if (ReplayTimer)
|
if (ReplayTimer)
|
||||||
timer::kill(ReplayTimer);
|
timer::kill(ReplayTimer);
|
||||||
@@ -608,14 +608,14 @@ void TPinballTable::EndGame_timeout(int timerId, void* caller)
|
|||||||
table->EndGameTimeoutTimer = 0;
|
table->EndGameTimeoutTimer = 0;
|
||||||
pb::end_game();
|
pb::end_game();
|
||||||
|
|
||||||
for (int i = 0; i < table->ComponentList->Count(); i++)
|
for (int i = 0; i < table->ComponentList->GetCount(); i++)
|
||||||
{
|
{
|
||||||
static_cast<TPinballComponent*>(table->ComponentList->Get(i))->Message(1022, 0);
|
table->ComponentList->Get(i)->Message(1022, 0);
|
||||||
}
|
}
|
||||||
if (table->Demo)
|
if (table->Demo)
|
||||||
table->Demo->Message(1022, 0.0);
|
table->Demo->Message(1022, 0.0);
|
||||||
control::handler(67, pinball::MissTextBox);
|
control::handler(67, pinball::MissTextBox);
|
||||||
pinball::InfoTextBox->Display(pinball::get_rc_string(24, 0), -1.0);
|
pinball::InfoTextBox->Display(pinball::get_rc_Wstring(24, 0), -1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TPinballTable::LightShow_timeout(int timerId, void* caller)
|
void TPinballTable::LightShow_timeout(int timerId, void* caller)
|
||||||
@@ -640,9 +640,9 @@ void TPinballTable::tilt_timeout(int timerId, void* caller)
|
|||||||
table->TiltTimeoutTimer = 0;
|
table->TiltTimeoutTimer = 0;
|
||||||
if (table->TiltLockFlag)
|
if (table->TiltLockFlag)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < table->BallList->Count(); i++)
|
for (int i = 0; i < table->BallList->GetCount(); i++)
|
||||||
{
|
{
|
||||||
table->Drain->Collision(static_cast<TBall*>(table->BallList->Get(i)), &vec, &vec, 0.0, nullptr);
|
table->Drain->Collision(table->BallList->Get(i), &vec, &vec, 0.0, nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,12 +2,12 @@
|
|||||||
|
|
||||||
#include "TPinballComponent.h"
|
#include "TPinballComponent.h"
|
||||||
|
|
||||||
|
class TBall;
|
||||||
struct scoreStruct;
|
struct scoreStruct;
|
||||||
class TFlipper;
|
class TFlipper;
|
||||||
class TPlunger;
|
class TPlunger;
|
||||||
class TDrain;
|
class TDrain;
|
||||||
class TDemo;
|
class TDemo;
|
||||||
class objlist_class;
|
|
||||||
class TLightGroup;
|
class TLightGroup;
|
||||||
|
|
||||||
struct score_struct_super
|
struct score_struct_super
|
||||||
@@ -65,8 +65,8 @@ public:
|
|||||||
int YOffset;
|
int YOffset;
|
||||||
int Width;
|
int Width;
|
||||||
int Height;
|
int Height;
|
||||||
objlist_class* ComponentList;
|
objlist_class<TPinballComponent>* ComponentList;
|
||||||
objlist_class* BallList;
|
objlist_class<TBall>* BallList;
|
||||||
TLightGroup* LightGroup;
|
TLightGroup* LightGroup;
|
||||||
float GravityDirVectMult;
|
float GravityDirVectMult;
|
||||||
float GravityAngleX;
|
float GravityAngleX;
|
||||||
|
|||||||
@@ -5,12 +5,12 @@
|
|||||||
#include "control.h"
|
#include "control.h"
|
||||||
#include "loader.h"
|
#include "loader.h"
|
||||||
#include "maths.h"
|
#include "maths.h"
|
||||||
|
#include "objlist_class.h"
|
||||||
#include "pb.h"
|
#include "pb.h"
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
#include "TBall.h"
|
#include "TBall.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include "TPinballTable.h"
|
#include "TPinballTable.h"
|
||||||
#include "TZmapList.h"
|
|
||||||
|
|
||||||
TPlunger::TPlunger(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true)
|
TPlunger::TPlunger(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true)
|
||||||
{
|
{
|
||||||
@@ -27,7 +27,7 @@ TPlunger::TPlunger(TPinballTable* table, int groupIndex) : TCollisionComponent(t
|
|||||||
MaxPullback = 100;
|
MaxPullback = 100;
|
||||||
Elasticity = 0.5f;
|
Elasticity = 0.5f;
|
||||||
Smoothness = 0.5f;
|
Smoothness = 0.5f;
|
||||||
PullbackIncrement = static_cast<int>(100.0 / (ListBitmap->Count() * 8.0));
|
PullbackIncrement = static_cast<int>(100.0 / (ListBitmap->GetCount() * 8.0));
|
||||||
Unknown4F = 0.025f;
|
Unknown4F = 0.025f;
|
||||||
float* floatArr = loader::query_float_attribute(groupIndex, 0, 601);
|
float* floatArr = loader::query_float_attribute(groupIndex, 0, 601);
|
||||||
table->PlungerPositionX = floatArr[0];
|
table->PlungerPositionX = floatArr[0];
|
||||||
@@ -65,8 +65,8 @@ int TPlunger::Message(int code, float value)
|
|||||||
PullbackTimer_ = 0;
|
PullbackTimer_ = 0;
|
||||||
if (code == 1005)
|
if (code == 1005)
|
||||||
loader::play_sound(SoundIndexP2);
|
loader::play_sound(SoundIndexP2);
|
||||||
auto bmp = static_cast<gdrv_bitmap8*>(ListBitmap->Get(0));
|
auto bmp = ListBitmap->Get(0);
|
||||||
auto zMap = static_cast<zmap_header_type*>(ListZMap->Get(0));
|
auto zMap = ListZMap->Get(0);
|
||||||
render::sprite_set(
|
render::sprite_set(
|
||||||
RenderSprite,
|
RenderSprite,
|
||||||
bmp,
|
bmp,
|
||||||
@@ -79,7 +79,7 @@ int TPlunger::Message(int code, float value)
|
|||||||
}
|
}
|
||||||
case 1015:
|
case 1015:
|
||||||
{
|
{
|
||||||
auto ball = static_cast<TBall*>(PinballTable->ComponentList->Get(0));
|
auto ball = PinballTable->BallList->Get(0);
|
||||||
ball->Message(1024, 0.0);
|
ball->Message(1024, 0.0);
|
||||||
ball->Position.X = PinballTable->PlungerPositionX;
|
ball->Position.X = PinballTable->PlungerPositionX;
|
||||||
ball->Position.Y = PinballTable->PlungerPositionY;
|
ball->Position.Y = PinballTable->PlungerPositionY;
|
||||||
@@ -112,8 +112,8 @@ int TPlunger::Message(int code, float value)
|
|||||||
PullbackTimer_ = 0;
|
PullbackTimer_ = 0;
|
||||||
if (code == 1005)
|
if (code == 1005)
|
||||||
loader::play_sound(SoundIndexP2);
|
loader::play_sound(SoundIndexP2);
|
||||||
auto bmp = static_cast<gdrv_bitmap8*>(ListBitmap->Get(0));
|
auto bmp = ListBitmap->Get(0);
|
||||||
auto zMap = static_cast<zmap_header_type*>(ListZMap->Get(0));
|
auto zMap = ListZMap->Get(0);
|
||||||
render::sprite_set(
|
render::sprite_set(
|
||||||
RenderSprite,
|
RenderSprite,
|
||||||
bmp,
|
bmp,
|
||||||
@@ -151,10 +151,10 @@ void TPlunger::PullbackTimer(int timerId, void* caller)
|
|||||||
plunger->Boost = static_cast<float>(plunger->MaxPullback);
|
plunger->Boost = static_cast<float>(plunger->MaxPullback);
|
||||||
}
|
}
|
||||||
int index = static_cast<int>(floor(
|
int index = static_cast<int>(floor(
|
||||||
static_cast<float>(plunger->ListBitmap->Count() - 1) *
|
static_cast<float>(plunger->ListBitmap->GetCount() - 1) *
|
||||||
(plunger->Boost / static_cast<float>(plunger->MaxPullback))));
|
(plunger->Boost / static_cast<float>(plunger->MaxPullback))));
|
||||||
auto bmp = static_cast<gdrv_bitmap8*>(plunger->ListBitmap->Get(index));
|
auto bmp = plunger->ListBitmap->Get(index);
|
||||||
auto zMap = static_cast<zmap_header_type*>(plunger->ListZMap->Get(index));
|
auto zMap = plunger->ListZMap->Get(index);
|
||||||
render::sprite_set(
|
render::sprite_set(
|
||||||
plunger->RenderSprite,
|
plunger->RenderSprite,
|
||||||
bmp,
|
bmp,
|
||||||
|
|||||||
@@ -4,10 +4,10 @@
|
|||||||
|
|
||||||
#include "control.h"
|
#include "control.h"
|
||||||
#include "loader.h"
|
#include "loader.h"
|
||||||
|
#include "objlist_class.h"
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include "TPinballTable.h"
|
#include "TPinballTable.h"
|
||||||
#include "TZmapList.h"
|
|
||||||
|
|
||||||
TPopupTarget::TPopupTarget(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true)
|
TPopupTarget::TPopupTarget(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true)
|
||||||
{
|
{
|
||||||
@@ -91,7 +91,7 @@ void TPopupTarget::TimerExpired(int timerId, void* caller)
|
|||||||
auto target = static_cast<TPopupTarget*>(caller);
|
auto target = static_cast<TPopupTarget*>(caller);
|
||||||
target->Timer = 0;
|
target->Timer = 0;
|
||||||
target->ActiveFlag = 1;
|
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->Get(0));
|
||||||
if (timerId)
|
if (timerId)
|
||||||
{
|
{
|
||||||
if (target->SoftHitSoundId)
|
if (target->SoftHitSoundId)
|
||||||
|
|||||||
@@ -22,16 +22,8 @@ TRamp::TRamp(TPinballTable* table, int groupIndex) : TCollisionComponent(table,
|
|||||||
loader::query_visual(groupIndex, 0, &visual);
|
loader::query_visual(groupIndex, 0, &visual);
|
||||||
CollisionGroup = visual.CollisionGroup;
|
CollisionGroup = visual.CollisionGroup;
|
||||||
|
|
||||||
auto floatArr1 = loader::query_float_attribute(groupIndex, 0, 701);
|
BallFieldMult = loader::query_float_attribute(groupIndex, 0, 701, 0.2f);
|
||||||
if (floatArr1)
|
RampFlag1 = static_cast<int>(loader::query_float_attribute(groupIndex, 0, 1305, 0));
|
||||||
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;
|
|
||||||
|
|
||||||
auto floatArr3Plane = loader::query_float_attribute(groupIndex, 0, 1300);
|
auto floatArr3Plane = loader::query_float_attribute(groupIndex, 0, 1300);
|
||||||
RampPlaneCount = static_cast<int>(floor(*floatArr3Plane));
|
RampPlaneCount = static_cast<int>(floor(*floatArr3Plane));
|
||||||
|
|||||||
@@ -5,12 +5,12 @@
|
|||||||
#include "control.h"
|
#include "control.h"
|
||||||
#include "gdrv.h"
|
#include "gdrv.h"
|
||||||
#include "loader.h"
|
#include "loader.h"
|
||||||
|
#include "objlist_class.h"
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
#include "TBall.h"
|
#include "TBall.h"
|
||||||
#include "TEdgeSegment.h"
|
#include "TEdgeSegment.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include "TPinballTable.h"
|
#include "TPinballTable.h"
|
||||||
#include "TZmapList.h"
|
|
||||||
|
|
||||||
TRollover::TRollover(TPinballTable* table, int groupIndex, bool createWall) : TCollisionComponent(
|
TRollover::TRollover(TPinballTable* table, int groupIndex, bool createWall) : TCollisionComponent(
|
||||||
table, groupIndex, createWall)
|
table, groupIndex, createWall)
|
||||||
@@ -22,7 +22,7 @@ TRollover::TRollover(TPinballTable* table, int groupIndex) : TCollisionComponent
|
|||||||
{
|
{
|
||||||
RolloverFlag = 0;
|
RolloverFlag = 0;
|
||||||
if (ListBitmap)
|
if (ListBitmap)
|
||||||
render::sprite_set_bitmap(RenderSprite, static_cast<gdrv_bitmap8*>(ListBitmap->Get(0)));
|
render::sprite_set_bitmap(RenderSprite, ListBitmap->Get(0));
|
||||||
build_walls(groupIndex);
|
build_walls(groupIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ int TRollover::Message(int code, float value)
|
|||||||
this->ActiveFlag = 1;
|
this->ActiveFlag = 1;
|
||||||
this->RolloverFlag = 0;
|
this->RolloverFlag = 0;
|
||||||
if (this->ListBitmap)
|
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->Get(0));
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -63,7 +63,7 @@ void TRollover::Collision(TBall* ball, vector_type* nextPosition, vector_type* d
|
|||||||
if (ListBitmap)
|
if (ListBitmap)
|
||||||
{
|
{
|
||||||
if (!RolloverFlag)
|
if (!RolloverFlag)
|
||||||
bmp = static_cast<gdrv_bitmap8*>(ListBitmap->Get(0));
|
bmp = ListBitmap->Get(0);
|
||||||
render::sprite_set_bitmap(RenderSprite, bmp);
|
render::sprite_set_bitmap(RenderSprite, bmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ int TSink::Message(int code, float value)
|
|||||||
switch (code)
|
switch (code)
|
||||||
{
|
{
|
||||||
case 56:
|
case 56:
|
||||||
if (value < 0.0)
|
if (value < 0.0f)
|
||||||
value = TimerTime;
|
value = TimerTime;
|
||||||
Timer = timer::set(value, this, TimerExpired);
|
Timer = timer::set(value, this, TimerExpired);
|
||||||
break;
|
break;
|
||||||
@@ -95,7 +95,7 @@ void TSink::Collision(TBall* ball, vector_type* nextPosition, vector_type* direc
|
|||||||
void TSink::TimerExpired(int timerId, void* caller)
|
void TSink::TimerExpired(int timerId, void* caller)
|
||||||
{
|
{
|
||||||
auto sink = static_cast<TSink*>(caller);
|
auto sink = static_cast<TSink*>(caller);
|
||||||
auto ball = static_cast<TBall*>(sink->PinballTable->BallList->Get(0));
|
auto ball = sink->PinballTable->BallList->Get(0);
|
||||||
ball->CollisionComp = nullptr;
|
ball->CollisionComp = nullptr;
|
||||||
ball->ActiveFlag = 1;
|
ball->ActiveFlag = 1;
|
||||||
ball->Position.X = sink->BallPosition.X;
|
ball->Position.X = sink->BallPosition.X;
|
||||||
|
|||||||
@@ -4,10 +4,10 @@
|
|||||||
|
|
||||||
#include "control.h"
|
#include "control.h"
|
||||||
#include "loader.h"
|
#include "loader.h"
|
||||||
|
#include "objlist_class.h"
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include "TPinballTable.h"
|
#include "TPinballTable.h"
|
||||||
#include "TZmapList.h"
|
|
||||||
|
|
||||||
TSoloTarget::TSoloTarget(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true)
|
TSoloTarget::TSoloTarget(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true)
|
||||||
{
|
{
|
||||||
@@ -41,8 +41,8 @@ int TSoloTarget::Message(int code, float value)
|
|||||||
if (ListBitmap)
|
if (ListBitmap)
|
||||||
{
|
{
|
||||||
auto index = 1 - ActiveFlag;
|
auto index = 1 - ActiveFlag;
|
||||||
auto bmp = static_cast<gdrv_bitmap8*>(ListBitmap->Get(index));
|
auto bmp = ListBitmap->Get(index);
|
||||||
auto zMap = static_cast<zmap_header_type*>(ListZMap->Get(index));
|
auto zMap = ListZMap->Get(index);
|
||||||
render::sprite_set(
|
render::sprite_set(
|
||||||
RenderSprite,
|
RenderSprite,
|
||||||
bmp,
|
bmp,
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
#include "TTableLayer.h"
|
#include "TTableLayer.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "fullscrn.h"
|
||||||
#include "loader.h"
|
#include "loader.h"
|
||||||
#include "objlist_class.h"
|
#include "objlist_class.h"
|
||||||
|
#include "pb.h"
|
||||||
#include "proj.h"
|
#include "proj.h"
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
#include "TBall.h"
|
#include "TBall.h"
|
||||||
@@ -19,7 +22,8 @@ TTableLayer::TTableLayer(TPinballTable* table): TCollisionComponent(table, -1, f
|
|||||||
auto groupIndex = loader::query_handle("table");
|
auto groupIndex = loader::query_handle("table");
|
||||||
loader::query_visual(groupIndex, 0, &visual);
|
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]);
|
proj::recenter(projCenter[0], projCenter[1]);
|
||||||
render::set_background_zmap(visual.ZMap, 0, 0);
|
render::set_background_zmap(visual.ZMap, 0, 0);
|
||||||
|
|
||||||
@@ -49,11 +53,12 @@ TTableLayer::TTableLayer(TPinballTable* table): TCollisionComponent(table, -1, f
|
|||||||
PinballTable->GravityAnglY = 1.570796f;
|
PinballTable->GravityAnglY = 1.570796f;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto table3 = PinballTable;
|
GraityDirX = cos(PinballTable->GravityAnglY) * sin(PinballTable->GravityAngleX) * PinballTable->GravityDirVectMult;
|
||||||
GraityDirX = cos(table3->GravityAnglY) * sin(table3->GravityAngleX) * table3->GravityDirVectMult;
|
GraityDirY = sin(PinballTable->GravityAnglY) * sin(PinballTable->GravityAngleX) * PinballTable->GravityDirVectMult;
|
||||||
GraityDiY = sin(table3->GravityAnglY) * sin(table3->GravityAngleX) * table3->GravityDirVectMult;
|
|
||||||
auto angleMultArr = loader::query_float_attribute(groupIndex, 0, 701);
|
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;
|
GraityMult = *angleMultArr;
|
||||||
else
|
else
|
||||||
GraityMult = 0.2f;
|
GraityMult = 0.2f;
|
||||||
@@ -109,7 +114,7 @@ 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 - static_cast<float>(rand()) * 0.00003051850947599719f + ball->Acceleration.X) *
|
||||||
ball->Speed * GraityMult;
|
ball->Speed * GraityMult;
|
||||||
vecDst->Y = GraityDiY - ball->Acceleration.Y * ball->Speed * GraityMult;
|
vecDst->Y = GraityDirY - ball->Acceleration.Y * ball->Speed * GraityMult;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,47 +219,47 @@ void TTableLayer::edges_insert_circle(circle_type* circle, TEdgeSegment* edge, f
|
|||||||
ray.Direction.X = 1.0;
|
ray.Direction.X = 1.0;
|
||||||
ray.Direction.Y = 0.0;
|
ray.Direction.Y = 0.0;
|
||||||
ray.MaxDistance = edge_manager->AdvanceX;
|
ray.MaxDistance = edge_manager->AdvanceX;
|
||||||
if (maths::ray_intersect_circle(&ray, circle) < 1000000000.0)
|
if (maths::ray_intersect_circle(&ray, circle) < 1000000000.0f)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
ray.Direction.X = -1.0;
|
ray.Direction.X = -1.0;
|
||||||
ray.Origin.X = ray.Origin.X + edge_manager->AdvanceX;
|
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;
|
break;
|
||||||
|
|
||||||
ray.Direction.X = 0.0;
|
ray.Direction.X = 0.0;
|
||||||
ray.Direction.Y = 1.0;
|
ray.Direction.Y = 1.0;
|
||||||
ray.MaxDistance = edge_manager->AdvanceY;
|
ray.MaxDistance = edge_manager->AdvanceY;
|
||||||
if (maths::ray_intersect_circle(&ray, circle) < 1000000000.0)
|
if (maths::ray_intersect_circle(&ray, circle) < 1000000000.0f)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
ray.Direction.Y = -1.0;
|
ray.Direction.Y = -1.0;
|
||||||
ray.Origin.Y = ray.Origin.Y + edge_manager->AdvanceY;
|
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;
|
break;
|
||||||
|
|
||||||
ray.Direction.Y = 0.0;
|
ray.Direction.Y = 0.0;
|
||||||
ray.Direction.X = -1.0;
|
ray.Direction.X = -1.0;
|
||||||
ray.MaxDistance = edge_manager->AdvanceX;
|
ray.MaxDistance = edge_manager->AdvanceX;
|
||||||
if (maths::ray_intersect_circle(&ray, circle) < 1000000000.0)
|
if (maths::ray_intersect_circle(&ray, circle) < 1000000000.0f)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
ray.Direction.X = 1.0;
|
ray.Direction.X = 1.0;
|
||||||
ray.Origin.X = ray.Origin.X - edge_manager->AdvanceX;
|
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;
|
break;
|
||||||
|
|
||||||
ray.Direction.X = 0.0;
|
ray.Direction.X = 0.0;
|
||||||
ray.Direction.Y = -1.0;
|
ray.Direction.Y = -1.0;
|
||||||
ray.MaxDistance = edge_manager->AdvanceY;
|
ray.MaxDistance = edge_manager->AdvanceY;
|
||||||
if (maths::ray_intersect_circle(&ray, circle) < 1000000000.0)
|
if (maths::ray_intersect_circle(&ray, circle) < 1000000000.0f)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
ray.Direction.Y = 1.0;
|
ray.Direction.Y = 1.0;
|
||||||
ray.Origin.Y = ray.Origin.Y - edge_manager->AdvanceY;
|
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;
|
break;
|
||||||
|
|
||||||
collision = false;
|
collision = false;
|
||||||
}
|
}
|
||||||
while (false);
|
while (false);
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ public:
|
|||||||
float Unknown3F;
|
float Unknown3F;
|
||||||
float Unknown4F;
|
float Unknown4F;
|
||||||
float GraityDirX;
|
float GraityDirX;
|
||||||
float GraityDiY;
|
float GraityDirY;
|
||||||
int Unknown7;
|
int Unknown7;
|
||||||
float GraityMult;
|
float GraityMult;
|
||||||
field_effect_type Field;
|
field_effect_type Field;
|
||||||
|
|||||||
@@ -2,7 +2,9 @@
|
|||||||
#include "TTextBox.h"
|
#include "TTextBox.h"
|
||||||
|
|
||||||
#include "control.h"
|
#include "control.h"
|
||||||
|
#include "fullscrn.h"
|
||||||
#include "loader.h"
|
#include "loader.h"
|
||||||
|
#include "pb.h"
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
#include "score.h"
|
#include "score.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
@@ -22,8 +24,9 @@ TTextBox::TTextBox(TPinballTable* table, int groupIndex) : TPinballComponent(tab
|
|||||||
|
|
||||||
if (groupIndex > 0)
|
if (groupIndex > 0)
|
||||||
{
|
{
|
||||||
|
/*Full tilt: text box dimensions index is offset by resolution*/
|
||||||
int arrLength;
|
int arrLength;
|
||||||
auto dimensions = loader::query_iattribute(groupIndex, 1500, &arrLength);
|
auto dimensions = loader::query_iattribute(groupIndex + fullscrn::GetResolution(), 1500, &arrLength);
|
||||||
OffsetX = dimensions[0];
|
OffsetX = dimensions[0];
|
||||||
OffsetY = dimensions[1];
|
OffsetY = dimensions[1];
|
||||||
Width = dimensions[2];
|
Width = dimensions[2];
|
||||||
@@ -106,19 +109,19 @@ void TTextBox::Clear()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TTextBox::Display(char* text, float time)
|
void TTextBox::Display(const wchar_t* text, float time)
|
||||||
{
|
{
|
||||||
if (!text)
|
if (!text)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (Message1 && !strcmp(text, Message2->Text))
|
if (Message1 && !lstrcmpW(text, Message2->Text))
|
||||||
{
|
{
|
||||||
Message2->Refresh(time);
|
Message2->Refresh(time);
|
||||||
if (Message2 == Message1)
|
if (Message2 == Message1)
|
||||||
{
|
{
|
||||||
if (Timer && Timer != -1)
|
if (Timer && Timer != -1)
|
||||||
timer::kill(Timer);
|
timer::kill(Timer);
|
||||||
if (time == -1.0)
|
if (time == -1.0f)
|
||||||
Timer = -1;
|
Timer = -1;
|
||||||
else
|
else
|
||||||
Timer = timer::set(time, this, TimerExpired);
|
Timer = timer::set(time, this, TimerExpired);
|
||||||
@@ -150,10 +153,8 @@ void TTextBox::Display(char* text, float time)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TTextBox::Draw()
|
void TTextBox::Draw(bool redraw)
|
||||||
{
|
{
|
||||||
TTextBoxMessage* nextMessage = nullptr;
|
|
||||||
|
|
||||||
auto bmp = BgBmp;
|
auto bmp = BgBmp;
|
||||||
if (bmp)
|
if (bmp)
|
||||||
gdrv::copy_bitmap(
|
gdrv::copy_bitmap(
|
||||||
@@ -168,119 +169,119 @@ void TTextBox::Draw()
|
|||||||
else
|
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)
|
while (Message1)
|
||||||
{
|
{
|
||||||
auto message = Message1;
|
if (redraw)
|
||||||
if (message->Time == -1.0)
|
|
||||||
{
|
{
|
||||||
nextMessage = message->NextMessage;
|
display = true;
|
||||||
if (!message->NextMessage)
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Message1->Time == -1.0f)
|
||||||
|
{
|
||||||
|
if (!Message1->NextMessage)
|
||||||
{
|
{
|
||||||
Timer = -1;
|
Timer = -1;
|
||||||
LABEL_18:
|
display = true;
|
||||||
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;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if (Message1->TimeLeft() >= -2.0f)
|
||||||
{
|
{
|
||||||
auto timeLeft = (Message1->TimeLeft());
|
if (Timer > 0)
|
||||||
if (timeLeft >= -2.0f)
|
timer::kill(Timer);
|
||||||
|
Timer = timer::set(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::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);
|
||||||
|
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;
|
||||||
|
wchar_t* textEndSpace = nullptr;
|
||||||
|
auto textEnd = text;
|
||||||
|
while (true)
|
||||||
{
|
{
|
||||||
int timer;
|
auto maskedChar = curChar & 0x7F;
|
||||||
if (timeLeft >= 0.25f)
|
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
|
else
|
||||||
{
|
{
|
||||||
timer = timer::set(0.25, this, TimerExpired);
|
curChar = *textEnd;
|
||||||
}
|
}
|
||||||
Timer = timer;
|
|
||||||
goto LABEL_18;
|
|
||||||
}
|
}
|
||||||
nextMessage = message->NextMessage;
|
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
delete message;
|
|
||||||
Message1 = nextMessage;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gdrv::blit(
|
gdrv::blit(
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ public:
|
|||||||
~TTextBox() override;
|
~TTextBox() override;
|
||||||
int Message(int code, float value) override;
|
int Message(int code, float value) override;
|
||||||
void Clear();
|
void Clear();
|
||||||
void Display(char* text, float time);
|
void Display(const wchar_t* text, float time);
|
||||||
void Draw();
|
void Draw(bool redraw = false);
|
||||||
|
|
||||||
static void TimerExpired(int timerId, void* tb);
|
static void TimerExpired(int timerId, void* tb);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,17 +3,17 @@
|
|||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "pb.h"
|
#include "pb.h"
|
||||||
|
|
||||||
TTextBoxMessage::TTextBoxMessage(char* text, float time)
|
TTextBoxMessage::TTextBoxMessage(const wchar_t* text, float time)
|
||||||
{
|
{
|
||||||
NextMessage = nullptr;
|
NextMessage = nullptr;
|
||||||
Time = time;
|
Time = time;
|
||||||
EndTicks = pb::time_ticks + static_cast<int>(time * 1000.0f);
|
EndTicks = pb::time_ticks + static_cast<int>(time * 1000.0f);
|
||||||
if (text)
|
if (text)
|
||||||
{
|
{
|
||||||
const auto textLen = strlen(text) + 1;
|
const auto textLen = lstrlenW(text) + 1;
|
||||||
Text = memory::allocate(textLen);
|
Text = memory::allocate<wchar_t>(textLen);
|
||||||
if (Text)
|
if (Text)
|
||||||
strcpy_s(Text, textLen, text);
|
lstrcpynW(Text, text, textLen);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Text = nullptr;
|
Text = nullptr;
|
||||||
|
|||||||
@@ -3,11 +3,11 @@ class TTextBoxMessage
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TTextBoxMessage* NextMessage;
|
TTextBoxMessage* NextMessage;
|
||||||
char* Text;
|
wchar_t* Text;
|
||||||
float Time;
|
float Time;
|
||||||
int EndTicks;
|
int EndTicks;
|
||||||
|
|
||||||
TTextBoxMessage(char* text, float time);
|
TTextBoxMessage(const wchar_t* text, float time);
|
||||||
~TTextBoxMessage();
|
~TTextBoxMessage();
|
||||||
float TimeLeft() const;
|
float TimeLeft() const;
|
||||||
void Refresh(float time);
|
void Refresh(float time);
|
||||||
|
|||||||
@@ -3,16 +3,16 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "control.h"
|
#include "control.h"
|
||||||
|
#include "objlist_class.h"
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include "TZmapList.h"
|
|
||||||
|
|
||||||
TWall::TWall(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true)
|
TWall::TWall(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true)
|
||||||
{
|
{
|
||||||
if (RenderSprite)
|
if (RenderSprite)
|
||||||
render::sprite_set_bitmap(RenderSprite, nullptr);
|
render::sprite_set_bitmap(RenderSprite, nullptr);
|
||||||
if (ListBitmap)
|
if (ListBitmap)
|
||||||
BmpPtr = static_cast<gdrv_bitmap8*>(ListBitmap->Get(0));
|
BmpPtr = ListBitmap->Get(0);
|
||||||
Timer = 0;
|
Timer = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
/* flag values for play params */
|
/* flag values for play params */
|
||||||
#define WMIX_QUEUEWAVE 0x00
|
#define WMIX_QUEUEWAVE 0x00
|
||||||
#define WMIX_CLEARQUEUE 0x01
|
#define WMIX_CLEARQUEUE 0x01
|
||||||
@@ -15,8 +16,8 @@ struct GLOBALS;
|
|||||||
|
|
||||||
struct volume_struct
|
struct volume_struct
|
||||||
{
|
{
|
||||||
unsigned __int16 L;
|
uint16_t L;
|
||||||
unsigned __int16 R;
|
uint16_t R;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -59,14 +60,14 @@ struct MIXCONFIG
|
|||||||
DWORD dwFlags;
|
DWORD dwFlags;
|
||||||
WORD wChannels;
|
WORD wChannels;
|
||||||
WORD wSamplingRate;
|
WORD wSamplingRate;
|
||||||
unsigned __int16 WaveBlockCount;
|
uint16_t WaveBlockCount;
|
||||||
unsigned __int16 WaveBlockLen;
|
uint16_t WaveBlockLen;
|
||||||
__int16 CmixPtrDefaultFlag;
|
int16_t CmixPtrDefaultFlag;
|
||||||
unsigned __int16 ResetMixDefaultFlag;
|
uint16_t ResetMixDefaultFlag;
|
||||||
unsigned __int16 GoodWavePos;
|
uint16_t GoodWavePos;
|
||||||
unsigned __int16 wDeviceID;
|
uint16_t wDeviceID;
|
||||||
unsigned __int16 PauseBlocks;
|
uint16_t PauseBlocks;
|
||||||
__int16 ShowDebugDialogs;
|
int16_t ShowDebugDialogs;
|
||||||
HKEY RegistryKey;
|
HKEY RegistryKey;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -88,14 +89,14 @@ struct PLAYQUEUE
|
|||||||
struct GLOBALS
|
struct GLOBALS
|
||||||
{
|
{
|
||||||
WORD wMagic1;
|
WORD wMagic1;
|
||||||
__int16 unknown0;
|
int16_t unknown0;
|
||||||
HWND hWndApp;
|
HWND hWndApp;
|
||||||
int unknown2;
|
int unknown2;
|
||||||
HWAVEOUT hWaveOut;
|
HWAVEOUT hWaveOut;
|
||||||
int fActive;
|
int fActive;
|
||||||
int SettingsDialogActiveFlag;
|
int SettingsDialogActiveFlag;
|
||||||
unsigned int wDeviceID;
|
unsigned int wDeviceID;
|
||||||
char szDevicePName[96];
|
char szDevicePName[96];
|
||||||
WAVEOUTCAPSA WaveoutCaps;
|
WAVEOUTCAPSA WaveoutCaps;
|
||||||
volume_struct DefaultVolume;
|
volume_struct DefaultVolume;
|
||||||
volume_struct ChannelVolume[MAXCHANNELS];
|
volume_struct ChannelVolume[MAXCHANNELS];
|
||||||
@@ -112,13 +113,13 @@ struct GLOBALS
|
|||||||
DWORD dwBaseTime;
|
DWORD dwBaseTime;
|
||||||
int fGoodGetPos;
|
int fGoodGetPos;
|
||||||
DWORD dwWaveOutPos;
|
DWORD dwWaveOutPos;
|
||||||
void (*CmixPtr)(unsigned __int8* lpDest, unsigned __int8** rgWaveSrc, volume_struct* volume, int iNumWaves,
|
void (*CmixPtr)(uint8_t* lpDest, uint8_t** rgWaveSrc, volume_struct* volume, int iNumWaves,
|
||||||
unsigned __int16 length);
|
uint16_t length);
|
||||||
int (* pfnRemix)(DWORD, CHANNELNODE*);
|
int (* pfnRemix)(DWORD, CHANNELNODE*);
|
||||||
DWORD (* pfnSampleAdjust)(DWORD, DWORD);
|
DWORD (* pfnSampleAdjust)(DWORD, DWORD);
|
||||||
CHANNELNODE* pWaitList;
|
CHANNELNODE* pWaitList;
|
||||||
__int16 wMagic2;
|
int16_t wMagic2;
|
||||||
__int16 unknown112;
|
int16_t unknown112;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dialog_template
|
struct dialog_template
|
||||||
@@ -182,16 +183,16 @@ private:
|
|||||||
static DWORD SubFactor(DWORD a1, DWORD a2);
|
static DWORD SubFactor(DWORD a1, DWORD a2);
|
||||||
static DWORD AddFactor(DWORD a1, DWORD a2);
|
static DWORD AddFactor(DWORD a1, DWORD a2);
|
||||||
static dialog_template* MakeSettingsDlgTemplate();
|
static dialog_template* MakeSettingsDlgTemplate();
|
||||||
static dialog_template* MakeDlgTemplate(unsigned* totalSize, unsigned style, __int16 x, __int16 y, __int16 cx,
|
static dialog_template* MakeDlgTemplate(size_t* totalSize, unsigned style, int16_t x, int16_t y, int16_t cx,
|
||||||
__int16 cy,
|
int16_t cy,
|
||||||
const wchar_t* String);
|
const wchar_t* String);
|
||||||
static dialog_template* AddDlgControl(unsigned int* totalSize, dialog_template* dlgTemplate, __int16 idClass,
|
static dialog_template* AddDlgControl(size_t* totalSize, dialog_template* dlgTemplate, int16_t idClass,
|
||||||
unsigned style,
|
unsigned style,
|
||||||
WORD id, __int16 x, __int16 y, __int16 cx, __int16 cy,
|
WORD id, int16_t x, int16_t y, int16_t cx, int16_t cy,
|
||||||
const wchar_t* String);
|
const wchar_t* String);
|
||||||
static void DestroySettingsDlgTemplate(LPCVOID pMem);
|
static void DestroySettingsDlgTemplate(LPCVOID pMem);
|
||||||
static int Settings_OnInitDialog(HWND hWnd, int wParam, MIXCONFIG* lpMixconfig);
|
static int Settings_OnInitDialog(HWND hWnd, WPARAM wParam, MIXCONFIG* lpMixconfig);
|
||||||
static int Settings_OnCommand(HWND hWnd, int command, int lParam, int wParam);
|
static int Settings_OnCommand(HWND hWnd, int command, LPARAM lParam, int wParam);
|
||||||
static int ReadRegistryToGetMachineSpecificInfSection(unsigned wDeviceId, LPSTR lpString1, int maxLength);
|
static int ReadRegistryToGetMachineSpecificInfSection(unsigned wDeviceId, LPSTR lpString1, int maxLength);
|
||||||
static const char* GetOperatingSystemPrefix();
|
static const char* GetOperatingSystemPrefix();
|
||||||
static unsigned int FigureOutDMABufferSize(unsigned int waveBlockLen, PCMWAVEFORMAT* pcm);
|
static unsigned int FigureOutDMABufferSize(unsigned int waveBlockLen, PCMWAVEFORMAT* pcm);
|
||||||
@@ -215,8 +216,8 @@ private:
|
|||||||
static int HasCurrentOutputFormat(MIXWAVE* lpMixWave);
|
static int HasCurrentOutputFormat(MIXWAVE* lpMixWave);
|
||||||
static CHANNELNODE* GetChannelNode();
|
static CHANNELNODE* GetChannelNode();
|
||||||
static void ResetWavePosIfNoChannelData();
|
static void ResetWavePosIfNoChannelData();
|
||||||
static void cmixit(unsigned __int8* lpDest, unsigned __int8** rgWaveSrc, volume_struct* volumeArr, int iNumWaves,
|
static void cmixit(uint8_t* lpDest, uint8_t** rgWaveSrc, volume_struct* volumeArr, int iNumWaves,
|
||||||
unsigned __int16 length);
|
uint16_t length);
|
||||||
static LRESULT __stdcall WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
|
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_PTR __stdcall SettingsDlgProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
|
||||||
|
|
||||||
@@ -226,8 +227,8 @@ private:
|
|||||||
static CHANNELNODE* free_channel_nodes;
|
static CHANNELNODE* free_channel_nodes;
|
||||||
static unsigned char volume_table[11][256];
|
static unsigned char volume_table[11][256];
|
||||||
static int debug_flag;
|
static int debug_flag;
|
||||||
static void (*cmixit_ptr)(unsigned __int8* lpDest, unsigned __int8** rgWaveSrc, volume_struct* volume,
|
static void (*cmixit_ptr)(uint8_t* lpDest, uint8_t** rgWaveSrc, volume_struct* volume,
|
||||||
int iNumWaves, unsigned __int16 length);
|
int iNumWaves, uint16_t length);
|
||||||
static HMODULE HModule;
|
static HMODULE HModule;
|
||||||
static GLOBALS *Globals, *GlobalsActive;
|
static GLOBALS *Globals, *GlobalsActive;
|
||||||
static PCMWAVEFORMAT gpFormat;
|
static PCMWAVEFORMAT gpFormat;
|
||||||
|
|||||||
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");
|
static_assert(std::is_base_of<TPinballComponent, T>::value, "T must inherit from TPinballComponent");
|
||||||
T* Component;
|
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);
|
component_tag::SetComponent(component);
|
||||||
}
|
}
|
||||||
@@ -65,14 +65,15 @@ public:
|
|||||||
static TPinballTable* TableG;
|
static TPinballTable* TableG;
|
||||||
static component_info score_components[88];
|
static component_info score_components[88];
|
||||||
static component_tag_base* simple_components[142];
|
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 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 component_tag_base *wormhole_tag_array1[3], *wormhole_tag_array2[3], *wormhole_tag_array3[3];
|
||||||
|
|
||||||
static void make_links(TPinballTable* table);
|
static void make_links(TPinballTable* table);
|
||||||
static TPinballComponent* make_component_link(component_tag_base* tag);
|
static TPinballComponent* make_component_link(component_tag_base* tag);
|
||||||
static void handler(int code, TPinballComponent* cmp);
|
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_add_extra_ball(float count);
|
||||||
static void table_set_bonus_hold();
|
static void table_set_bonus_hold();
|
||||||
static void table_set_bonus();
|
static void table_set_bonus();
|
||||||
@@ -81,7 +82,7 @@ public:
|
|||||||
static void table_set_multiball();
|
static void table_set_multiball();
|
||||||
static void table_bump_ball_sink_lock();
|
static void table_bump_ball_sink_lock();
|
||||||
static void table_set_replay(float value);
|
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 bool light_on(component_tag<TLight>* tag);
|
||||||
static int SpecialAddScore(int score);
|
static int SpecialAddScore(int score);
|
||||||
static int AddRankProgress(int rank);
|
static int AddRankProgress(int rank);
|
||||||
@@ -182,6 +183,5 @@ public:
|
|||||||
static void UnselectMissionController(int code, TPinballComponent* caller);
|
static void UnselectMissionController(int code, TPinballComponent* caller);
|
||||||
static void WaitingDeploymentController(int code, TPinballComponent* caller);
|
static void WaitingDeploymentController(int code, TPinballComponent* caller);
|
||||||
private:
|
private:
|
||||||
static int pbctrl_state;
|
|
||||||
static int extraball_light_flag;
|
static int extraball_light_flag;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
#include "fullscrn.h"
|
#include "fullscrn.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "options.h"
|
||||||
|
#include "pb.h"
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
#include "winmain.h"
|
#include "winmain.h"
|
||||||
|
|
||||||
@@ -10,10 +14,22 @@ tagRECT fullscrn::WindowRect1, fullscrn::WindowRect2;
|
|||||||
rectangle_type fullscrn::WHRect;
|
rectangle_type fullscrn::WHRect;
|
||||||
int fullscrn::fullscrn_flag1;
|
int fullscrn::fullscrn_flag1;
|
||||||
int fullscrn::display_changed;
|
int fullscrn::display_changed;
|
||||||
int fullscrn::ChangeDisplay, fullscrn::SmthFullScrnFlag2;
|
int fullscrn::ChangeDisplay, fullscrn::ignoreNextDisplayChangeFg;
|
||||||
int fullscrn::trick = 1;
|
int fullscrn::trick = 1;
|
||||||
int fullscrn::MenuEnabled;
|
int fullscrn::MenuEnabled;
|
||||||
HMENU fullscrn::MenuHandle;
|
HMENU fullscrn::MenuHandle;
|
||||||
|
int fullscrn::resolution = 0;
|
||||||
|
int fullscrn::maxResolution = 0;
|
||||||
|
const resolution_info fullscrn::resolution_array[3] =
|
||||||
|
{
|
||||||
|
{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;
|
||||||
|
|
||||||
void fullscrn::init(int width, int height, int isFullscreen, HWND winHandle, HMENU menuHandle, int changeDisplay)
|
void fullscrn::init(int width, int height, int isFullscreen, HWND winHandle, HMENU menuHandle, int changeDisplay)
|
||||||
{
|
{
|
||||||
@@ -36,15 +52,21 @@ void fullscrn::init(int width, int height, int isFullscreen, HWND winHandle, HME
|
|||||||
WindowRect2.right = (WindowRect1.right - WindowRect1.left - widht2) / 2 - 2 + widht2 + 4;
|
WindowRect2.right = (WindowRect1.right - WindowRect1.left - widht2) / 2 - 2 + widht2 + 4;
|
||||||
WindowRect2.left = (WindowRect1.right - WindowRect1.left - widht2) / 2 - 2;
|
WindowRect2.left = (WindowRect1.right - WindowRect1.left - widht2) / 2 - 2;
|
||||||
WindowRect2.top = borderHeight / 2 - (captionHeight + menuHeight) - 2;
|
WindowRect2.top = borderHeight / 2 - (captionHeight + menuHeight) - 2;
|
||||||
|
|
||||||
|
/*RECT client{0,0,width,height};
|
||||||
|
AdjustWindowRect(&client, winmain::WndStyle, true);*/
|
||||||
MoveWindow(
|
MoveWindow(
|
||||||
hWnd,
|
hWnd,
|
||||||
(WindowRect1.right - WindowRect1.left - widht2) / 2 - 2,
|
(WindowRect1.right - WindowRect1.left - widht2) / 2 - 2,
|
||||||
WindowRect2.top,
|
WindowRect2.top,
|
||||||
widht2 + 4 + 10,
|
WindowRect2.right - WindowRect2.left + 10,
|
||||||
WindowRect2.bottom - WindowRect2.top + 10,
|
WindowRect2.bottom - WindowRect2.top + 10,
|
||||||
0);
|
0);
|
||||||
// Todo: WH + 10 hack: original request 640x480 window but somehow receives 650x490, even thought spyxx says it is 640x480
|
// Todo: WH + 10 hack: original request 640x480 window but somehow receives 650x490, even thought spyxx says it is 640x480
|
||||||
fullscrn_flag1 = 0;
|
fullscrn_flag1 = 0;
|
||||||
|
|
||||||
|
window_size_changed();
|
||||||
|
assertm(ScaleX == 1 && ScaleY == 1, "Wrong default client size");
|
||||||
}
|
}
|
||||||
|
|
||||||
void fullscrn::shutdown()
|
void fullscrn::shutdown()
|
||||||
@@ -84,13 +106,13 @@ int fullscrn::set_screen_mode(int isFullscreen)
|
|||||||
int fullscrn::disableWindowFlagsDisDlg()
|
int fullscrn::disableWindowFlagsDisDlg()
|
||||||
{
|
{
|
||||||
long style = GetWindowLongA(hWnd, -16);
|
long style = GetWindowLongA(hWnd, -16);
|
||||||
return SetWindowLongA(hWnd, -16, style & 0xFF3FFFFF);
|
return SetWindowLongA(hWnd, -16, style & ~(WS_CAPTION | WS_THICKFRAME));
|
||||||
}
|
}
|
||||||
|
|
||||||
int fullscrn::setWindowFlagsDisDlg()
|
int fullscrn::setWindowFlagsDisDlg()
|
||||||
{
|
{
|
||||||
int style = GetWindowLongA(hWnd, -16);
|
int style = GetWindowLongA(hWnd, -16);
|
||||||
return SetWindowLongA(hWnd, -16, style | 0xC00000);
|
return SetWindowLongA(hWnd, -16, style | WS_CAPTION | WS_THICKFRAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
int fullscrn::enableFullscreen()
|
int fullscrn::enableFullscreen()
|
||||||
@@ -100,33 +122,33 @@ int fullscrn::enableFullscreen()
|
|||||||
|
|
||||||
if (ChangeDisplay && !display_changed)
|
if (ChangeDisplay && !display_changed)
|
||||||
{
|
{
|
||||||
DevMode.dmSize = 156;
|
DevMode.dmSize = sizeof DevMode;
|
||||||
DevMode.dmFields = 1835008;
|
DevMode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
|
||||||
DevMode.dmPelsWidth = 640;
|
DevMode.dmPelsWidth = resolution_array[resolution].ScreenWidth;
|
||||||
DevMode.dmPelsHeight = 480;
|
DevMode.dmPelsHeight = resolution_array[resolution].ScreenHeight;
|
||||||
DevMode.dmBitsPerPel = 8;
|
DevMode.dmBitsPerPel = 32;
|
||||||
disableWindowFlagsDisDlg();
|
disableWindowFlagsDisDlg();
|
||||||
if (trick)
|
if (trick)
|
||||||
{
|
{
|
||||||
GetWindowRect(GetDesktopWindow(), &Rect);
|
GetWindowRect(GetDesktopWindow(), &Rect);
|
||||||
SetWindowPos(hWnd, (HWND)-1, 0, 0, Rect.right - Rect.left + 1,
|
SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, Rect.right - Rect.left + 1,
|
||||||
Rect.bottom - Rect.top + 1, 8u);
|
Rect.bottom - Rect.top + 1, SWP_NOREDRAW);
|
||||||
}
|
}
|
||||||
SmthFullScrnFlag2 = 1;
|
ignoreNextDisplayChangeFg = 1;
|
||||||
LONG changeDispResult = ChangeDisplaySettingsA(&DevMode, 4u);
|
LONG changeDispResult = ChangeDisplaySettingsA(&DevMode, CDS_FULLSCREEN);
|
||||||
if (changeDispResult == 1)
|
if (changeDispResult == DISP_CHANGE_RESTART)
|
||||||
{
|
{
|
||||||
BYTE2(DevMode.dmFields) &= 0xFBu;
|
DevMode.dmFields &= ~DM_BITSPERPEL;
|
||||||
SmthFullScrnFlag2 = 1;
|
ignoreNextDisplayChangeFg = 1;
|
||||||
changeDispResult = ChangeDisplaySettingsA(&DevMode, 4u);
|
changeDispResult = ChangeDisplaySettingsA(&DevMode, CDS_FULLSCREEN);
|
||||||
}
|
}
|
||||||
display_changed = changeDispResult == 0;
|
display_changed = changeDispResult == DISP_CHANGE_SUCCESSFUL;
|
||||||
if (changeDispResult == 0)
|
if (display_changed)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
GetWindowRect(GetDesktopWindow(), &Rect);
|
GetWindowRect(GetDesktopWindow(), &Rect);
|
||||||
disableWindowFlagsDisDlg();
|
disableWindowFlagsDisDlg();
|
||||||
SetWindowPos(hWnd, (HWND)-1, 0, 0, Rect.right - Rect.left + 1, Rect.bottom - Rect.top + 1, 8u);
|
SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, Rect.right - Rect.left + 1, Rect.bottom - Rect.top + 1, SWP_NOREDRAW);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,20 +157,20 @@ int fullscrn::disableFullscreen()
|
|||||||
if (display_changed)
|
if (display_changed)
|
||||||
{
|
{
|
||||||
display_changed = 0;
|
display_changed = 0;
|
||||||
SmthFullScrnFlag2 = 1;
|
ignoreNextDisplayChangeFg = 1;
|
||||||
ChangeDisplaySettingsA(nullptr, 4u);
|
ChangeDisplaySettingsA(nullptr, CDS_FULLSCREEN);
|
||||||
if (trick)
|
if (trick)
|
||||||
SetWindowPos(hWnd, (HWND)-1, 0, 0, 0, 0, 0x13u);
|
SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
|
||||||
}
|
}
|
||||||
setWindowFlagsDisDlg();
|
setWindowFlagsDisDlg();
|
||||||
SetWindowPos(
|
SetWindowPos(
|
||||||
hWnd,
|
hWnd,
|
||||||
nullptr,
|
HWND_TOP,
|
||||||
WindowRect2.left,
|
WindowRect2.left,
|
||||||
WindowRect2.top,
|
WindowRect2.top,
|
||||||
WindowRect2.right - WindowRect2.left,
|
WindowRect2.right - WindowRect2.left,
|
||||||
WindowRect2.bottom - WindowRect2.top,
|
WindowRect2.bottom - WindowRect2.top,
|
||||||
0x14u);
|
SWP_NOZORDER | SWP_NOACTIVATE);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -242,9 +264,9 @@ void fullscrn::center_in(HWND parent, HWND child)
|
|||||||
int fullscrn::displaychange()
|
int fullscrn::displaychange()
|
||||||
{
|
{
|
||||||
int result = 0;
|
int result = 0;
|
||||||
if (SmthFullScrnFlag2)
|
if (ignoreNextDisplayChangeFg)
|
||||||
{
|
{
|
||||||
SmthFullScrnFlag2 = 0;
|
ignoreNextDisplayChangeFg = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -258,24 +280,24 @@ int fullscrn::displaychange()
|
|||||||
set_menu_mode(1);
|
set_menu_mode(1);
|
||||||
SetWindowPos(
|
SetWindowPos(
|
||||||
hWnd,
|
hWnd,
|
||||||
nullptr,
|
HWND_TOP,
|
||||||
WindowRect2.left,
|
WindowRect2.left,
|
||||||
WindowRect2.top,
|
WindowRect2.top,
|
||||||
WindowRect2.right - WindowRect2.left,
|
WindowRect2.right - WindowRect2.left,
|
||||||
WindowRect2.bottom - WindowRect2.top,
|
WindowRect2.bottom - WindowRect2.top,
|
||||||
0x1Cu);
|
SWP_NOZORDER | SWP_NOREDRAW | SWP_NOACTIVATE);
|
||||||
result = 1;
|
result = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SetWindowPos(
|
SetWindowPos(
|
||||||
hWnd,
|
hWnd,
|
||||||
nullptr,
|
HWND_TOP,
|
||||||
WindowRect2.left,
|
WindowRect2.left,
|
||||||
WindowRect2.top,
|
WindowRect2.top,
|
||||||
WindowRect2.right - WindowRect2.left,
|
WindowRect2.right - WindowRect2.left,
|
||||||
WindowRect2.bottom - WindowRect2.top,
|
WindowRect2.bottom - WindowRect2.top,
|
||||||
0x14u);
|
SWP_NOZORDER | SWP_NOACTIVATE);
|
||||||
}
|
}
|
||||||
center_in(GetDesktopWindow(), hWnd);
|
center_in(GetDesktopWindow(), hWnd);
|
||||||
}
|
}
|
||||||
@@ -289,50 +311,48 @@ void fullscrn::activate(int flag)
|
|||||||
if (!flag)
|
if (!flag)
|
||||||
{
|
{
|
||||||
set_screen_mode(0);
|
set_screen_mode(0);
|
||||||
SetWindowPos(hWnd, (HWND)1, 0, 0, 0, 0, 0x13u);
|
SetWindowPos(hWnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void fullscrn::fillRect(int right, int bottom)
|
void fullscrn::fillRect(int right, int bottom, int left, int top)
|
||||||
{
|
{
|
||||||
// Weird reg usage, should be zero
|
|
||||||
int v2 = 0;
|
|
||||||
int v3 = 0;
|
|
||||||
|
|
||||||
RECT rc;
|
RECT rc;
|
||||||
HGDIOBJ brush = CreateSolidBrush(0);
|
auto brush = CreateSolidBrush(0);
|
||||||
if (brush)
|
if (brush)
|
||||||
{
|
{
|
||||||
HDC dc = winmain::_GetDC(hWnd);
|
auto dc = winmain::_GetDC(hWnd);
|
||||||
HGDIOBJ brushHandle = SelectObject(dc, brush);
|
|
||||||
if (dc)
|
if (dc)
|
||||||
{
|
{
|
||||||
rc.right = right + v2 + 1;
|
auto prevBrush = SelectObject(dc, brush);
|
||||||
rc.bottom = bottom + v3 + 1;
|
rc.right = left + right + 1;
|
||||||
rc.left = v2;
|
rc.bottom = top + bottom + 1;
|
||||||
rc.top = v3;
|
rc.left = left;
|
||||||
FillRect(dc, &rc, static_cast<HBRUSH>(brush));
|
rc.top = top;
|
||||||
|
FillRect(dc, &rc, brush);
|
||||||
|
SelectObject(dc, prevBrush);
|
||||||
ReleaseDC(hWnd, dc);
|
ReleaseDC(hWnd, dc);
|
||||||
}
|
}
|
||||||
SelectObject(dc, brushHandle);
|
|
||||||
DeleteObject(brush);
|
DeleteObject(brush);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned fullscrn::convert_mouse_pos(unsigned int mouseXY)
|
unsigned fullscrn::convert_mouse_pos(unsigned int mouseXY)
|
||||||
{
|
{
|
||||||
unsigned __int16 x = mouseXY & 0xffFF - render::vscreen.XPosition;
|
uint16_t x = mouseXY & 0xffFF - render::vscreen.XPosition;
|
||||||
unsigned __int16 y = (mouseXY >> 16) - render::vscreen.YPosition;
|
uint16_t y = (mouseXY >> 16) - render::vscreen.YPosition;
|
||||||
return x | y << 16;
|
return x | y << 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fullscrn::getminmaxinfo(MINMAXINFO* maxMin)
|
void fullscrn::getminmaxinfo(MINMAXINFO* maxMin)
|
||||||
{
|
{
|
||||||
maxMin->ptMaxSize.x = WindowRect2.right - WindowRect2.left;
|
/*Block down-scaling lower than min resolution*/
|
||||||
maxMin->ptMaxSize.y = WindowRect2.bottom - WindowRect2.top;
|
maxMin->ptMinTrackSize = POINT
|
||||||
maxMin->ptMaxPosition.x = WindowRect2.left;
|
{
|
||||||
maxMin->ptMaxPosition.y = WindowRect2.top;
|
resolution_array[0].ScreenWidth / 2,
|
||||||
|
resolution_array[0].ScreenHeight / 2
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void fullscrn::paint()
|
void fullscrn::paint()
|
||||||
@@ -345,7 +365,7 @@ void fullscrn::paint()
|
|||||||
if (fullscrn_flag1 & 1)
|
if (fullscrn_flag1 & 1)
|
||||||
{
|
{
|
||||||
menuHeight = GetSystemMetrics(SM_CYMENU);
|
menuHeight = GetSystemMetrics(SM_CYMENU);
|
||||||
fillRect(WindowRect1.right - 1, menuHeight);
|
fillRect(WindowRect1.right - 1, menuHeight, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -354,9 +374,83 @@ void fullscrn::paint()
|
|||||||
menuHeight = GetSystemMetrics(SM_CYMENU);
|
menuHeight = GetSystemMetrics(SM_CYMENU);
|
||||||
else
|
else
|
||||||
menuHeight = 0;
|
menuHeight = 0;
|
||||||
fillRect(WindowRect1.right, menuHeight + WindowRect1.bottom);
|
fillRect(WindowRect1.right, menuHeight + WindowRect1.bottom, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
render::paint();
|
pb::paint();
|
||||||
fullscrn_flag1 = 0;
|
fullscrn_flag1 = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int fullscrn::GetResolution()
|
||||||
|
{
|
||||||
|
return resolution;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fullscrn::SetResolution(int resolution)
|
||||||
|
{
|
||||||
|
if (!pb::FullTiltMode)
|
||||||
|
resolution = 0;
|
||||||
|
assertm(resolution >= 0 && resolution <= 2, "Resolution value out of bounds");
|
||||||
|
fullscrn::resolution = resolution;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fullscrn::GetMaxResolution()
|
||||||
|
{
|
||||||
|
return maxResolution;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fullscrn::SetMaxResolution(int resolution)
|
||||||
|
{
|
||||||
|
assertm(resolution >= 0 && resolution <= 2, "Resolution value out of bounds");
|
||||||
|
maxResolution = resolution;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fullscrn::get_max_supported_resolution()
|
||||||
|
{
|
||||||
|
if (!pb::FullTiltMode)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
auto resolutionWH = get_screen_resolution();
|
||||||
|
auto width = LOWORD(resolutionWH);
|
||||||
|
auto height = HIWORD(resolutionWH);
|
||||||
|
auto result = 0;
|
||||||
|
|
||||||
|
for (auto index = 1; index < 3; ++index)
|
||||||
|
{
|
||||||
|
auto resPtr = &resolution_array[index];
|
||||||
|
if (resPtr->ScreenWidth <= width && resPtr->ScreenHeight <= height)
|
||||||
|
result = index;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fullscrn::get_screen_resolution()
|
||||||
|
{
|
||||||
|
auto height = static_cast<uint16_t>(GetSystemMetrics(SM_CYSCREEN));
|
||||||
|
return static_cast<uint16_t>(GetSystemMetrics(SM_CXSCREEN)) | (height << 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
void fullscrn::window_size_changed()
|
||||||
|
{
|
||||||
|
/*No scaling in fullscreen mode*/
|
||||||
|
if (display_changed)
|
||||||
|
{
|
||||||
|
ScaleY = ScaleX = 1;
|
||||||
|
OffsetX = OffsetY = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RECT client{};
|
||||||
|
GetClientRect(hWnd, &client);
|
||||||
|
auto res = &resolution_array[resolution];
|
||||||
|
ScaleX = static_cast<float>(client.right) / res->TableWidth;
|
||||||
|
ScaleY = static_cast<float>(client.bottom) / res->TableHeight;
|
||||||
|
OffsetX = OffsetY = 0;
|
||||||
|
|
||||||
|
if (options::Options.UniformScaling)
|
||||||
|
{
|
||||||
|
ScaleY = ScaleX = min(ScaleX, ScaleY);
|
||||||
|
OffsetX = static_cast<int>(floor((client.right - res->TableWidth * ScaleX) / 2));
|
||||||
|
OffsetY = static_cast<int>(floor((client.bottom - res->TableHeight * ScaleY) / 2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,6 +5,16 @@
|
|||||||
#define BYTE1(x) BYTEn(x, 1) // byte 1 (counting from 0)
|
#define BYTE1(x) BYTEn(x, 1) // byte 1 (counting from 0)
|
||||||
#define BYTE2(x) BYTEn(x, 2)
|
#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
|
class fullscrn
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -15,8 +25,13 @@ public:
|
|||||||
static rectangle_type WHRect;
|
static rectangle_type WHRect;
|
||||||
static int fullscrn_flag1;
|
static int fullscrn_flag1;
|
||||||
static int display_changed;
|
static int display_changed;
|
||||||
static int ChangeDisplay, SmthFullScrnFlag2;
|
static int ChangeDisplay, ignoreNextDisplayChangeFg;
|
||||||
static int trick;
|
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(int width, int height, int isFullscreen, HWND winHandle, HMENU menuHandle, int changeDisplay);
|
||||||
static void shutdown();
|
static void shutdown();
|
||||||
@@ -29,14 +44,23 @@ public:
|
|||||||
static void getminmaxinfo(MINMAXINFO* maxMin);
|
static void getminmaxinfo(MINMAXINFO* maxMin);
|
||||||
static void paint();
|
static void paint();
|
||||||
static bool set_menu_mode(int menuEnabled);
|
static bool set_menu_mode(int menuEnabled);
|
||||||
|
static int GetResolution();
|
||||||
|
static void SetResolution(int resolution);
|
||||||
|
static int GetMaxResolution();
|
||||||
|
static void SetMaxResolution(int resolution);
|
||||||
|
static int get_max_supported_resolution();
|
||||||
|
static int get_screen_resolution();
|
||||||
|
static void window_size_changed();
|
||||||
private :
|
private :
|
||||||
static int MenuEnabled;
|
static int MenuEnabled;
|
||||||
static HMENU MenuHandle;
|
static HMENU MenuHandle;
|
||||||
|
static int resolution;
|
||||||
|
static int maxResolution;
|
||||||
|
|
||||||
static void GetWindowCenter();
|
static void GetWindowCenter();
|
||||||
static int disableWindowFlagsDisDlg();
|
static int disableWindowFlagsDisDlg();
|
||||||
static int setWindowFlagsDisDlg();
|
static int setWindowFlagsDisDlg();
|
||||||
static int enableFullscreen();
|
static int enableFullscreen();
|
||||||
static int disableFullscreen();
|
static int disableFullscreen();
|
||||||
static void fillRect(int right, int bottom);
|
static void fillRect(int right, int bottom, int left, int top);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
#include "gdrv.h"
|
#include "gdrv.h"
|
||||||
|
|
||||||
|
#include "fullscrn.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
#include "options.h"
|
||||||
#include "pinball.h"
|
#include "pinball.h"
|
||||||
#include "winmain.h"
|
#include "winmain.h"
|
||||||
|
|
||||||
HPALETTE gdrv::palette_handle = nullptr;
|
HPALETTE gdrv::palette_handle = nullptr;
|
||||||
HINSTANCE gdrv::hinst;
|
HINSTANCE gdrv::hinst;
|
||||||
HWND gdrv::hwnd;
|
HWND gdrv::hwnd;
|
||||||
LOGPALETTEx256 gdrv::current_palette{};
|
|
||||||
int gdrv::sequence_handle;
|
int gdrv::sequence_handle;
|
||||||
HDC gdrv::sequence_hdc;
|
HDC gdrv::sequence_hdc;
|
||||||
int gdrv::use_wing = 0;
|
int gdrv::use_wing = 0;
|
||||||
@@ -18,10 +20,12 @@ int gdrv::grtext_red = -1;
|
|||||||
|
|
||||||
int gdrv::init(HINSTANCE hInst, HWND hWnd)
|
int gdrv::init(HINSTANCE hInst, HWND hWnd)
|
||||||
{
|
{
|
||||||
|
LOGPALETTEx256 current_palette{};
|
||||||
|
|
||||||
hinst = hInst;
|
hinst = hInst;
|
||||||
hwnd = hWnd;
|
hwnd = hWnd;
|
||||||
if (!palette_handle)
|
if (!palette_handle)
|
||||||
palette_handle = CreatePalette((LOGPALETTE*)¤t_palette);
|
palette_handle = CreatePalette(¤t_palette);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,17 +41,16 @@ void gdrv::get_focus()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BITMAPINFO* gdrv::DibCreate(__int16 bpp, int width, int height)
|
BITMAPINFO* gdrv::DibCreate(int16_t bpp, int width, int height)
|
||||||
{
|
{
|
||||||
auto sizeBytes = height * ((width * bpp / 8 + 3) & 0xFFFFFFFC);
|
auto sizeBytes = height * (width * bpp / 8 + 3 & (~3));
|
||||||
auto buf = GlobalAlloc(0x42u, sizeBytes + 1064);
|
auto dib = memory::allocate<BITMAPINFO>(1, (256 - 1) * sizeof(RGBQUAD) + sizeBytes);
|
||||||
auto dib = static_cast<BITMAPINFO*>(GlobalLock(buf));
|
|
||||||
|
|
||||||
if (!dib)
|
if (!dib)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
dib->bmiHeader.biSizeImage = sizeBytes;
|
dib->bmiHeader.biSizeImage = sizeBytes;
|
||||||
dib->bmiHeader.biWidth = width;
|
dib->bmiHeader.biWidth = width;
|
||||||
dib->bmiHeader.biSize = 40;
|
dib->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||||
dib->bmiHeader.biHeight = height;
|
dib->bmiHeader.biHeight = height;
|
||||||
dib->bmiHeader.biPlanes = 1;
|
dib->bmiHeader.biPlanes = 1;
|
||||||
dib->bmiHeader.biBitCount = bpp;
|
dib->bmiHeader.biBitCount = bpp;
|
||||||
@@ -65,25 +68,15 @@ BITMAPINFO* gdrv::DibCreate(__int16 bpp, int width, int height)
|
|||||||
dib->bmiHeader.biClrUsed = 256;
|
dib->bmiHeader.biClrUsed = 256;
|
||||||
}
|
}
|
||||||
|
|
||||||
int index = 0;
|
|
||||||
for (auto i = (int*)dib->bmiColors; index < static_cast<signed int>(dib->bmiHeader.biClrUsed) / 16; ++index)
|
uint32_t paletteColors[]
|
||||||
{
|
{
|
||||||
*i++ = 0;
|
0, 0x800000, 0x8000, 8421376, 128, 8388736, 32896, 12632256,
|
||||||
*i++ = 0x800000;
|
8421504, 16711680, 65280, 16776960, 255, 16711935, 0xFFFF, 0xFFFFFF,
|
||||||
*i++ = 0x8000;
|
};
|
||||||
*i++ = 8421376;
|
for (auto index = 0u; index < dib->bmiHeader.biClrUsed; index += 16)
|
||||||
*i++ = 128;
|
{
|
||||||
*i++ = 8388736;
|
memcpy(&dib->bmiColors[index], paletteColors, sizeof paletteColors);
|
||||||
*i++ = 32896;
|
|
||||||
*i++ = 12632256;
|
|
||||||
*i++ = 8421504;
|
|
||||||
*i++ = 16711680;
|
|
||||||
*i++ = 65280;
|
|
||||||
*i++ = 16776960;
|
|
||||||
*i++ = 255;
|
|
||||||
*i++ = 16711935;
|
|
||||||
*i++ = 0xFFFF;
|
|
||||||
*i++ = 0xFFFFFF;
|
|
||||||
}
|
}
|
||||||
return dib;
|
return dib;
|
||||||
}
|
}
|
||||||
@@ -108,31 +101,24 @@ void gdrv::DibSetUsage(BITMAPINFO* dib, HPALETTE hpal, int someFlag)
|
|||||||
{
|
{
|
||||||
if (someFlag && someFlag <= 2)
|
if (someFlag && someFlag <= 2)
|
||||||
{
|
{
|
||||||
auto pltPtr = (short*)((char*)dib + dib->bmiHeader.biSize);
|
auto pltPtr = reinterpret_cast<short*>(dib->bmiColors);
|
||||||
for (int i = 0; i < numOfColors; ++i)
|
for (auto i = 0; i < numOfColors; ++i)
|
||||||
{
|
{
|
||||||
*pltPtr++ = i;
|
*pltPtr++ = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
assertm(false, "Entered bad code");
|
|
||||||
char* dibPtr = (char*)dib + dib->bmiHeader.biSize;
|
|
||||||
if (numOfColors >= 256)
|
if (numOfColors >= 256)
|
||||||
numOfColors = 256;
|
numOfColors = 256;
|
||||||
GetPaletteEntries(hpal, 0, numOfColors, pPalEntries);
|
GetPaletteEntries(hpal, 0, numOfColors, pPalEntries);
|
||||||
int index = 0;
|
for (auto index = 0; index < numOfColors; index++)
|
||||||
char* dibPtr2 = dibPtr + 1;
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
char v9 = pPalEntries[index++].peRed;
|
dib->bmiColors[index].rgbRed = pPalEntries[index].peRed;
|
||||||
dibPtr2[1] = v9;
|
dib->bmiColors[index].rgbGreen = pPalEntries[index].peGreen;
|
||||||
*dibPtr2 = dibPtr2[(char*)pPalEntries - dibPtr];
|
dib->bmiColors[index].rgbBlue = pPalEntries[index].peBlue;
|
||||||
*(dibPtr2 - 1) = dibPtr2[&pPalEntries[0].peGreen - (unsigned char*)dibPtr];
|
dib->bmiColors[index].rgbReserved = 0;
|
||||||
dibPtr2[2] = 0;
|
|
||||||
dibPtr2 += 4;
|
|
||||||
}
|
}
|
||||||
while (index < numOfColors);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -156,7 +142,7 @@ int gdrv::create_bitmap_dib(gdrv_bitmap8* bmp, int width, int height)
|
|||||||
if (dib->bmiHeader.biCompression == 3)
|
if (dib->bmiHeader.biCompression == 3)
|
||||||
bmpBufPtr = (char*)&dib->bmiHeader.biPlanes + dib->bmiHeader.biSize;
|
bmpBufPtr = (char*)&dib->bmiHeader.biPlanes + dib->bmiHeader.biSize;
|
||||||
else
|
else
|
||||||
bmpBufPtr = (char*)&dib->bmiHeader.biSize + 4 * dib->bmiHeader.biClrUsed + dib->bmiHeader.biSize;
|
bmpBufPtr = reinterpret_cast<char*>(&dib->bmiColors[dib->bmiHeader.biClrUsed]);
|
||||||
bmp->BmpBufPtr1 = bmpBufPtr;
|
bmp->BmpBufPtr1 = bmpBufPtr;
|
||||||
bmp->BmpBufPtr2 = bmpBufPtr;
|
bmp->BmpBufPtr2 = bmpBufPtr;
|
||||||
return 0;
|
return 0;
|
||||||
@@ -185,20 +171,37 @@ int gdrv::create_raw_bitmap(gdrv_bitmap8* bmp, int width, int height, int flag)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int gdrv::create_spliced_bitmap(gdrv_bitmap8* bmp, int width, int height, int size)
|
||||||
|
{
|
||||||
|
bmp->Dib = nullptr;
|
||||||
|
bmp->Width = width;
|
||||||
|
bmp->Stride = width;
|
||||||
|
bmp->BitmapType = BitmapType::Spliced;
|
||||||
|
bmp->Height = height;
|
||||||
|
char* buf = memory::allocate(size);
|
||||||
|
bmp->BmpBufPtr1 = buf;
|
||||||
|
if (!buf)
|
||||||
|
return -1;
|
||||||
|
bmp->BmpBufPtr2 = bmp->BmpBufPtr1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int gdrv::display_palette(PALETTEENTRY* plt)
|
int gdrv::display_palette(PALETTEENTRY* plt)
|
||||||
{
|
{
|
||||||
|
LOGPALETTEx256 current_palette{};
|
||||||
|
|
||||||
if (palette_handle)
|
if (palette_handle)
|
||||||
DeleteObject(palette_handle);
|
DeleteObject(palette_handle);
|
||||||
palette_handle = CreatePalette((LOGPALETTE*)¤t_palette);
|
palette_handle = CreatePalette(¤t_palette);
|
||||||
auto windowHandle = GetDesktopWindow();
|
auto windowHandle = GetDesktopWindow();
|
||||||
auto dc = winmain::_GetDC(windowHandle);
|
auto dc = winmain::_GetDC(windowHandle);
|
||||||
SetSystemPaletteUse(dc, 2u);
|
SetSystemPaletteUse(dc, 2u);
|
||||||
SetSystemPaletteUse(dc, 1u);
|
SetSystemPaletteUse(dc, 1u);
|
||||||
auto pltHandle = SelectPalette(dc, palette_handle, 0);
|
auto originalPalette = SelectPalette(dc, palette_handle, 0);
|
||||||
RealizePalette(dc);
|
RealizePalette(dc);
|
||||||
SelectPalette(dc, pltHandle, 0);
|
SelectPalette(dc, originalPalette, 0);
|
||||||
GetSystemPaletteEntries(dc, 0, 0x100u, current_palette.palPalEntry);
|
GetSystemPaletteEntries(dc, 0, 256, current_palette.palPalEntry);
|
||||||
for (int i = 0; i < 256; i++)
|
for (int i = 0; i < 256; i++)
|
||||||
{
|
{
|
||||||
current_palette.palPalEntry[i].peFlags = 0;
|
current_palette.palPalEntry[i].peFlags = 0;
|
||||||
@@ -219,15 +222,15 @@ int gdrv::display_palette(PALETTEENTRY* plt)
|
|||||||
pltDst++;
|
pltDst++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(GetDeviceCaps(dc, 38) & 0x100))
|
if (!(GetDeviceCaps(dc, RASTERCAPS) & RC_PALETTE))
|
||||||
{
|
{
|
||||||
current_palette.palPalEntry[255].peBlue = -1;
|
current_palette.palPalEntry[255].peBlue = -1;
|
||||||
current_palette.palPalEntry[255].peGreen = -1;
|
current_palette.palPalEntry[255].peGreen = -1;
|
||||||
current_palette.palPalEntry[255].peRed = -1;
|
current_palette.palPalEntry[255].peRed = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResizePalette(palette_handle, 0x100u);
|
ResizePalette(palette_handle, 256);
|
||||||
SetPaletteEntries(palette_handle, 0, 0x100u, current_palette.palPalEntry);
|
SetPaletteEntries(palette_handle, 0, 256, current_palette.palPalEntry);
|
||||||
windowHandle = GetDesktopWindow();
|
windowHandle = GetDesktopWindow();
|
||||||
ReleaseDC(windowHandle, dc);
|
ReleaseDC(windowHandle, dc);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -238,32 +241,32 @@ int gdrv::destroy_bitmap(gdrv_bitmap8* bmp)
|
|||||||
{
|
{
|
||||||
if (!bmp)
|
if (!bmp)
|
||||||
return -1;
|
return -1;
|
||||||
if (bmp->BitmapType == BitmapType::RawBitmap)
|
if (bmp->BitmapType == BitmapType::RawBitmap || bmp->BitmapType == BitmapType::Spliced)
|
||||||
{
|
{
|
||||||
memory::free(bmp->BmpBufPtr1);
|
memory::free(bmp->BmpBufPtr1);
|
||||||
}
|
}
|
||||||
else if (bmp->BitmapType == BitmapType::DibBitmap)
|
else if (bmp->BitmapType == BitmapType::DibBitmap)
|
||||||
{
|
{
|
||||||
GlobalUnlock(GlobalHandle(bmp->Dib));
|
memory::free(bmp->Dib);
|
||||||
GlobalFree(GlobalHandle(bmp->Dib));
|
|
||||||
}
|
}
|
||||||
memset(bmp, 0, sizeof(gdrv_bitmap8));
|
memset(bmp, 0, sizeof(gdrv_bitmap8));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT gdrv::start_blit_sequence()
|
void gdrv::start_blit_sequence()
|
||||||
{
|
{
|
||||||
HDC dc = winmain::_GetDC(hwnd);
|
HDC dc = winmain::_GetDC(hwnd);
|
||||||
sequence_handle = 0;
|
sequence_handle = 0;
|
||||||
sequence_hdc = dc;
|
sequence_hdc = dc;
|
||||||
SelectPalette(dc, palette_handle, 0);
|
SelectPalette(dc, palette_handle, 0);
|
||||||
return RealizePalette(sequence_hdc);
|
RealizePalette(sequence_hdc);
|
||||||
|
SetStretchBltMode(dc, stretchMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gdrv::blit_sequence(gdrv_bitmap8* bmp, int xSrc, int ySrcOff, int xDest, int yDest, int DestWidth, int DestHeight)
|
void gdrv::blit_sequence(gdrv_bitmap8* bmp, int xSrc, int ySrcOff, int xDest, int yDest, int DestWidth, int DestHeight)
|
||||||
{
|
{
|
||||||
if (!use_wing)
|
if (!use_wing)
|
||||||
StretchDIBits(
|
StretchDIBitsScaled(
|
||||||
sequence_hdc,
|
sequence_hdc,
|
||||||
xDest,
|
xDest,
|
||||||
yDest,
|
yDest,
|
||||||
@@ -273,10 +276,10 @@ void gdrv::blit_sequence(gdrv_bitmap8* bmp, int xSrc, int ySrcOff, int xDest, in
|
|||||||
bmp->Height - ySrcOff - DestHeight,
|
bmp->Height - ySrcOff - DestHeight,
|
||||||
DestWidth,
|
DestWidth,
|
||||||
DestHeight,
|
DestHeight,
|
||||||
bmp->BmpBufPtr1,
|
bmp,
|
||||||
bmp->Dib,
|
DIB_PAL_COLORS,
|
||||||
1u,
|
SRCCOPY
|
||||||
SRCCOPY);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -285,28 +288,29 @@ void gdrv::end_blit_sequence()
|
|||||||
ReleaseDC(hwnd, sequence_hdc);
|
ReleaseDC(hwnd, sequence_hdc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gdrv::blit(gdrv_bitmap8* bmp, int xSrc, int ySrcOff, int xDest, int yDest, int DestWidth, int DestHeight)
|
void gdrv::blit(gdrv_bitmap8* bmp, int xSrc, int ySrc, int xDest, int yDest, int DestWidth, int DestHeight)
|
||||||
{
|
{
|
||||||
HDC dc = winmain::_GetDC(hwnd);
|
HDC dc = winmain::_GetDC(hwnd);
|
||||||
|
SetStretchBltMode(dc, stretchMode);
|
||||||
if (dc)
|
if (dc)
|
||||||
{
|
{
|
||||||
SelectPalette(dc, palette_handle, 0);
|
SelectPalette(dc, palette_handle, 0);
|
||||||
RealizePalette(dc);
|
RealizePalette(dc);
|
||||||
if (!use_wing)
|
if (!use_wing)
|
||||||
StretchDIBits(
|
StretchDIBitsScaled(
|
||||||
dc,
|
dc,
|
||||||
xDest,
|
xDest,
|
||||||
yDest,
|
yDest,
|
||||||
DestWidth,
|
DestWidth,
|
||||||
DestHeight,
|
DestHeight,
|
||||||
xSrc,
|
xSrc,
|
||||||
bmp->Height - ySrcOff - DestHeight,
|
bmp->Height - ySrc - DestHeight,
|
||||||
DestWidth,
|
DestWidth,
|
||||||
DestHeight,
|
DestHeight,
|
||||||
bmp->BmpBufPtr1,
|
bmp,
|
||||||
bmp->Dib,
|
DIB_PAL_COLORS,
|
||||||
1u,
|
SRCCOPY
|
||||||
SRCCOPY);
|
);
|
||||||
ReleaseDC(hwnd, dc);
|
ReleaseDC(hwnd, dc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -314,10 +318,30 @@ void gdrv::blit(gdrv_bitmap8* bmp, int xSrc, int ySrcOff, int xDest, int yDest,
|
|||||||
void gdrv::blat(gdrv_bitmap8* bmp, int xDest, int yDest)
|
void gdrv::blat(gdrv_bitmap8* bmp, int xDest, int yDest)
|
||||||
{
|
{
|
||||||
HDC dc = winmain::_GetDC(hwnd);
|
HDC dc = winmain::_GetDC(hwnd);
|
||||||
|
|
||||||
|
// Black background for uniform scaling
|
||||||
|
if (fullscrn::OffsetX > 0 || fullscrn::OffsetY > 0)
|
||||||
|
{
|
||||||
|
const auto rop = BLACKNESS;
|
||||||
|
RECT client{};
|
||||||
|
GetClientRect(hwnd, &client);
|
||||||
|
if (fullscrn::OffsetX > 0)
|
||||||
|
{
|
||||||
|
BitBlt(dc, 0, 0, min(fullscrn::OffsetX + 2, client.right), client.bottom, dc, 0, 0, rop);
|
||||||
|
BitBlt(dc, max(client.right - fullscrn::OffsetX - 2, 0), 0, client.right, client.bottom, dc, 0, 0, rop);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BitBlt(dc, 0, 0, client.right, min(fullscrn::OffsetY + 2, client.bottom), dc, 0, 0, rop);
|
||||||
|
BitBlt(dc, 0, max(client.bottom - fullscrn::OffsetY - 2, 0), client.right, client.bottom, dc, 0, 0, rop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SelectPalette(dc, palette_handle, 0);
|
SelectPalette(dc, palette_handle, 0);
|
||||||
RealizePalette(dc);
|
RealizePalette(dc);
|
||||||
|
SetStretchBltMode(dc, stretchMode);
|
||||||
if (!use_wing)
|
if (!use_wing)
|
||||||
StretchDIBits(
|
StretchDIBitsScaled(
|
||||||
dc,
|
dc,
|
||||||
xDest,
|
xDest,
|
||||||
yDest,
|
yDest,
|
||||||
@@ -327,10 +351,10 @@ void gdrv::blat(gdrv_bitmap8* bmp, int xDest, int yDest)
|
|||||||
0,
|
0,
|
||||||
bmp->Width,
|
bmp->Width,
|
||||||
bmp->Height,
|
bmp->Height,
|
||||||
bmp->BmpBufPtr1,
|
bmp,
|
||||||
bmp->Dib,
|
DIB_PAL_COLORS,
|
||||||
1u,
|
SRCCOPY
|
||||||
SRCCOPY);
|
);
|
||||||
ReleaseDC(hwnd, dc);
|
ReleaseDC(hwnd, dc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -340,16 +364,11 @@ void gdrv::fill_bitmap(gdrv_bitmap8* bmp, int width, int height, int xOff, int y
|
|||||||
if (bmpHeight < 0)
|
if (bmpHeight < 0)
|
||||||
bmpHeight = -bmpHeight;
|
bmpHeight = -bmpHeight;
|
||||||
char* bmpPtr = &bmp->BmpBufPtr1[bmp->Width * (bmpHeight - height - yOff) + xOff];
|
char* bmpPtr = &bmp->BmpBufPtr1[bmp->Width * (bmpHeight - height - yOff) + xOff];
|
||||||
if (height > 0)
|
for (; height > 0; --height)
|
||||||
{
|
{
|
||||||
do
|
if (width > 0)
|
||||||
{
|
memset(bmpPtr, fillChar, width);
|
||||||
if (width > 0)
|
bmpPtr += bmp->Stride;
|
||||||
memset(bmpPtr, fillChar, width);
|
|
||||||
bmpPtr += bmp->Stride;
|
|
||||||
--height;
|
|
||||||
}
|
|
||||||
while (height);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -395,11 +414,24 @@ void gdrv::copy_bitmap_w_transparency(gdrv_bitmap8* dstBmp, int width, int heigh
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void gdrv::grtext_draw_ttext_in_box(LPCSTR text, int xOff, int yOff, int width, int height, int a6)
|
void gdrv::grtext_draw_ttext_in_box(LPCWSTR text, int xOff, int yOff, int width, int height)
|
||||||
{
|
{
|
||||||
tagRECT rc{};
|
// Original font was 16 points, used with lowest table resolution
|
||||||
|
static const int fontSizes[3] =
|
||||||
|
{
|
||||||
|
16,
|
||||||
|
22,
|
||||||
|
28
|
||||||
|
};
|
||||||
|
|
||||||
|
xOff = static_cast<int>(xOff * fullscrn::ScaleX) + fullscrn::OffsetX;
|
||||||
|
yOff = static_cast<int>(yOff * fullscrn::ScaleY) + fullscrn::OffsetY;
|
||||||
|
width = static_cast<int>(width * fullscrn::ScaleX);
|
||||||
|
height = static_cast<int>(height * fullscrn::ScaleY);
|
||||||
|
auto fontSize = static_cast<int>(round(fontSizes[fullscrn::GetResolution()] * fullscrn::ScaleY));
|
||||||
|
|
||||||
HDC dc = GetDC(hwnd);
|
HDC dc = GetDC(hwnd);
|
||||||
|
tagRECT rc{};
|
||||||
rc.left = xOff;
|
rc.left = xOff;
|
||||||
rc.right = width + xOff;
|
rc.right = width + xOff;
|
||||||
rc.top = yOff;
|
rc.top = yOff;
|
||||||
@@ -413,10 +445,78 @@ void gdrv::grtext_draw_ttext_in_box(LPCSTR text, int xOff, int yOff, int width,
|
|||||||
if (fontColor)
|
if (fontColor)
|
||||||
sscanf_s(fontColor, "%d %d %d", &grtext_red, &grtext_green, &grtext_blue);
|
sscanf_s(fontColor, "%d %d %d", &grtext_red, &grtext_green, &grtext_blue);
|
||||||
}
|
}
|
||||||
int prevMode = SetBkMode(dc, 1);
|
|
||||||
COLORREF color = SetTextColor(dc, (grtext_red) | (grtext_green << 8) | (grtext_blue << 16));
|
const char* font;
|
||||||
DrawTextA(dc, text, lstrlenA(text), &rc, 0x810u);
|
switch (options::Options.Language)
|
||||||
|
{
|
||||||
|
case Languages::TraditionalChinese:
|
||||||
|
font = "Microsoft JhengHei";
|
||||||
|
break;
|
||||||
|
case Languages::SimplifiedChinese:
|
||||||
|
font = "Microsoft YaHei";
|
||||||
|
break;
|
||||||
|
case Languages::Japanese:
|
||||||
|
font = "MS UI Gothic";
|
||||||
|
break;
|
||||||
|
case Languages::Korean:
|
||||||
|
font = "Gulim";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
font = "Arial";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default font does not scale well
|
||||||
|
auto hNewFont = CreateFont(fontSize, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE,
|
||||||
|
DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
|
||||||
|
DEFAULT_PITCH | FF_SWISS, font);
|
||||||
|
HFONT hOldFont = static_cast<HFONT>(SelectObject(dc, hNewFont));
|
||||||
|
int prevMode = SetBkMode(dc, TRANSPARENT);
|
||||||
|
COLORREF color = SetTextColor(dc, grtext_red | grtext_green << 8 | grtext_blue << 16);
|
||||||
|
|
||||||
|
DrawTextW(dc, text, lstrlenW(text), &rc, DT_NOPREFIX | DT_WORDBREAK);
|
||||||
|
|
||||||
|
SelectObject(dc, hOldFont);
|
||||||
|
DeleteObject(hNewFont);
|
||||||
SetBkMode(dc, prevMode);
|
SetBkMode(dc, prevMode);
|
||||||
SetTextColor(dc, color);
|
SetTextColor(dc, color);
|
||||||
ReleaseDC(hwnd, dc);
|
ReleaseDC(hwnd, dc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int gdrv::StretchDIBitsScaled(HDC hdc, int xDest, int yDest, int DestWidth, int DestHeight, int xSrc, int ySrc,
|
||||||
|
int SrcWidth, int SrcHeight, gdrv_bitmap8* bmp, UINT iUsage,
|
||||||
|
DWORD rop)
|
||||||
|
{
|
||||||
|
/*Scaled partial updates may leave 1px border artifacts around update area.
|
||||||
|
* Pad update area to compensate.*/
|
||||||
|
const int pad = 1, padX2 = pad * 2;
|
||||||
|
if (fullscrn::ScaleX > 1 && xSrc > pad && xSrc + pad < bmp->Width)
|
||||||
|
{
|
||||||
|
xSrc -= pad;
|
||||||
|
xDest -= pad;
|
||||||
|
SrcWidth += padX2;
|
||||||
|
DestWidth += padX2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fullscrn::ScaleY > 1 && ySrc > pad && ySrc + pad < bmp->Height)
|
||||||
|
{
|
||||||
|
ySrc -= pad;
|
||||||
|
yDest -= pad;
|
||||||
|
SrcHeight += padX2;
|
||||||
|
DestHeight += padX2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return StretchDIBits(
|
||||||
|
hdc,
|
||||||
|
static_cast<int>(round(xDest * fullscrn::ScaleX + fullscrn::OffsetX)),
|
||||||
|
static_cast<int>(round(yDest * fullscrn::ScaleY + fullscrn::OffsetY)),
|
||||||
|
static_cast<int>(round(DestWidth * fullscrn::ScaleX)),
|
||||||
|
static_cast<int>(round(DestHeight * fullscrn::ScaleY)),
|
||||||
|
xSrc,
|
||||||
|
ySrc,
|
||||||
|
SrcWidth,
|
||||||
|
SrcHeight,
|
||||||
|
bmp->BmpBufPtr1,
|
||||||
|
bmp->Dib,
|
||||||
|
iUsage,
|
||||||
|
rop);
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ enum class BitmapType : char
|
|||||||
None = 0,
|
None = 0,
|
||||||
RawBitmap = 1,
|
RawBitmap = 1,
|
||||||
DibBitmap = 2,
|
DibBitmap = 2,
|
||||||
|
Spliced = 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct gdrv_bitmap8
|
struct gdrv_bitmap8
|
||||||
@@ -21,14 +22,14 @@ struct gdrv_bitmap8
|
|||||||
int YPosition;
|
int YPosition;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LOGPALETTEx256
|
struct LOGPALETTEx256 : LOGPALETTE
|
||||||
{
|
{
|
||||||
WORD palVersion;
|
PALETTEENTRY palPalEntry2[256 - 1];
|
||||||
WORD palNumEntries;
|
|
||||||
PALETTEENTRY palPalEntry[256];
|
|
||||||
|
|
||||||
LOGPALETTEx256() : palVersion(0x300), palNumEntries(256), palPalEntry{}
|
LOGPALETTEx256() : palPalEntry2{}
|
||||||
{
|
{
|
||||||
|
palVersion = 0x300;
|
||||||
|
palNumEntries = 256;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -37,7 +38,6 @@ class gdrv
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static HPALETTE palette_handle;
|
static HPALETTE palette_handle;
|
||||||
static LOGPALETTEx256 current_palette;
|
|
||||||
static int sequence_handle;
|
static int sequence_handle;
|
||||||
static HDC sequence_hdc;
|
static HDC sequence_hdc;
|
||||||
static int use_wing;
|
static int use_wing;
|
||||||
@@ -45,14 +45,15 @@ public:
|
|||||||
static int init(HINSTANCE hInst, HWND hWnd);
|
static int init(HINSTANCE hInst, HWND hWnd);
|
||||||
static int uninit();
|
static int uninit();
|
||||||
static void get_focus();
|
static void get_focus();
|
||||||
static BITMAPINFO* DibCreate(__int16 bpp, int width, int height);
|
static BITMAPINFO* DibCreate(int16_t bpp, int width, int height);
|
||||||
static void DibSetUsage(BITMAPINFO* dib, HPALETTE hpal, int someFlag);
|
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_dib(gdrv_bitmap8* bmp, int width, int height);
|
||||||
static int create_bitmap(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 create_raw_bitmap(gdrv_bitmap8* bmp, int width, int height, int flag);
|
||||||
|
static int create_spliced_bitmap(gdrv_bitmap8* bmp, int width, int height, int size);
|
||||||
static int destroy_bitmap(gdrv_bitmap8* bmp);
|
static int destroy_bitmap(gdrv_bitmap8* bmp);
|
||||||
static int display_palette(PALETTEENTRY* plt);
|
static int display_palette(PALETTEENTRY* plt);
|
||||||
static UINT start_blit_sequence();
|
static void start_blit_sequence();
|
||||||
static void blit_sequence(gdrv_bitmap8* bmp, int xSrc, int ySrcOff, int xDest, int yDest, int DestWidth,
|
static void blit_sequence(gdrv_bitmap8* bmp, int xSrc, int ySrcOff, int xDest, int yDest, int DestWidth,
|
||||||
int DestHeight);
|
int DestHeight);
|
||||||
static void end_blit_sequence();
|
static void end_blit_sequence();
|
||||||
@@ -63,11 +64,17 @@ public:
|
|||||||
int srcXOff, int srcYOff);
|
int srcXOff, int srcYOff);
|
||||||
static void copy_bitmap_w_transparency(gdrv_bitmap8* dstBmp, int width, int height, int xOff, int yOff,
|
static void copy_bitmap_w_transparency(gdrv_bitmap8* dstBmp, int width, int height, int xOff, int yOff,
|
||||||
gdrv_bitmap8* srcBmp, int srcXOff, int srcYOff);
|
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 grtext_draw_ttext_in_box(LPCWSTR text, int xOff, int yOff, int width, int height);
|
||||||
private:
|
private:
|
||||||
|
/*COLORONCOLOR or HALFTONE*/
|
||||||
|
static const int stretchMode = COLORONCOLOR;
|
||||||
static HWND hwnd;
|
static HWND hwnd;
|
||||||
static HINSTANCE hinst;
|
static HINSTANCE hinst;
|
||||||
static int grtext_blue;
|
static int grtext_blue;
|
||||||
static int grtext_green;
|
static int grtext_green;
|
||||||
static int grtext_red;
|
static int grtext_red;
|
||||||
|
|
||||||
|
static int StretchDIBitsScaled(HDC hdc, int xDest, int yDest, int DestWidth, int DestHeight, int xSrc, int ySrc,
|
||||||
|
int SrcWidth, int SrcHeight, gdrv_bitmap8* bmp, UINT iUsage,
|
||||||
|
DWORD rop);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -9,8 +9,8 @@
|
|||||||
|
|
||||||
int high_score::dlg_enter_name;
|
int high_score::dlg_enter_name;
|
||||||
int high_score::dlg_score;
|
int high_score::dlg_score;
|
||||||
int high_score::position;
|
int high_score::dlg_position;
|
||||||
LPCSTR high_score::default_name;
|
LPCWSTR high_score::default_name;
|
||||||
high_score_struct* high_score::dlg_hst;
|
high_score_struct* high_score::dlg_hst;
|
||||||
|
|
||||||
winhelp_entry high_score::help[21]
|
winhelp_entry high_score::help[21]
|
||||||
@@ -40,7 +40,8 @@ winhelp_entry high_score::help[21]
|
|||||||
|
|
||||||
int high_score::read(high_score_struct* table, int* ptrToSmth)
|
int high_score::read(high_score_struct* table, int* ptrToSmth)
|
||||||
{
|
{
|
||||||
char Buffer[20];
|
char scoreBuffer[20];
|
||||||
|
wchar_t nameBuffer[20];
|
||||||
|
|
||||||
int scoreSum = 0;
|
int scoreSum = 0;
|
||||||
clear_table(table);
|
clear_table(table);
|
||||||
@@ -48,30 +49,26 @@ int high_score::read(high_score_struct* table, int* ptrToSmth)
|
|||||||
if (!buf1)
|
if (!buf1)
|
||||||
return 1;
|
return 1;
|
||||||
char* buf2 = memory::allocate(300u);
|
char* buf2 = memory::allocate(300u);
|
||||||
int position = 0;
|
auto optPath = pinball::get_rc_string(166, 0);
|
||||||
high_score_struct* tablePtr = table;
|
for (auto position = 0; position < 5; ++position)
|
||||||
const CHAR* optPath = pinball::get_rc_string(166, 0);
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
_itoa_s(position, Buffer, 10);
|
auto tablePtr = &table[position];
|
||||||
lstrcatA(Buffer, ".Name");
|
|
||||||
options::get_string(optPath, Buffer, buf1, pinball::WindowName, 32);
|
wsprintfW(nameBuffer, L"%d.Name", position);
|
||||||
buf1[32] = 0;
|
options::get_string(optPath, nameBuffer, tablePtr->Name, L"", 32);
|
||||||
lstrcpyA(tablePtr->Name, buf1);
|
tablePtr->Name[31] = 0;
|
||||||
_itoa_s(position, Buffer, 10);
|
|
||||||
lstrcatA(Buffer, ".Score");
|
sprintf_s(scoreBuffer, "%d.Score", position);
|
||||||
options::get_string(optPath, Buffer, buf1, pinball::WindowName, 300);
|
options::get_string(optPath, scoreBuffer, buf1, "", 300);
|
||||||
tablePtr->Score = atol(buf1);
|
tablePtr->Score = atol(buf1);
|
||||||
for (int i = lstrlenA(tablePtr->Name); --i >= 0; scoreSum += tablePtr->Name[i])
|
|
||||||
{
|
for (auto i = lstrlenW(tablePtr->Name) - 1; i >= 0; i--)
|
||||||
}
|
scoreSum += tablePtr->Name[i];
|
||||||
scoreSum += tablePtr->Score;
|
scoreSum += tablePtr->Score;
|
||||||
++position;
|
|
||||||
++tablePtr;
|
|
||||||
}
|
}
|
||||||
while (position < 5);
|
|
||||||
scramble_number_string(scoreSum, buf1);
|
scramble_number_string(scoreSum, buf1);
|
||||||
options::get_string(optPath, "Verification", buf2, pinball::WindowName, 300);
|
options::get_string(optPath, "Verification", buf2, "", 300);
|
||||||
if (lstrcmpA(buf1, buf2))
|
if (lstrcmpA(buf1, buf2))
|
||||||
clear_table(table);
|
clear_table(table);
|
||||||
memory::free(buf1);
|
memory::free(buf1);
|
||||||
@@ -81,32 +78,30 @@ int high_score::read(high_score_struct* table, int* ptrToSmth)
|
|||||||
|
|
||||||
int high_score::write(high_score_struct* table, int* ptrToSmth)
|
int high_score::write(high_score_struct* table, int* ptrToSmth)
|
||||||
{
|
{
|
||||||
char Buffer[20];
|
char scoreBuffer[20];
|
||||||
|
wchar_t nameBuffer[20];
|
||||||
|
|
||||||
high_score_struct* tablePtr = table;
|
|
||||||
int scoreSum = 0;
|
int scoreSum = 0;
|
||||||
CHAR* buf = memory::allocate(300u);
|
CHAR* buf = memory::allocate(300u);
|
||||||
if (!buf)
|
if (!buf)
|
||||||
return 1;
|
return 1;
|
||||||
int position = 0;
|
auto optPath = pinball::get_rc_string(166, 0);
|
||||||
const CHAR* optPath = pinball::get_rc_string(166, 0);
|
for (auto position = 0; position < 5; ++position)
|
||||||
do
|
|
||||||
{
|
{
|
||||||
_itoa_s(position, Buffer, 10);
|
auto tablePtr = &table[position];
|
||||||
lstrcatA(Buffer, ".Name");
|
|
||||||
options::set_string(optPath, Buffer, tablePtr->Name);
|
wsprintfW(nameBuffer, L"%d.Name", position);
|
||||||
_itoa_s(position, Buffer, 10);
|
options::set_string(optPath, nameBuffer, tablePtr->Name);
|
||||||
lstrcatA(Buffer, ".Score");
|
|
||||||
|
sprintf_s(scoreBuffer, "%d.Score", position);
|
||||||
_ltoa_s(tablePtr->Score, buf, 300, 10);
|
_ltoa_s(tablePtr->Score, buf, 300, 10);
|
||||||
options::set_string(optPath, Buffer, buf);
|
options::set_string(optPath, scoreBuffer, buf);
|
||||||
for (int i = lstrlenA(tablePtr->Name); --i >= 0; scoreSum += tablePtr->Name[i])
|
|
||||||
{
|
for (auto i = lstrlenW(tablePtr->Name) - 1; i >= 0; i--)
|
||||||
}
|
scoreSum += tablePtr->Name[i];
|
||||||
scoreSum += tablePtr->Score;
|
scoreSum += tablePtr->Score;
|
||||||
++position;
|
|
||||||
++tablePtr;
|
|
||||||
}
|
}
|
||||||
while (position < 5);
|
|
||||||
scramble_number_string(scoreSum, buf);
|
scramble_number_string(scoreSum, buf);
|
||||||
options::set_string(optPath, "Verification", buf);
|
options::set_string(optPath, "Verification", buf);
|
||||||
memory::free(buf);
|
memory::free(buf);
|
||||||
@@ -136,7 +131,7 @@ int high_score::get_score_position(high_score_struct* table, int score)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int high_score::place_new_score_into(high_score_struct* table, int score, LPSTR scoreStr, int position)
|
int high_score::place_new_score_into(high_score_struct* table, int score, LPWSTR name, int position)
|
||||||
{
|
{
|
||||||
if (position >= 0)
|
if (position >= 0)
|
||||||
{
|
{
|
||||||
@@ -154,9 +149,9 @@ int high_score::place_new_score_into(high_score_struct* table, int score, LPSTR
|
|||||||
}
|
}
|
||||||
high_score_struct* posTable = &table[position];
|
high_score_struct* posTable = &table[position];
|
||||||
posTable->Score = score;
|
posTable->Score = score;
|
||||||
if (lstrlenA(scoreStr) >= 31)
|
if (lstrlenW(name) >= 31)
|
||||||
scoreStr[31] = 0;
|
name[31] = 0;
|
||||||
lstrcpyA(posTable->Name, scoreStr);
|
lstrcpyW(posTable->Name, name);
|
||||||
posTable->Name[31] = 0;
|
posTable->Name[31] = 0;
|
||||||
}
|
}
|
||||||
return position;
|
return position;
|
||||||
@@ -172,17 +167,17 @@ void high_score::show_high_score_dialog(high_score_struct* table)
|
|||||||
dlg_enter_name = 0;
|
dlg_enter_name = 0;
|
||||||
dlg_score = 0;
|
dlg_score = 0;
|
||||||
dlg_hst = table;
|
dlg_hst = table;
|
||||||
DialogBoxParamA(winmain::hinst, "dlg_highscores", winmain::hwnd_frame, HighScore, 0);
|
DialogBoxParamW(winmain::hinst, L"dlg_highscores", winmain::hwnd_frame, HighScore, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void high_score::show_and_set_high_score_dialog(high_score_struct* table, int score, int pos, LPCSTR defaultName)
|
void high_score::show_and_set_high_score_dialog(high_score_struct* table, int score, int pos, LPCWSTR defaultName)
|
||||||
{
|
{
|
||||||
position = pos;
|
dlg_position = pos;
|
||||||
dlg_score = score;
|
dlg_score = score;
|
||||||
dlg_hst = table;
|
dlg_hst = table;
|
||||||
dlg_enter_name = 1;
|
dlg_enter_name = 1;
|
||||||
default_name = defaultName;
|
default_name = defaultName;
|
||||||
while (DialogBoxParamA(winmain::hinst, "dlg_highscores", winmain::hwnd_frame, HighScore, 0))
|
while (DialogBoxParamW(winmain::hinst, L"dlg_highscores", winmain::hwnd_frame, HighScore, 0))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -191,8 +186,7 @@ INT_PTR high_score::HighScore(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||||||
{
|
{
|
||||||
HWND parent;
|
HWND parent;
|
||||||
int nIDDlgItem;
|
int nIDDlgItem;
|
||||||
CHAR String1[256];
|
wchar_t name[32];
|
||||||
CHAR name[32];
|
|
||||||
|
|
||||||
switch (msg)
|
switch (msg)
|
||||||
{
|
{
|
||||||
@@ -210,22 +204,22 @@ INT_PTR high_score::HighScore(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||||||
show_high_scores(hWnd, dlg_hst);
|
show_high_scores(hWnd, dlg_hst);
|
||||||
for (nIDDlgItem = DLG_HIGHSCORES_EditName1; nIDDlgItem < 611; ++nIDDlgItem)
|
for (nIDDlgItem = DLG_HIGHSCORES_EditName1; nIDDlgItem < 611; ++nIDDlgItem)
|
||||||
{
|
{
|
||||||
ShowWindow(GetDlgItem(hWnd, nIDDlgItem), 0);
|
ShowWindow(GetDlgItem(hWnd, nIDDlgItem), SW_HIDE);
|
||||||
}
|
}
|
||||||
if (dlg_enter_name == 1)
|
if (dlg_enter_name == 1)
|
||||||
{
|
{
|
||||||
if (position == -1)
|
if (dlg_position == -1)
|
||||||
{
|
{
|
||||||
dlg_enter_name = 0;
|
dlg_enter_name = 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
HWND nameTextBox = GetDlgItem(hWnd, position + DLG_HIGHSCORES_EditName1);
|
HWND nameTextBox = GetDlgItem(hWnd, dlg_position + DLG_HIGHSCORES_EditName1);
|
||||||
ShowWindow(nameTextBox, 5);
|
ShowWindow(nameTextBox, SW_SHOW);
|
||||||
EnableWindow(nameTextBox, 1);
|
EnableWindow(nameTextBox, 1);
|
||||||
SetFocus(nameTextBox);
|
SetFocus(nameTextBox);
|
||||||
if (default_name)
|
if (default_name)
|
||||||
{
|
{
|
||||||
SetWindowTextA(nameTextBox, default_name);
|
SetWindowTextW(nameTextBox, default_name);
|
||||||
SendMessageA(nameTextBox, EM_SETSEL, 0, -1);
|
SendMessageA(nameTextBox, EM_SETSEL, 0, -1);
|
||||||
}
|
}
|
||||||
SendMessageA(nameTextBox, EM_SETLIMITTEXT, 31u, 0);
|
SendMessageA(nameTextBox, EM_SETLIMITTEXT, 31u, 0);
|
||||||
@@ -246,15 +240,15 @@ INT_PTR high_score::HighScore(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
GetDlgItemTextA(hWnd, position + DLG_HIGHSCORES_EditName1, name, 32);
|
GetDlgItemTextW(hWnd, dlg_position + DLG_HIGHSCORES_EditName1, name, 32);
|
||||||
name[31] = 0;
|
name[31] = 0;
|
||||||
place_new_score_into(dlg_hst, dlg_score, name, position);
|
place_new_score_into(dlg_hst, dlg_score, name, dlg_position);
|
||||||
break;
|
break;
|
||||||
case DLG_HIGHSCORES_Cancel:
|
case DLG_HIGHSCORES_Cancel:
|
||||||
break;
|
break;
|
||||||
case DLG_HIGHSCORES_Clear:
|
case DLG_HIGHSCORES_Clear:
|
||||||
lstrcpyA(String1, pinball::get_rc_string(41, 0));
|
if (MessageBoxW(hWnd, pinball::get_rc_Wstring(40, 0),
|
||||||
if (MessageBoxA(hWnd, pinball::get_rc_string(40, 0), String1, MB_DEFBUTTON2 | MB_OKCANCEL) == 1)
|
pinball::get_rc_Wstring(41, 0), MB_DEFBUTTON2 | MB_OKCANCEL) == 1)
|
||||||
{
|
{
|
||||||
clear_table(dlg_hst);
|
clear_table(dlg_hst);
|
||||||
if (dlg_enter_name)
|
if (dlg_enter_name)
|
||||||
@@ -281,9 +275,9 @@ void high_score::show_high_scores(HWND hDlg, high_score_struct* table)
|
|||||||
int nextPosition = 0;
|
int nextPosition = 0;
|
||||||
for (int i = 0; i < 5; ++i)
|
for (int i = 0; i < 5; ++i)
|
||||||
{
|
{
|
||||||
if (dlg_enter_name == 1 && position == i)
|
if (dlg_enter_name == 1 && dlg_position == i)
|
||||||
{
|
{
|
||||||
hsdlg_show_score(hDlg, " ", dlg_score, i);
|
hsdlg_show_score(hDlg, L" ", dlg_score, i);
|
||||||
nextPosition = 1;
|
nextPosition = 1;
|
||||||
}
|
}
|
||||||
hsdlg_show_score(hDlg, tablePtr->Name, tablePtr->Score, i + nextPosition);
|
hsdlg_show_score(hDlg, tablePtr->Name, tablePtr->Score, i + nextPosition);
|
||||||
@@ -291,7 +285,7 @@ void high_score::show_high_scores(HWND hDlg, high_score_struct* table)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void high_score::hsdlg_show_score(HWND hDlg, LPCSTR name, int score, int position)
|
void high_score::hsdlg_show_score(HWND hDlg, LPCWSTR name, int score, int position)
|
||||||
{
|
{
|
||||||
CHAR scoreStr[36];
|
CHAR scoreStr[36];
|
||||||
if (position < 5)
|
if (position < 5)
|
||||||
@@ -299,7 +293,7 @@ void high_score::hsdlg_show_score(HWND hDlg, LPCSTR name, int score, int positio
|
|||||||
score::string_format(score, scoreStr);
|
score::string_format(score, scoreStr);
|
||||||
if (scoreStr[0])
|
if (scoreStr[0])
|
||||||
{
|
{
|
||||||
SetWindowTextA(GetDlgItem(hDlg, position + DLG_HIGHSCORES_StaticName1), name);
|
SetWindowTextW(GetDlgItem(hDlg, position + DLG_HIGHSCORES_StaticName1), name);
|
||||||
SetWindowTextA(GetDlgItem(hDlg, position + DLG_HIGHSCORES_Score1), scoreStr);
|
SetWindowTextA(GetDlgItem(hDlg, position + DLG_HIGHSCORES_Score1), scoreStr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
struct high_score_struct
|
struct high_score_struct
|
||||||
{
|
{
|
||||||
char Name[32];
|
wchar_t Name[32];
|
||||||
int Score;
|
int Score;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -15,19 +15,19 @@ public:
|
|||||||
static int write(high_score_struct* table, int* ptrToSmth);
|
static int write(high_score_struct* table, int* ptrToSmth);
|
||||||
static void clear_table(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 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 int place_new_score_into(high_score_struct* table, int score, LPWSTR name, int position);
|
||||||
static void scramble_number_string(int Value, char* Buffer);
|
static void scramble_number_string(int Value, char* Buffer);
|
||||||
|
|
||||||
static void show_high_score_dialog(high_score_struct* table);
|
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 void show_and_set_high_score_dialog(high_score_struct* table, int score, int pos, LPCWSTR defaultName);
|
||||||
static INT_PTR __stdcall HighScore(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
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 show_high_scores(HWND hDlg, high_score_struct* table);
|
||||||
static void hsdlg_show_score(HWND hDlg, LPCSTR name, int score, int position);
|
static void hsdlg_show_score(HWND hDlg, LPCWSTR name, int score, int position);
|
||||||
private :
|
private :
|
||||||
static int dlg_enter_name;
|
static int dlg_enter_name;
|
||||||
static int dlg_score;
|
static int dlg_score;
|
||||||
static int position;
|
static int dlg_position;
|
||||||
static LPCSTR default_name;
|
static LPCWSTR default_name;
|
||||||
static high_score_struct* dlg_hst;
|
static high_score_struct* dlg_hst;
|
||||||
static winhelp_entry help[21];
|
static winhelp_entry help[21];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#include "loader.h"
|
#include "loader.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "partman.h"
|
#include "partman.h"
|
||||||
|
#include "pb.h"
|
||||||
#include "pinball.h"
|
#include "pinball.h"
|
||||||
#include "Sound.h"
|
#include "Sound.h"
|
||||||
#include "zdrv.h"
|
#include "zdrv.h"
|
||||||
@@ -47,20 +48,19 @@ soundListStruct loader::sound_list[65];
|
|||||||
|
|
||||||
int loader::error(int errorCode, int captionCode)
|
int loader::error(int errorCode, int captionCode)
|
||||||
{
|
{
|
||||||
int curCode = loader_errors[0].Code;
|
auto curCode = loader_errors;
|
||||||
const char *errorText = nullptr, *errorCaption = nullptr;
|
const char *errorText = nullptr, *errorCaption = nullptr;
|
||||||
int index = 0, index2 = 0;
|
auto index = 0;
|
||||||
if (loader_errors[0].Code >= 0)
|
while (curCode->Code >= 0)
|
||||||
do
|
{
|
||||||
{
|
if (errorCode == curCode->Code)
|
||||||
if (errorCode == curCode)
|
errorText = curCode->Message;
|
||||||
errorText = loader_errors[index2].Message;
|
if (captionCode == curCode->Code)
|
||||||
if (captionCode == curCode)
|
errorCaption = curCode->Message;
|
||||||
errorCaption = loader_errors[index2].Message;
|
curCode++;
|
||||||
index2 = ++index;
|
index++;
|
||||||
curCode = loader_errors[index].Code;
|
}
|
||||||
}
|
|
||||||
while (curCode >= 0);
|
|
||||||
if (!errorText)
|
if (!errorText)
|
||||||
errorText = loader_errors[index].Message;
|
errorText = loader_errors[index].Message;
|
||||||
MessageBoxA(nullptr, errorText, errorCaption, 0x2000u);
|
MessageBoxA(nullptr, errorText, errorCaption, 0x2000u);
|
||||||
@@ -89,7 +89,7 @@ void loader::loadfrom(datFileStruct* datFile)
|
|||||||
|
|
||||||
for (auto groupIndex = 0; groupIndex < datFile->NumberOfGroups; ++groupIndex)
|
for (auto groupIndex = 0; groupIndex < datFile->NumberOfGroups; ++groupIndex)
|
||||||
{
|
{
|
||||||
auto value = reinterpret_cast<__int16*>(partman::field(datFile, groupIndex, datFieldTypes::ShortValue));
|
auto value = reinterpret_cast<int16_t*>(partman::field(datFile, groupIndex, datFieldTypes::ShortValue));
|
||||||
if (value && *value == 202)
|
if (value && *value == 202)
|
||||||
{
|
{
|
||||||
if (sound_count < 65)
|
if (sound_count < 65)
|
||||||
@@ -116,7 +116,7 @@ void loader::unload()
|
|||||||
|
|
||||||
int loader::get_sound_id(int groupIndex)
|
int loader::get_sound_id(int groupIndex)
|
||||||
{
|
{
|
||||||
__int16 soundIndex = 1;
|
int16_t soundIndex = 1;
|
||||||
if (sound_count <= 1)
|
if (sound_count <= 1)
|
||||||
{
|
{
|
||||||
error(25, 26);
|
error(25, 26);
|
||||||
@@ -135,20 +135,28 @@ int loader::get_sound_id(int groupIndex)
|
|||||||
|
|
||||||
if (!sound_list[soundIndex].Loaded && !sound_list[soundIndex].WavePtr)
|
if (!sound_list[soundIndex].Loaded && !sound_list[soundIndex].WavePtr)
|
||||||
{
|
{
|
||||||
|
WaveHeader wavHeader{};
|
||||||
|
|
||||||
int soundGroupId = sound_list[soundIndex].GroupIndex;
|
int soundGroupId = sound_list[soundIndex].GroupIndex;
|
||||||
sound_list[soundIndex].Duration = 0.0;
|
sound_list[soundIndex].Duration = 0.0;
|
||||||
if (soundGroupId > 0 && !pinball::quickFlag)
|
if (soundGroupId > 0 && !pinball::quickFlag)
|
||||||
{
|
{
|
||||||
auto value = reinterpret_cast<__int16*>(partman::field(loader_table, soundGroupId,
|
auto value = reinterpret_cast<int16_t*>(partman::field(loader_table, soundGroupId,
|
||||||
datFieldTypes::ShortValue));
|
datFieldTypes::ShortValue));
|
||||||
if (value && *value == 202)
|
if (value && *value == 202)
|
||||||
{
|
{
|
||||||
|
/*FT sounds are in SOUND subfolder*/
|
||||||
|
char filePath[300]{}, fileName2[100]{};
|
||||||
auto fileName = partman::field(loader_table, soundGroupId, datFieldTypes::String);
|
auto fileName = partman::field(loader_table, soundGroupId, datFieldTypes::String);
|
||||||
HFILE hFile = _lopen(fileName, 0);
|
sprintf_s(fileName2, pb::FullTiltMode ? "SOUND\\%s" : "%s", fileName);
|
||||||
sound_list[soundIndex].Duration = static_cast<float>(static_cast<double>(_llseek(hFile, 0, SEEK_END)) *
|
pinball::make_path_name(filePath, fileName2);
|
||||||
0.0000909090909090909);
|
|
||||||
|
HFILE hFile = _lopen(filePath, 0);
|
||||||
|
_lread(hFile, &wavHeader, sizeof wavHeader);
|
||||||
_lclose(hFile);
|
_lclose(hFile);
|
||||||
sound_list[soundIndex].WavePtr = Sound::LoadWaveFile(fileName);
|
auto sampleCount = wavHeader.data_size / (wavHeader.channels * (wavHeader.bits_per_sample / 8.0));
|
||||||
|
sound_list[soundIndex].Duration = static_cast<float>(sampleCount / wavHeader.sample_rate);
|
||||||
|
sound_list[soundIndex].WavePtr = Sound::LoadWaveFile(filePath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -168,7 +176,7 @@ short loader::query_visual_states(int groupIndex)
|
|||||||
short result;
|
short result;
|
||||||
if (groupIndex < 0)
|
if (groupIndex < 0)
|
||||||
return error(0, 17);
|
return error(0, 17);
|
||||||
auto shortArr = reinterpret_cast<__int16*>(partman::field(loader_table, groupIndex, datFieldTypes::ShortArray));
|
auto shortArr = reinterpret_cast<int16_t*>(partman::field(loader_table, groupIndex, datFieldTypes::ShortArray));
|
||||||
if (shortArr && *shortArr == 100)
|
if (shortArr && *shortArr == 100)
|
||||||
result = shortArr[1];
|
result = shortArr[1];
|
||||||
else
|
else
|
||||||
@@ -187,7 +195,7 @@ char* loader::query_name(int groupIndex)
|
|||||||
return partman::field(loader_table, groupIndex, datFieldTypes::GroupName);
|
return partman::field(loader_table, groupIndex, datFieldTypes::GroupName);
|
||||||
}
|
}
|
||||||
|
|
||||||
__int16* loader::query_iattribute(int groupIndex, int firstValue, int* arraySize)
|
int16_t* loader::query_iattribute(int groupIndex, int firstValue, int* arraySize)
|
||||||
{
|
{
|
||||||
if (groupIndex < 0)
|
if (groupIndex < 0)
|
||||||
{
|
{
|
||||||
@@ -197,7 +205,7 @@ __int16* loader::query_iattribute(int groupIndex, int firstValue, int* arraySize
|
|||||||
|
|
||||||
for (auto skipIndex = 0;; ++skipIndex)
|
for (auto skipIndex = 0;; ++skipIndex)
|
||||||
{
|
{
|
||||||
auto shortArr = reinterpret_cast<__int16*>(partman::field_nth(loader_table, groupIndex,
|
auto shortArr = reinterpret_cast<int16_t*>(partman::field_nth(loader_table, groupIndex,
|
||||||
datFieldTypes::ShortArray, skipIndex));
|
datFieldTypes::ShortArray, skipIndex));
|
||||||
if (!shortArr)
|
if (!shortArr)
|
||||||
break;
|
break;
|
||||||
@@ -234,7 +242,7 @@ float* loader::query_float_attribute(int groupIndex, int groupIndexOffset, int f
|
|||||||
skipIndex));
|
skipIndex));
|
||||||
if (!floatArr)
|
if (!floatArr)
|
||||||
break;
|
break;
|
||||||
if (static_cast<__int16>(floor(*floatArr)) == firstValue)
|
if (static_cast<int16_t>(floor(*floatArr)) == firstValue)
|
||||||
return floatArr + 1;
|
return floatArr + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -242,11 +250,42 @@ float* loader::query_float_attribute(int groupIndex, int groupIndexOffset, int f
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float loader::query_float_attribute(int groupIndex, int groupIndexOffset, int firstValue, float defVal)
|
||||||
|
{
|
||||||
|
if (groupIndex < 0)
|
||||||
|
{
|
||||||
|
error(0, 22);
|
||||||
|
return NAN;
|
||||||
|
}
|
||||||
|
|
||||||
|
int stateId = state_id(groupIndex, groupIndexOffset);
|
||||||
|
if (stateId < 0)
|
||||||
|
{
|
||||||
|
error(16, 22);
|
||||||
|
return NAN;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto skipIndex = 0;; ++skipIndex)
|
||||||
|
{
|
||||||
|
auto floatArr = reinterpret_cast<float*>(partman::field_nth(loader_table, stateId,
|
||||||
|
datFieldTypes::FloatArray, skipIndex));
|
||||||
|
if (!floatArr)
|
||||||
|
break;
|
||||||
|
if (static_cast<int16_t>(floor(*floatArr)) == firstValue)
|
||||||
|
return floatArr[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isnan(defVal))
|
||||||
|
return defVal;
|
||||||
|
error(13, 22);
|
||||||
|
return NAN;
|
||||||
|
}
|
||||||
|
|
||||||
int loader::material(int groupIndex, visualStruct* visual)
|
int loader::material(int groupIndex, visualStruct* visual)
|
||||||
{
|
{
|
||||||
if (groupIndex < 0)
|
if (groupIndex < 0)
|
||||||
return error(0, 21);
|
return error(0, 21);
|
||||||
auto shortArr = reinterpret_cast<__int16*>(partman::field(loader_table, groupIndex, datFieldTypes::ShortValue));
|
auto shortArr = reinterpret_cast<int16_t*>(partman::field(loader_table, groupIndex, datFieldTypes::ShortValue));
|
||||||
if (!shortArr)
|
if (!shortArr)
|
||||||
return error(1, 21);
|
return error(1, 21);
|
||||||
if (*shortArr != 300)
|
if (*shortArr != 300)
|
||||||
@@ -290,7 +329,7 @@ int loader::state_id(int groupIndex, int groupIndexOffset)
|
|||||||
auto visualState = query_visual_states(groupIndex);
|
auto visualState = query_visual_states(groupIndex);
|
||||||
if (visualState <= 0)
|
if (visualState <= 0)
|
||||||
return error(12, 24);
|
return error(12, 24);
|
||||||
auto shortArr = reinterpret_cast<__int16*>(partman::field(loader_table, groupIndex, datFieldTypes::ShortValue));
|
auto shortArr = reinterpret_cast<int16_t*>(partman::field(loader_table, groupIndex, datFieldTypes::ShortValue));
|
||||||
if (!shortArr)
|
if (!shortArr)
|
||||||
return error(1, 24);
|
return error(1, 24);
|
||||||
if (*shortArr != 200)
|
if (*shortArr != 200)
|
||||||
@@ -301,7 +340,7 @@ int loader::state_id(int groupIndex, int groupIndexOffset)
|
|||||||
return groupIndex;
|
return groupIndex;
|
||||||
|
|
||||||
groupIndex += groupIndexOffset;
|
groupIndex += groupIndexOffset;
|
||||||
shortArr = reinterpret_cast<__int16*>(partman::field(loader_table, groupIndex, datFieldTypes::ShortValue));
|
shortArr = reinterpret_cast<int16_t*>(partman::field(loader_table, groupIndex, datFieldTypes::ShortValue));
|
||||||
if (!shortArr)
|
if (!shortArr)
|
||||||
return error(1, 24);
|
return error(1, 24);
|
||||||
if (*shortArr != 201)
|
if (*shortArr != 201)
|
||||||
@@ -313,7 +352,7 @@ int loader::kicker(int groupIndex, visualKickerStruct* kicker)
|
|||||||
{
|
{
|
||||||
if (groupIndex < 0)
|
if (groupIndex < 0)
|
||||||
return error(0, 20);
|
return error(0, 20);
|
||||||
auto shortArr = reinterpret_cast<__int16*>(partman::field(loader_table, groupIndex, datFieldTypes::ShortValue));
|
auto shortArr = reinterpret_cast<int16_t*>(partman::field(loader_table, groupIndex, datFieldTypes::ShortValue));
|
||||||
if (!shortArr)
|
if (!shortArr)
|
||||||
return error(1, 20);
|
return error(1, 20);
|
||||||
if (*shortArr != 400)
|
if (*shortArr != 400)
|
||||||
@@ -381,7 +420,7 @@ int loader::query_visual(int groupIndex, int groupIndexOffset, visualStruct* vis
|
|||||||
visual->ZMap->ZPtr2 = visual->ZMap->ZPtr1;
|
visual->ZMap->ZPtr2 = visual->ZMap->ZPtr1;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto shortArr = reinterpret_cast<__int16*>(partman::field(loader_table, stateId, datFieldTypes::ShortArray));
|
auto shortArr = reinterpret_cast<int16_t*>(partman::field(loader_table, stateId, datFieldTypes::ShortArray));
|
||||||
if (shortArr)
|
if (shortArr)
|
||||||
{
|
{
|
||||||
unsigned int shortArrSize = partman::field_size(loader_table, stateId, datFieldTypes::ShortArray);
|
unsigned int shortArrSize = partman::field_size(loader_table, stateId, datFieldTypes::ShortArray);
|
||||||
@@ -433,11 +472,11 @@ int loader::query_visual(int groupIndex, int groupIndexOffset, visualStruct* vis
|
|||||||
auto floatArr = reinterpret_cast<float*>(partman::field(loader_table, stateId, datFieldTypes::FloatArray));
|
auto floatArr = reinterpret_cast<float*>(partman::field(loader_table, stateId, datFieldTypes::FloatArray));
|
||||||
if (!floatArr)
|
if (!floatArr)
|
||||||
return 0;
|
return 0;
|
||||||
if (*floatArr != 600.0)
|
if (*floatArr != 600.0f)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
visual->FloatArrCount = (partman::field_size(loader_table, stateId, datFieldTypes::FloatArray) / 4) / 2 - 2;
|
visual->FloatArrCount = partman::field_size(loader_table, stateId, datFieldTypes::FloatArray) / 4 / 2 - 2;
|
||||||
auto floatVal = static_cast<int>(floor(floatArr[1]) - 1.0);
|
auto floatVal = static_cast<int>(floor(floatArr[1]) - 1.0f);
|
||||||
switch (floatVal)
|
switch (floatVal)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
|
|||||||
@@ -48,6 +48,40 @@ struct visualStruct
|
|||||||
zmap_header_type* ZMap;
|
zmap_header_type* ZMap;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#pragma pack(push)
|
||||||
|
#pragma pack(1)
|
||||||
|
// WAVE file header format
|
||||||
|
struct WaveHeader
|
||||||
|
{
|
||||||
|
unsigned char riff[4]; // RIFF string
|
||||||
|
|
||||||
|
unsigned int overall_size; // overall size of file in bytes
|
||||||
|
|
||||||
|
unsigned char wave[4]; // WAVE string
|
||||||
|
|
||||||
|
unsigned char fmt_chunk_marker[4]; // fmt string with trailing null char
|
||||||
|
|
||||||
|
unsigned int length_of_fmt; // length of the format data
|
||||||
|
|
||||||
|
unsigned short format_type; // format type. 1-PCM, 3- IEEE float, 6 - 8bit A law, 7 - 8bit mu law
|
||||||
|
|
||||||
|
unsigned short channels; // no.of channels
|
||||||
|
|
||||||
|
unsigned int sample_rate; // sampling rate (blocks per second)
|
||||||
|
|
||||||
|
unsigned int byterate; // SampleRate * NumChannels * BitsPerSample/8
|
||||||
|
|
||||||
|
unsigned short block_align; // NumChannels * BitsPerSample/8
|
||||||
|
|
||||||
|
unsigned short bits_per_sample; // bits per sample, 8- 8bits, 16- 16 bits etc
|
||||||
|
|
||||||
|
unsigned char data_chunk_header[4]; // DATA string or FLLR string
|
||||||
|
|
||||||
|
unsigned int data_size; // NumSamples * NumChannels * BitsPerSample/8 - size of the next chunk that will be read
|
||||||
|
};
|
||||||
|
#pragma pack(pop)
|
||||||
|
static_assert(sizeof(WaveHeader) == 44, "Wrong size of WaveHeader");
|
||||||
|
|
||||||
|
|
||||||
class loader
|
class loader
|
||||||
{
|
{
|
||||||
@@ -65,7 +99,8 @@ public:
|
|||||||
static int query_visual(int groupIndex, int groupIndexOffset, visualStruct* visual);
|
static int query_visual(int groupIndex, int groupIndexOffset, visualStruct* visual);
|
||||||
static char* query_name(int groupIndex);
|
static char* query_name(int groupIndex);
|
||||||
static float* query_float_attribute(int groupIndex, int groupIndexOffset, int firstValue);
|
static float* query_float_attribute(int groupIndex, int groupIndexOffset, int firstValue);
|
||||||
static __int16* query_iattribute(int groupIndex, int firstValue, int* arraySize);
|
static float query_float_attribute(int groupIndex, int groupIndexOffset, int firstValue, float defVal);
|
||||||
|
static int16_t* query_iattribute(int groupIndex, int firstValue, int* arraySize);
|
||||||
static float play_sound(int soundIndex);
|
static float play_sound(int soundIndex);
|
||||||
static datFileStruct* loader_table;
|
static datFileStruct* loader_table;
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ float maths::ray_intersect_circle(ray_type* ray, circle_type* circle)
|
|||||||
|
|
||||||
// Tca, L dot D, projection of L on D
|
// Tca, L dot D, projection of L on D
|
||||||
float Tca = Ly * ray->Direction.Y + Lx * ray->Direction.X;
|
float Tca = Ly * ray->Direction.Y + Lx * ray->Direction.X;
|
||||||
if (Tca < 0.0) // No intersection if Tca is negative
|
if (Tca < 0.0f) // No intersection if Tca is negative
|
||||||
return 1000000000.0f;
|
return 1000000000.0f;
|
||||||
|
|
||||||
// L dot L, distance from ray origin to circle center
|
// L dot L, distance from ray origin to circle center
|
||||||
@@ -144,12 +144,12 @@ float maths::ray_intersect_circle(ray_type* ray, circle_type* circle)
|
|||||||
|
|
||||||
// Thc^2 = rad^2 - d = rad^2 - L dot L + Tca dot Tca
|
// Thc^2 = rad^2 - d = rad^2 - L dot L + Tca dot Tca
|
||||||
float ThcSq = circle->RadiusSq - LMagSq + Tca * Tca;
|
float ThcSq = circle->RadiusSq - LMagSq + Tca * Tca;
|
||||||
if (ThcSq < 0.0) // No intersection if Thc is negative
|
if (ThcSq < 0.0f) // No intersection if Thc is negative
|
||||||
return 1000000000.0f;
|
return 1000000000.0f;
|
||||||
|
|
||||||
// T0 = Tca - Thc, distance from origin to first intersection
|
// T0 = Tca - Thc, distance from origin to first intersection
|
||||||
float T0 = Tca - sqrt(ThcSq);
|
float T0 = Tca - sqrt(ThcSq);
|
||||||
if (T0 < 0.0 || T0 > ray->MaxDistance)
|
if (T0 < 0.0f || T0 > ray->MaxDistance)
|
||||||
return 1000000000.0f;
|
return 1000000000.0f;
|
||||||
return T0;
|
return T0;
|
||||||
}
|
}
|
||||||
@@ -158,7 +158,7 @@ float maths::ray_intersect_circle(ray_type* ray, circle_type* circle)
|
|||||||
float maths::normalize_2d(vector_type* vec)
|
float maths::normalize_2d(vector_type* vec)
|
||||||
{
|
{
|
||||||
float mag = sqrt(vec->X * vec->X + vec->Y * vec->Y);
|
float mag = sqrt(vec->X * vec->X + vec->Y * vec->Y);
|
||||||
if (0.0 != mag)
|
if (mag != 0.0f)
|
||||||
{
|
{
|
||||||
vec->X = 1.0f / mag * vec->X;
|
vec->X = 1.0f / mag * vec->X;
|
||||||
vec->Y = 1.0f / mag * vec->Y;
|
vec->Y = 1.0f / mag * vec->Y;
|
||||||
@@ -179,7 +179,7 @@ void maths::line_init(line_type* line, float x0, float y0, float x1, float y1)
|
|||||||
line->PerpendicularL.X = line->Direction.Y;
|
line->PerpendicularL.X = line->Direction.Y;
|
||||||
line->PerpendicularL.Y = -line->Direction.X;
|
line->PerpendicularL.Y = -line->Direction.X;
|
||||||
line->PreComp1 = -(line->Direction.Y * x0) + line->Direction.X * y0;
|
line->PreComp1 = -(line->Direction.Y * x0) + line->Direction.X * y0;
|
||||||
if (line->Direction.X >= 0.000000001 || line->Direction.X <= -0.000000001)
|
if (line->Direction.X >= 0.000000001f || line->Direction.X <= -0.000000001f)
|
||||||
{
|
{
|
||||||
v9 = x1;
|
v9 = x1;
|
||||||
lineDirection = x0 >= x1;
|
lineDirection = x0 >= x1;
|
||||||
@@ -210,7 +210,7 @@ float maths::ray_intersect_line(ray_type* ray, line_type* line)
|
|||||||
bool v6;
|
bool v6;
|
||||||
|
|
||||||
float perpDot = line->PerpendicularL.Y * ray->Direction.Y + ray->Direction.X * line->PerpendicularL.X;
|
float perpDot = line->PerpendicularL.Y * ray->Direction.Y + ray->Direction.X * line->PerpendicularL.X;
|
||||||
if (perpDot < 0.0)
|
if (perpDot < 0.0f)
|
||||||
{
|
{
|
||||||
float result = -((ray->Origin.X * line->PerpendicularL.X + ray->Origin.Y * line->PerpendicularL.Y + line->
|
float result = -((ray->Origin.X * line->PerpendicularL.X + ray->Origin.Y * line->PerpendicularL.Y + line->
|
||||||
PreComp1)
|
PreComp1)
|
||||||
@@ -220,7 +220,7 @@ float maths::ray_intersect_line(ray_type* ray, line_type* line)
|
|||||||
line->RayIntersect.X = result * ray->Direction.X + ray->Origin.X;
|
line->RayIntersect.X = result * ray->Direction.X + ray->Origin.X;
|
||||||
float v4 = result * ray->Direction.Y + ray->Origin.Y;
|
float v4 = result * ray->Direction.Y + ray->Origin.Y;
|
||||||
line->RayIntersect.Y = v4;
|
line->RayIntersect.Y = v4;
|
||||||
if (0.0 == line->Direction.X)
|
if (line->Direction.X == 0.0f)
|
||||||
{
|
{
|
||||||
if (v4 >= line->OriginX)
|
if (v4 >= line->OriginX)
|
||||||
{
|
{
|
||||||
@@ -256,7 +256,7 @@ float maths::magnitude(vector_type* vec)
|
|||||||
{
|
{
|
||||||
float result;
|
float result;
|
||||||
auto magSq = vec->X * vec->X + vec->Y * vec->Y + vec->Z * vec->Z;
|
auto magSq = vec->X * vec->X + vec->Y * vec->Y + vec->Z * vec->Z;
|
||||||
if (magSq == 0.0)
|
if (magSq == 0.0f)
|
||||||
result = 0.0;
|
result = 0.0;
|
||||||
else
|
else
|
||||||
result = sqrt(magSq);
|
result = sqrt(magSq);
|
||||||
@@ -342,7 +342,7 @@ float maths::distance_to_flipper(ray_type* ray1, ray_type* ray2)
|
|||||||
auto distance = 1000000000.0f;
|
auto distance = 1000000000.0f;
|
||||||
auto distanceType = -1;
|
auto distanceType = -1;
|
||||||
auto newDistance = ray_intersect_line(ray1, &TFlipperEdge::lineA);
|
auto newDistance = ray_intersect_line(ray1, &TFlipperEdge::lineA);
|
||||||
if (newDistance < 1000000000.0)
|
if (newDistance < 1000000000.0f)
|
||||||
{
|
{
|
||||||
distance = newDistance;
|
distance = newDistance;
|
||||||
distanceType = 0;
|
distanceType = 0;
|
||||||
@@ -365,7 +365,7 @@ float maths::distance_to_flipper(ray_type* ray1, ray_type* ray2)
|
|||||||
distance = newDistance;
|
distance = newDistance;
|
||||||
distanceType = 1;
|
distanceType = 1;
|
||||||
}
|
}
|
||||||
if (!ray2 || distance >= 1000000000.0)
|
if (!ray2 || distance >= 1000000000.0f)
|
||||||
return distance;
|
return distance;
|
||||||
|
|
||||||
if (distanceType != -1)
|
if (distanceType != -1)
|
||||||
|
|||||||
@@ -1,58 +1,40 @@
|
|||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
|
||||||
unsigned int memory::use_total;
|
size_t memory::use_total;
|
||||||
int memory::critical_allocation;
|
int memory::critical_allocation;
|
||||||
void (*memory::critical_callback)();
|
void (*memory::critical_callback)();
|
||||||
|
std::map<void*, size_t> memory::alloc_map{};
|
||||||
|
|
||||||
void memory::init(void (*callback)())
|
void memory::init(void (*callback)())
|
||||||
{
|
{
|
||||||
critical_callback = callback;
|
critical_callback = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* memory::allocate(unsigned int size)
|
char* memory::allocate(size_t size)
|
||||||
{
|
{
|
||||||
char* buf = static_cast<char*>(malloc(size + 4));
|
auto buf = static_cast<char*>(malloc(size));
|
||||||
if (buf)
|
if (!buf)
|
||||||
{
|
{
|
||||||
*(unsigned int*)buf = size << 8;
|
if (critical_allocation && critical_callback)
|
||||||
use_total += size + 4;
|
critical_callback();
|
||||||
*buf = size >= 0xFFDC ? -91 : 90;
|
return nullptr;
|
||||||
return buf + 4;
|
|
||||||
}
|
}
|
||||||
if (critical_allocation && critical_callback)
|
|
||||||
critical_callback();
|
use_total += size;
|
||||||
return nullptr;
|
alloc_map[buf] = size;
|
||||||
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
void memory::free(void* buf)
|
void memory::free(void* buf)
|
||||||
{
|
{
|
||||||
unsigned int* bufStart = static_cast<unsigned int*>(buf) - 1;
|
auto alloc = alloc_map.find(buf);
|
||||||
use_total -= (*bufStart >> 8) + 4;
|
if (alloc == alloc_map.end())
|
||||||
char firstChar = *(char*)bufStart;
|
|
||||||
if (firstChar == 90 || firstChar == -91)
|
|
||||||
std::free(bufStart);
|
|
||||||
else
|
|
||||||
assertm(false, "Unknown memory type");
|
|
||||||
}
|
|
||||||
|
|
||||||
char* memory::realloc(void* buf, unsigned int size)
|
|
||||||
{
|
|
||||||
if (!buf)
|
|
||||||
return allocate(size);
|
|
||||||
|
|
||||||
char* bufStart = static_cast<char*>(buf) - 4;
|
|
||||||
use_total -= *(unsigned int*)bufStart >> 8;
|
|
||||||
if (*bufStart != 90 && *bufStart != -91 ||
|
|
||||||
(bufStart = static_cast<char*>(std::realloc(bufStart, size + 4))) != nullptr)
|
|
||||||
{
|
{
|
||||||
char bufType = *bufStart;
|
assertm(false, "Unknown memory type");
|
||||||
*(unsigned int*)bufStart = size << 8;
|
return;
|
||||||
use_total += size;
|
|
||||||
*bufStart = bufType;
|
|
||||||
return bufStart + 4;
|
|
||||||
}
|
}
|
||||||
if (critical_allocation && critical_callback)
|
|
||||||
critical_callback();
|
use_total -= alloc->second;
|
||||||
return nullptr;
|
std::free(alloc->first);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +1,60 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include <map>
|
||||||
|
|
||||||
class memory
|
class memory
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static void init(void (*callback)(void));
|
static void init(void (*callback)(void));
|
||||||
static char* allocate(unsigned int size);
|
static char* allocate(size_t size);
|
||||||
static void free(void* buf);
|
static void free(void* buf);
|
||||||
static char* realloc(void* buf, unsigned int size);
|
|
||||||
|
|
||||||
static unsigned int use_total;
|
template <typename T>
|
||||||
|
static T* allocate(size_t count = 1, size_t add = 0)
|
||||||
|
{
|
||||||
|
size_t size = sizeof(T) * count + add;
|
||||||
|
auto buf = static_cast<T*>(malloc(size));
|
||||||
|
if (!buf)
|
||||||
|
{
|
||||||
|
if (critical_allocation && critical_callback)
|
||||||
|
critical_callback();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
use_total += size;
|
||||||
|
alloc_map[buf] = size;
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static T* realloc(T* buf, size_t size)
|
||||||
|
{
|
||||||
|
if (!buf)
|
||||||
|
return reinterpret_cast<T*>(allocate(size));
|
||||||
|
|
||||||
|
auto alloc = alloc_map.find(buf);
|
||||||
|
if (alloc == alloc_map.end())
|
||||||
|
{
|
||||||
|
assertm(false, "Unknown memory type");
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto newBuf = static_cast<T*>(std::realloc(alloc->first, size));
|
||||||
|
if (!newBuf)
|
||||||
|
{
|
||||||
|
if (critical_allocation && critical_callback)
|
||||||
|
critical_callback();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
use_total += size - alloc->second;
|
||||||
|
alloc_map.erase(alloc);
|
||||||
|
alloc_map[newBuf] = size;
|
||||||
|
return newBuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t use_total;
|
||||||
static int critical_allocation;
|
static int critical_allocation;
|
||||||
|
private:
|
||||||
static void (*critical_callback)();
|
static void (*critical_callback)();
|
||||||
|
static std::map<void*, size_t> alloc_map;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Fill memory block with an integer value
|
|
||||||
inline void memset32(void* ptr, unsigned int value, int count)
|
|
||||||
{
|
|
||||||
auto p = (unsigned int*)ptr;
|
|
||||||
for (int i = 0; i < count; i++)
|
|
||||||
*p++ = value;
|
|
||||||
}
|
|
||||||
@@ -1,15 +1,22 @@
|
|||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
#include "midi.h"
|
#include "midi.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "pb.h"
|
||||||
#include "pinball.h"
|
#include "pinball.h"
|
||||||
|
|
||||||
tagMCI_OPEN_PARMSA midi::mci_open_info;
|
tagMCI_OPEN_PARMSA midi::mci_open_info;
|
||||||
char midi::midi_device_type[28];
|
char midi::midi_file_name[28];
|
||||||
HWND midi::midi_notify_hwnd;
|
HWND midi::midi_notify_hwnd;
|
||||||
int midi::midi_seq1_open, midi::midi_seq1_playing;
|
int midi::midi_seq1_open, midi::midi_seq1_playing;
|
||||||
|
|
||||||
MCIERROR midi::play_pb_theme(int flag)
|
MCIERROR midi::play_pb_theme(int flag)
|
||||||
{
|
{
|
||||||
|
if (pb::FullTiltMode)
|
||||||
|
{
|
||||||
|
return play_ft(track1);
|
||||||
|
}
|
||||||
|
|
||||||
MCI_PLAY_PARMS playParams;
|
MCI_PLAY_PARMS playParams;
|
||||||
MCIERROR result = 0;
|
MCIERROR result = 0;
|
||||||
|
|
||||||
@@ -26,6 +33,11 @@ MCIERROR midi::play_pb_theme(int flag)
|
|||||||
|
|
||||||
MCIERROR midi::music_stop()
|
MCIERROR midi::music_stop()
|
||||||
{
|
{
|
||||||
|
if (pb::FullTiltMode)
|
||||||
|
{
|
||||||
|
return stop_ft();
|
||||||
|
}
|
||||||
|
|
||||||
MCIERROR result = 0;
|
MCIERROR result = 0;
|
||||||
if (midi_seq1_playing)
|
if (midi_seq1_playing)
|
||||||
result = mciSendCommandA(mci_open_info.wDeviceID, MCI_STOP, 0, 0);
|
result = mciSendCommandA(mci_open_info.wDeviceID, MCI_STOP, 0, 0);
|
||||||
@@ -34,18 +46,28 @@ MCIERROR midi::music_stop()
|
|||||||
|
|
||||||
int midi::music_init(HWND hwnd)
|
int midi::music_init(HWND hwnd)
|
||||||
{
|
{
|
||||||
|
if (pb::FullTiltMode)
|
||||||
|
{
|
||||||
|
return music_init_ft(hwnd);
|
||||||
|
}
|
||||||
|
|
||||||
mci_open_info.wDeviceID = 0;
|
mci_open_info.wDeviceID = 0;
|
||||||
midi_notify_hwnd = hwnd;
|
midi_notify_hwnd = hwnd;
|
||||||
lstrcpyA(midi_device_type, pinball::get_rc_string(156, 0));
|
lstrcpyA(midi_file_name, pinball::get_rc_string(156, 0));
|
||||||
mci_open_info.lpstrElementName = nullptr;
|
mci_open_info.lpstrElementName = midi_file_name;
|
||||||
mci_open_info.lpstrDeviceType = midi_device_type;
|
mci_open_info.lpstrDeviceType = nullptr;
|
||||||
auto result = mciSendCommandA(0, MCI_OPEN, MCI_OPEN_TYPE | MCI_NOTIFY_SUPERSEDED, (DWORD_PTR)&mci_open_info);
|
auto result = mciSendCommandA(0, MCI_OPEN, MCI_OPEN_ELEMENT | MCI_NOTIFY_SUPERSEDED, (DWORD_PTR)&mci_open_info);
|
||||||
midi_seq1_open = result == 0;
|
midi_seq1_open = result == 0;
|
||||||
return midi_seq1_open;
|
return midi_seq1_open;
|
||||||
}
|
}
|
||||||
|
|
||||||
MCIERROR midi::restart_midi_seq(int param)
|
MCIERROR midi::restart_midi_seq(LPARAM param)
|
||||||
{
|
{
|
||||||
|
if (pb::FullTiltMode)
|
||||||
|
{
|
||||||
|
return play_ft(active_track);
|
||||||
|
}
|
||||||
|
|
||||||
MCI_PLAY_PARMS playParams;
|
MCI_PLAY_PARMS playParams;
|
||||||
MCIERROR result = 0;
|
MCIERROR result = 0;
|
||||||
|
|
||||||
@@ -58,7 +80,431 @@ MCIERROR midi::restart_midi_seq(int param)
|
|||||||
|
|
||||||
void midi::music_shutdown()
|
void midi::music_shutdown()
|
||||||
{
|
{
|
||||||
|
if (pb::FullTiltMode)
|
||||||
|
{
|
||||||
|
music_shutdown_ft();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (midi_seq1_open)
|
if (midi_seq1_open)
|
||||||
mciSendCommandA(mci_open_info.wDeviceID, MCI_CLOSE, 0, 0);
|
mciSendCommandA(mci_open_info.wDeviceID, MCI_CLOSE, 0, 0);
|
||||||
midi_seq1_open = 0;
|
midi_seq1_open = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
objlist_class<midi_struct>* midi::TrackList;
|
||||||
|
midi_struct *midi::track1, *midi::track2, *midi::track3, *midi::active_track, *midi::active_track2;
|
||||||
|
int midi::some_flag1;
|
||||||
|
|
||||||
|
int midi::music_init_ft(HWND hwnd)
|
||||||
|
{
|
||||||
|
midi_notify_hwnd = hwnd;
|
||||||
|
active_track = nullptr;
|
||||||
|
TrackList = new objlist_class<midi_struct>(0, 1);
|
||||||
|
|
||||||
|
track1 = load_track("taba1");
|
||||||
|
track2 = load_track("taba2");
|
||||||
|
track3 = load_track("taba3");
|
||||||
|
if (!track2)
|
||||||
|
track2 = track1;
|
||||||
|
if (!track3)
|
||||||
|
track3 = track1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void midi::music_shutdown_ft()
|
||||||
|
{
|
||||||
|
if (active_track)
|
||||||
|
stream_close(active_track);
|
||||||
|
while (TrackList->GetCount())
|
||||||
|
{
|
||||||
|
midi_struct* midi = TrackList->Get(0);
|
||||||
|
unload_track(midi);
|
||||||
|
TrackList->Delete(midi);
|
||||||
|
}
|
||||||
|
active_track = nullptr;
|
||||||
|
delete TrackList;
|
||||||
|
}
|
||||||
|
|
||||||
|
midi_struct* midi::load_track(LPCSTR fileName)
|
||||||
|
{
|
||||||
|
midi_struct* midi;
|
||||||
|
char filePath[256];
|
||||||
|
char fileName2[256];
|
||||||
|
|
||||||
|
lstrcpyA(fileName2, "sound\\");
|
||||||
|
lstrcatA(fileName2, fileName);
|
||||||
|
pinball::make_path_name(filePath, fileName2, 254u);
|
||||||
|
lstrcatA(filePath, ".MDS");
|
||||||
|
if (load_file(&midi, filePath, 0, 1))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
if (midi)
|
||||||
|
TrackList->Add(midi);
|
||||||
|
return midi;
|
||||||
|
}
|
||||||
|
|
||||||
|
int midi::load_file(midi_struct** midi_res, void* filePtrOrPath, int fileSizeP, int flags)
|
||||||
|
{
|
||||||
|
int returnCode;
|
||||||
|
unsigned int fileSize;
|
||||||
|
HANDLE mapHandle = nullptr;
|
||||||
|
midi_struct* midi = nullptr;
|
||||||
|
HANDLE fileHandle = INVALID_HANDLE_VALUE;
|
||||||
|
int fileFlag = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if ((flags & 3) == 0 || (flags & 3) == 3)
|
||||||
|
{
|
||||||
|
returnCode = 4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
midi = static_cast<midi_struct*>(LocalAlloc(0x40u, sizeof(midi_struct)));
|
||||||
|
if (!midi)
|
||||||
|
{
|
||||||
|
returnCode = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
midi->Magic = mmioFOURCC('M', 'D', 'S', 'I');
|
||||||
|
midi->StreamHandle = nullptr;
|
||||||
|
midi->PreparedBlocksCount = 0;
|
||||||
|
|
||||||
|
if ((flags & 2) != 0)
|
||||||
|
{
|
||||||
|
fileSize = fileSizeP;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fileFlag = 1;
|
||||||
|
fileHandle = CreateFileA(static_cast<LPCSTR>(filePtrOrPath), GENERIC_READ, 1u, nullptr, OPEN_EXISTING,
|
||||||
|
0x80u, nullptr);
|
||||||
|
if (fileHandle == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
returnCode = 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
fileSize = GetFileSize(fileHandle, nullptr);
|
||||||
|
mapHandle = CreateFileMappingA(fileHandle, nullptr, 2u, 0, 0, nullptr);
|
||||||
|
if (!mapHandle)
|
||||||
|
{
|
||||||
|
returnCode = 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
filePtrOrPath = MapViewOfFile(mapHandle, 4u, 0, 0, 0);
|
||||||
|
if (!filePtrOrPath)
|
||||||
|
{
|
||||||
|
returnCode = 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
returnCode = read_file(midi, static_cast<riff_header*>(filePtrOrPath), fileSize);
|
||||||
|
}
|
||||||
|
while (false);
|
||||||
|
|
||||||
|
|
||||||
|
if (returnCode)
|
||||||
|
{
|
||||||
|
if (midi)
|
||||||
|
LocalFree(midi);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*midi_res = midi;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fileFlag)
|
||||||
|
{
|
||||||
|
if (filePtrOrPath)
|
||||||
|
UnmapViewOfFile(filePtrOrPath);
|
||||||
|
if (mapHandle)
|
||||||
|
CloseHandle(mapHandle);
|
||||||
|
if (fileHandle != INVALID_HANDLE_VALUE)
|
||||||
|
CloseHandle(fileHandle);
|
||||||
|
}
|
||||||
|
return returnCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
int midi::read_file(midi_struct* midi, riff_header* filePtr, unsigned fileSize)
|
||||||
|
{
|
||||||
|
auto returnCode = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
midi->DataPtr1 = nullptr;
|
||||||
|
if (fileSize < 12)
|
||||||
|
{
|
||||||
|
returnCode = 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (filePtr->Riff != mmioFOURCC('R', 'I', 'F', 'F'))
|
||||||
|
{
|
||||||
|
returnCode = 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (filePtr->Mids != mmioFOURCC('M', 'I', 'D', 'S'))
|
||||||
|
{
|
||||||
|
returnCode = 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (filePtr->FileSize > fileSize - 8)
|
||||||
|
{
|
||||||
|
returnCode = 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (fileSize - 12 < 8)
|
||||||
|
{
|
||||||
|
returnCode = 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (filePtr->Fmt != mmioFOURCC('f', 'm', 't', ' '))
|
||||||
|
{
|
||||||
|
returnCode = 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (filePtr->FmtSize > fileSize - 12)
|
||||||
|
{
|
||||||
|
returnCode = 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (filePtr->FmtSize < 12)
|
||||||
|
{
|
||||||
|
returnCode = 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
midi->DwTimeFormat = filePtr->dwTimeFormat;
|
||||||
|
midi->CbMaxBuffer = filePtr->cbMaxBuffer;
|
||||||
|
midi->DwFlagsFormat = filePtr->dwFlags;
|
||||||
|
auto blocksSize = fileSize - 20 - filePtr->FmtSize;
|
||||||
|
if (blocksSize < 8)
|
||||||
|
{
|
||||||
|
returnCode = 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto dataChunk = reinterpret_cast<riff_data*>(reinterpret_cast<char*>(&filePtr->dwTimeFormat) + filePtr->FmtSize
|
||||||
|
);
|
||||||
|
if (dataChunk->Data != mmioFOURCC('d','a','t','a'))
|
||||||
|
{
|
||||||
|
returnCode = 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (dataChunk->DataSize > blocksSize || dataChunk->DataSize < 4)
|
||||||
|
{
|
||||||
|
returnCode = 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
midi->BlockCount = dataChunk->BlocksPerChunk;
|
||||||
|
midi->DataPtr1 = reinterpret_cast<midihdr_tag*>(memory::allocate(
|
||||||
|
dataChunk->BlocksPerChunk * (midi->CbMaxBuffer + sizeof(midihdr_tag))));
|
||||||
|
if (!midi->DataPtr1)
|
||||||
|
{
|
||||||
|
returnCode = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!midi->BlockCount)
|
||||||
|
{
|
||||||
|
returnCode = 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto blocksSizeIndex = blocksSize - 12;
|
||||||
|
auto srcPtr = dataChunk->Blocks;
|
||||||
|
auto* dstPtr = midi->DataPtr1;
|
||||||
|
for (auto blockIndex = midi->BlockCount; blockIndex; blockIndex--)
|
||||||
|
{
|
||||||
|
dstPtr->lpData = reinterpret_cast<LPSTR>(&dstPtr[1]);
|
||||||
|
dstPtr->dwBufferLength = midi->CbMaxBuffer;
|
||||||
|
dstPtr->dwFlags = 0;
|
||||||
|
dstPtr->dwUser = reinterpret_cast<DWORD_PTR>(midi);
|
||||||
|
dstPtr->lpNext = nullptr;
|
||||||
|
if (blocksSizeIndex < 8)
|
||||||
|
{
|
||||||
|
returnCode = 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto blockSize = srcPtr->CbBuffer;
|
||||||
|
if (blockSize > midi->CbMaxBuffer || blockSize > blocksSizeIndex - 8)
|
||||||
|
{
|
||||||
|
returnCode = 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((midi->DwFlagsFormat & 1) != 0)
|
||||||
|
{
|
||||||
|
/*Not used in FT, some kind of compression*/
|
||||||
|
assertm(false, "Unimplemented code reached");
|
||||||
|
/*int a1[16];
|
||||||
|
a1[0] = (int)blockDataPtr;
|
||||||
|
a1[2] = blockSize;
|
||||||
|
a1[1] = blockSize;
|
||||||
|
if (!sub_4031A0(a1, dataPtr))
|
||||||
|
{
|
||||||
|
returnCode = 3; break;
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dstPtr->dwBytesRecorded = blockSize;
|
||||||
|
memcpy(dstPtr->lpData, srcPtr->AData, blockSize);
|
||||||
|
}
|
||||||
|
blocksSizeIndex -= blockSize + 8;
|
||||||
|
srcPtr = reinterpret_cast<riff_block*>(&srcPtr->AData[blockSize]);
|
||||||
|
dstPtr = reinterpret_cast<midihdr_tag*>(reinterpret_cast<char*>(&dstPtr[1]) + midi->CbMaxBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (false);
|
||||||
|
|
||||||
|
if (returnCode && midi->DataPtr1)
|
||||||
|
{
|
||||||
|
memory::free(midi->DataPtr1);
|
||||||
|
}
|
||||||
|
return returnCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
int midi::play_ft(midi_struct* midi)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
|
||||||
|
stop_ft();
|
||||||
|
if (!midi)
|
||||||
|
return 0;
|
||||||
|
if (some_flag1)
|
||||||
|
{
|
||||||
|
active_track2 = midi;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (stream_open(midi, 1))
|
||||||
|
{
|
||||||
|
active_track = nullptr;
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
active_track = midi;
|
||||||
|
result = 1;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int midi::stop_ft()
|
||||||
|
{
|
||||||
|
int returnCode = 0;
|
||||||
|
if (active_track)
|
||||||
|
returnCode = stream_close(active_track);
|
||||||
|
active_track = nullptr;
|
||||||
|
return returnCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
int midi::unload_track(midi_struct* midi)
|
||||||
|
{
|
||||||
|
if (midi->Magic != mmioFOURCC('M', 'D', 'S', 'I'))
|
||||||
|
return 6;
|
||||||
|
if (midi->StreamHandle)
|
||||||
|
stream_close(midi);
|
||||||
|
if (midi->DataPtr1)
|
||||||
|
{
|
||||||
|
memory::free(midi->DataPtr1);
|
||||||
|
}
|
||||||
|
midi->Magic = mmioFOURCC('d','a','t','a');
|
||||||
|
LocalFree(midi);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int midi::stream_open(midi_struct* midi, char flags)
|
||||||
|
{
|
||||||
|
auto returnCode = 0;
|
||||||
|
if (midi->Magic != mmioFOURCC('M', 'D', 'S', 'I'))
|
||||||
|
return 6;
|
||||||
|
|
||||||
|
UINT puDeviceID = -1;
|
||||||
|
auto steamOpenedFg = !midi->StreamHandle;
|
||||||
|
MIDIPROPTIMEDIV propdata{8, midi->DwTimeFormat};
|
||||||
|
if (steamOpenedFg &&
|
||||||
|
!midiStreamOpen(&midi->StreamHandle, &puDeviceID, 1u, reinterpret_cast<DWORD_PTR>(midi_callback), 0,
|
||||||
|
CALLBACK_FUNCTION) &&
|
||||||
|
!midiStreamProperty(midi->StreamHandle, reinterpret_cast<LPBYTE>(&propdata),MIDIPROP_TIMEDIV | MIDIPROP_SET))
|
||||||
|
{
|
||||||
|
midihdr_tag* blockPtr = midi->DataPtr1;
|
||||||
|
for (auto blockIndex = midi->BlockCount; blockIndex; blockIndex--)
|
||||||
|
{
|
||||||
|
if (midiOutPrepareHeader(reinterpret_cast<HMIDIOUT>(midi->StreamHandle), blockPtr, sizeof(MIDIHDR)) ||
|
||||||
|
midiStreamOut(midi->StreamHandle, blockPtr, sizeof(MIDIHDR)))
|
||||||
|
{
|
||||||
|
returnCode = 5;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
++midi->PreparedBlocksCount;
|
||||||
|
blockPtr = reinterpret_cast<midihdr_tag*>(reinterpret_cast<char*>(&blockPtr[1]) + blockPtr->dwBufferLength);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!returnCode)
|
||||||
|
{
|
||||||
|
if (!steamOpenedFg && (midi->SomeFlag2 & 4) == 0)
|
||||||
|
return 7;
|
||||||
|
|
||||||
|
midi->SomeFlag2 &= ~2;
|
||||||
|
if ((flags & 1) != 0)
|
||||||
|
midi->SomeFlag2 |= 2;
|
||||||
|
midi->SomeFlag2 &= ~4;
|
||||||
|
if (midiStreamRestart(midi->StreamHandle))
|
||||||
|
returnCode = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (returnCode && steamOpenedFg)
|
||||||
|
{
|
||||||
|
if (midi->StreamHandle)
|
||||||
|
stream_close(midi);
|
||||||
|
}
|
||||||
|
return returnCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
int midi::stream_close(midi_struct* midi)
|
||||||
|
{
|
||||||
|
int returnCode;
|
||||||
|
|
||||||
|
if (midi->Magic != mmioFOURCC('M', 'D', 'S', 'I'))
|
||||||
|
return 6;
|
||||||
|
if (!midi->StreamHandle)
|
||||||
|
return 7;
|
||||||
|
midi->SomeFlag2 |= 1u;
|
||||||
|
if (midiOutReset(reinterpret_cast<HMIDIOUT>(midi->StreamHandle)))
|
||||||
|
{
|
||||||
|
returnCode = 5;
|
||||||
|
midi->SomeFlag2 &= ~1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
midihdr_tag* blockPtr = midi->DataPtr1;
|
||||||
|
for (int i = midi->BlockCount; i; --i)
|
||||||
|
{
|
||||||
|
midiOutUnprepareHeader(reinterpret_cast<HMIDIOUT>(midi->StreamHandle), blockPtr, sizeof(MIDIHDR));
|
||||||
|
blockPtr = reinterpret_cast<midihdr_tag*>(reinterpret_cast<char*>(&blockPtr[1]) + blockPtr->dwBufferLength);
|
||||||
|
}
|
||||||
|
midiStreamClose(midi->StreamHandle);
|
||||||
|
returnCode = 0;
|
||||||
|
midi->StreamHandle = nullptr;
|
||||||
|
midi->SomeFlag2 = 0;
|
||||||
|
}
|
||||||
|
return returnCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void midi::midi_callback(HMIDIOUT hmo, UINT wMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
|
||||||
|
{
|
||||||
|
if (wMsg == 969)
|
||||||
|
{
|
||||||
|
auto mhdr = reinterpret_cast<LPMIDIHDR>(dwParam1);
|
||||||
|
auto midi = reinterpret_cast<midi_struct*>(mhdr->dwUser);
|
||||||
|
if ((midi->SomeFlag2 & 2) == 0 || (midi->SomeFlag2 & 1) != 0 || midiStreamOut(
|
||||||
|
midi->StreamHandle, mhdr, sizeof(MIDIHDR)))
|
||||||
|
--midi->PreparedBlocksCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,16 +1,81 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "objlist_class.h"
|
||||||
|
|
||||||
|
struct midi_struct
|
||||||
|
{
|
||||||
|
DWORD Magic;
|
||||||
|
DWORD DwTimeFormat;
|
||||||
|
DWORD CbMaxBuffer;
|
||||||
|
DWORD DwFlagsFormat;
|
||||||
|
midihdr_tag* DataPtr1;
|
||||||
|
HMIDISTRM StreamHandle;
|
||||||
|
int SomeFlag2;
|
||||||
|
int BlockCount;
|
||||||
|
int PreparedBlocksCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
#pragma pack(push)
|
||||||
|
#pragma pack(1)
|
||||||
|
struct riff_block
|
||||||
|
{
|
||||||
|
DWORD TkStart;
|
||||||
|
DWORD CbBuffer;
|
||||||
|
char AData[4];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct riff_data
|
||||||
|
{
|
||||||
|
DWORD Data;
|
||||||
|
DWORD DataSize;
|
||||||
|
DWORD BlocksPerChunk;
|
||||||
|
riff_block Blocks[1];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct riff_header
|
||||||
|
{
|
||||||
|
DWORD Riff;
|
||||||
|
DWORD FileSize;
|
||||||
|
DWORD Mids;
|
||||||
|
DWORD Fmt;
|
||||||
|
DWORD FmtSize;
|
||||||
|
DWORD dwTimeFormat;
|
||||||
|
DWORD cbMaxBuffer;
|
||||||
|
DWORD dwFlags;
|
||||||
|
riff_data Data;
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert(sizeof(riff_block) == 0xC, "Wrong size of riff_block");
|
||||||
|
static_assert(sizeof(riff_data) == 0x18, "Wrong size of riff_data");
|
||||||
|
static_assert(sizeof(riff_header) == 0x38, "Wrong size of riff_header");
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
class midi
|
class midi
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static MCIERROR play_pb_theme(int flag);
|
static MCIERROR play_pb_theme(int flag);
|
||||||
static MCIERROR music_stop();
|
static MCIERROR music_stop();
|
||||||
static int music_init(HWND hwnd);
|
static int music_init(HWND hwnd);
|
||||||
static MCIERROR restart_midi_seq(int param);
|
static MCIERROR restart_midi_seq(LPARAM param);
|
||||||
static void music_shutdown();
|
static void music_shutdown();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static tagMCI_OPEN_PARMSA mci_open_info;
|
static tagMCI_OPEN_PARMSA mci_open_info;
|
||||||
static char midi_device_type[28];
|
static char midi_file_name[28];
|
||||||
static HWND midi_notify_hwnd;
|
static HWND midi_notify_hwnd;
|
||||||
static int midi_seq1_open, midi_seq1_playing;
|
static int midi_seq1_open, midi_seq1_playing;
|
||||||
|
|
||||||
|
static objlist_class<midi_struct>* TrackList;
|
||||||
|
static midi_struct *track1, *track2, *track3, *active_track, *active_track2;
|
||||||
|
static int some_flag1;
|
||||||
|
static int music_init_ft(HWND hwnd);
|
||||||
|
static void music_shutdown_ft();
|
||||||
|
static midi_struct* load_track(LPCSTR fileName);
|
||||||
|
static int load_file(midi_struct** midi_res, void* filePtrOrPath, int fileSizeP, int flags);
|
||||||
|
static int read_file(midi_struct* midi, riff_header* filePtr, unsigned int fileSize);
|
||||||
|
static int play_ft(midi_struct* midi);
|
||||||
|
static int stop_ft();
|
||||||
|
static int unload_track(midi_struct* midi);
|
||||||
|
static int stream_open(midi_struct* midi, char flags);
|
||||||
|
static int stream_close(midi_struct* midi);
|
||||||
|
static void CALLBACK midi_callback(HMIDIOUT hmo, UINT wMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1,
|
||||||
|
DWORD_PTR dwParam2);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -71,21 +71,21 @@ void nudge::_nudge(float xDiff, float yDiff)
|
|||||||
auto ballList = pb::MainTable->BallList;
|
auto ballList = pb::MainTable->BallList;
|
||||||
accelMod.X = xDiff * 0.5f;
|
accelMod.X = xDiff * 0.5f;
|
||||||
accelMod.Y = yDiff * 0.5f;
|
accelMod.Y = yDiff * 0.5f;
|
||||||
for (auto index = 0; index < ballList->Count(); index++)
|
for (auto index = 0; index < ballList->GetCount(); index++)
|
||||||
{
|
{
|
||||||
auto ball = static_cast<TBall*>(ballList->Get(index));
|
auto ball = ballList->Get(index);
|
||||||
if (ball->ActiveFlag && !ball->CollisionComp)
|
if (ball->ActiveFlag && !ball->CollisionComp)
|
||||||
{
|
{
|
||||||
ball->Acceleration.X = ball->Acceleration.X * ball->Speed;
|
ball->Acceleration.X = ball->Acceleration.X * ball->Speed;
|
||||||
ball->Acceleration.Y = ball->Acceleration.Y * ball->Speed;
|
ball->Acceleration.Y = ball->Acceleration.Y * ball->Speed;
|
||||||
maths::vector_add(&ball->Acceleration, &accelMod);
|
maths::vector_add(&ball->Acceleration, &accelMod);
|
||||||
ball->Speed = maths::normalize_2d(&ball->Acceleration);
|
ball->Speed = maths::normalize_2d(&ball->Acceleration);
|
||||||
if (0.0 == ball->Acceleration.X)
|
if (ball->Acceleration.X == 0.0f)
|
||||||
invAccelX = 1000000000.0;
|
invAccelX = 1000000000.0;
|
||||||
else
|
else
|
||||||
invAccelX = 1.0f / ball->Acceleration.X;
|
invAccelX = 1.0f / ball->Acceleration.X;
|
||||||
ball->InvAcceleration.X = invAccelX;
|
ball->InvAcceleration.X = invAccelX;
|
||||||
if (0.0 == ball->Acceleration.Y)
|
if (ball->Acceleration.Y == 0.0f)
|
||||||
invAccelY = 1000000000.0;
|
invAccelY = 1000000000.0;
|
||||||
else
|
else
|
||||||
invAccelY = 1.0f / ball->Acceleration.Y;
|
invAccelY = 1.0f / ball->Acceleration.Y;
|
||||||
@@ -94,6 +94,6 @@ void nudge::_nudge(float xDiff, float yDiff)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render::shift(static_cast<int>(floor(xDiff + 0.5)), static_cast<int>(floor(0.5 - yDiff)), 0, 0, table->Width,
|
render::shift(static_cast<int>(floor(xDiff + 0.5f)), static_cast<int>(floor(0.5f - yDiff)), 0, 0, table->Width,
|
||||||
table->Height);
|
table->Height);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,94 +0,0 @@
|
|||||||
#include "pch.h"
|
|
||||||
#include "objlist_class.h"
|
|
||||||
#include <cstdlib>
|
|
||||||
|
|
||||||
#include "memory.h"
|
|
||||||
// v1 from Ida
|
|
||||||
|
|
||||||
objlist_class::objlist_class(int SizeInt, int growSize)
|
|
||||||
{
|
|
||||||
ListPtr = objlist_new(SizeInt);
|
|
||||||
GrowSize = growSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
objlist_class::~objlist_class()
|
|
||||||
{
|
|
||||||
if (ListPtr)
|
|
||||||
memory::free(ListPtr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void objlist_class::Add(void* value)
|
|
||||||
{
|
|
||||||
if (this->ListPtr->Count == this->ListPtr->Size)
|
|
||||||
Grow();
|
|
||||||
objlist_add_object(ListPtr, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void objlist_class::Grow()
|
|
||||||
{
|
|
||||||
this->ListPtr = objlist_grow(this->ListPtr, this->GrowSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
int objlist_class::Delete(void* value)
|
|
||||||
{
|
|
||||||
return objlist_delete_object(ListPtr, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void* objlist_class::Get(int index)
|
|
||||||
{
|
|
||||||
if (index >= ListPtr->Count)
|
|
||||||
return nullptr;
|
|
||||||
return this->ListPtr->Array[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
objlist_struct1* objlist_class::objlist_new(int sizeInt)
|
|
||||||
{
|
|
||||||
objlist_struct1* result = (objlist_struct1 *)memory::allocate(sizeof(void*) * sizeInt + sizeof(objlist_struct1));
|
|
||||||
if (!result)
|
|
||||||
return result;
|
|
||||||
result->Count = 0;
|
|
||||||
result->Size = sizeInt;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
int objlist_class::objlist_add_object(objlist_struct1* ptrToStruct, void* value)
|
|
||||||
{
|
|
||||||
int addIndex = ptrToStruct->Count;
|
|
||||||
if (addIndex >= ptrToStruct->Size)
|
|
||||||
return 0;
|
|
||||||
ptrToStruct->Array[addIndex] = value;
|
|
||||||
return ++ptrToStruct->Count;
|
|
||||||
}
|
|
||||||
|
|
||||||
objlist_struct1* objlist_class::objlist_grow(objlist_struct1* ptrToStruct, int growSize)
|
|
||||||
{
|
|
||||||
objlist_struct1* resultPtr = ptrToStruct;
|
|
||||||
if (!ptrToStruct)
|
|
||||||
return resultPtr;
|
|
||||||
int newSizeInt = growSize + ptrToStruct->Count;
|
|
||||||
if (newSizeInt <= ptrToStruct->Size)
|
|
||||||
return resultPtr;
|
|
||||||
objlist_struct1* resultPtr2 = (objlist_struct1*)memory::realloc(ptrToStruct, sizeof(void*) * newSizeInt + sizeof(objlist_struct1));
|
|
||||||
if (!resultPtr2)
|
|
||||||
return resultPtr;
|
|
||||||
resultPtr = resultPtr2;
|
|
||||||
resultPtr2->Size = growSize + resultPtr2->Count;
|
|
||||||
return resultPtr;
|
|
||||||
}
|
|
||||||
|
|
||||||
int objlist_class::objlist_delete_object(objlist_struct1* ptrToStruct, void* value)
|
|
||||||
{
|
|
||||||
int count = ptrToStruct->Count;
|
|
||||||
int index = count - 1;
|
|
||||||
if (count - 1 < 0)
|
|
||||||
return 0;
|
|
||||||
for (void** i = &ptrToStruct->Array[index]; *i != value; --i)
|
|
||||||
{
|
|
||||||
if (--index < 0)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
ptrToStruct->Array[index] = ptrToStruct->Array[count - 1];
|
|
||||||
--ptrToStruct->Count;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
@@ -1,28 +1,78 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
struct objlist_struct1
|
#include "memory.h"
|
||||||
{
|
|
||||||
int Size;
|
|
||||||
int Count;
|
|
||||||
void* Array[1];
|
|
||||||
};
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
class objlist_class
|
class objlist_class
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
objlist_class(int SizeInt, int growSize);
|
objlist_class(int sizeInt, int growSize)
|
||||||
~objlist_class();
|
{
|
||||||
void Add(void* value);
|
ListPtr = memory::allocate<T*>(sizeInt);
|
||||||
void Grow();
|
Count = 0;
|
||||||
int Delete(void* value);
|
Size = sizeInt;
|
||||||
void* Get(int index);
|
GrowSize = growSize;
|
||||||
int Count() const { return !ListPtr ? 0 : ListPtr->Count; }
|
}
|
||||||
int Size() const { return !ListPtr ? 0 : ListPtr->Size; }
|
|
||||||
|
~objlist_class()
|
||||||
|
{
|
||||||
|
if (ListPtr)
|
||||||
|
memory::free(ListPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Add(T* value)
|
||||||
|
{
|
||||||
|
if (Count == Size)
|
||||||
|
Grow();
|
||||||
|
if (Count >= Size)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ListPtr[Count] = value;
|
||||||
|
Count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Grow()
|
||||||
|
{
|
||||||
|
if (!ListPtr)
|
||||||
|
return;
|
||||||
|
auto newSize = Count + GrowSize;
|
||||||
|
if (newSize <= Size)
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto newList = memory::realloc(ListPtr, sizeof(T*) * newSize);
|
||||||
|
if (!newList)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ListPtr = newList;
|
||||||
|
Size = newSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Delete(T* value)
|
||||||
|
{
|
||||||
|
for (auto index = Count - 1; index >= 0; index--)
|
||||||
|
{
|
||||||
|
if (ListPtr[index] == value)
|
||||||
|
{
|
||||||
|
ListPtr[index] = ListPtr[Count - 1];
|
||||||
|
Count--;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
T* Get(int index) const
|
||||||
|
{
|
||||||
|
if (index >= Count)
|
||||||
|
return nullptr;
|
||||||
|
return ListPtr[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetCount() const { return Count; }
|
||||||
|
int GetSize() const { return Size; }
|
||||||
private:
|
private:
|
||||||
objlist_struct1* ListPtr;
|
T** ListPtr;
|
||||||
int GrowSize;
|
int GrowSize;
|
||||||
static objlist_struct1* objlist_new(int sizeInt);
|
int Size;
|
||||||
static int objlist_add_object(objlist_struct1* ptrToStruct, void* value);
|
int Count;
|
||||||
static objlist_struct1* objlist_grow(objlist_struct1* ptrToStruct, int growSize);
|
|
||||||
static int objlist_delete_object(objlist_struct1* ptrToStruct, void* value);
|
|
||||||
};
|
};
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,40 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "pinball.h"
|
#include "pinball.h"
|
||||||
|
#include "resource.h"
|
||||||
|
|
||||||
|
enum class Languages
|
||||||
|
{
|
||||||
|
English = MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
|
||||||
|
Russian = MAKELANGID(LANG_RUSSIAN, SUBLANG_RUSSIAN_RUSSIA),
|
||||||
|
TraditionalChinese = MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL),
|
||||||
|
SimplifiedChinese = MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED),
|
||||||
|
Polish = MAKELANGID(LANG_POLISH, SUBLANG_POLISH_POLAND),
|
||||||
|
German = MAKELANGID(LANG_GERMAN, SUBLANG_GERMAN),
|
||||||
|
Japanese = MAKELANGID(LANG_JAPANESE, SUBLANG_JAPANESE_JAPAN),
|
||||||
|
French = MAKELANGID(LANG_FRENCH, SUBLANG_FRENCH),
|
||||||
|
Italian = MAKELANGID(LANG_ITALIAN, SUBLANG_ITALIAN),
|
||||||
|
Hungarian = MAKELANGID(LANG_HUNGARIAN, SUBLANG_HUNGARIAN_HUNGARY),
|
||||||
|
Portuguese = MAKELANGID(LANG_PORTUGUESE, SUBLANG_PORTUGUESE),
|
||||||
|
BrazilianPortuguese = MAKELANGID(LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN),
|
||||||
|
Czech = MAKELANGID(LANG_CZECH, SUBLANG_CZECH_CZECH_REPUBLIC),
|
||||||
|
Danish = MAKELANGID(LANG_DANISH, SUBLANG_DANISH_DENMARK),
|
||||||
|
Finnish = MAKELANGID(LANG_FINNISH, SUBLANG_FINNISH_FINLAND),
|
||||||
|
Hebrew = MAKELANGID(LANG_HEBREW, SUBLANG_HEBREW_ISRAEL),
|
||||||
|
Arabic = MAKELANGID(LANG_ARABIC, SUBLANG_ARABIC_SAUDI_ARABIA),
|
||||||
|
Greek = MAKELANGID(LANG_GREEK, SUBLANG_GREEK_GREECE),
|
||||||
|
Spanish = MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH_MODERN),
|
||||||
|
Korean = MAKELANGID(LANG_KOREAN, SUBLANG_KOREAN),
|
||||||
|
Dutch = MAKELANGID(LANG_DUTCH, SUBLANG_DUTCH),
|
||||||
|
Norwegian = MAKELANGID(LANG_NORWEGIAN, SUBLANG_NORWEGIAN_BOKMAL),
|
||||||
|
Swedish = MAKELANGID(LANG_SWEDISH, SUBLANG_SWEDISH),
|
||||||
|
Turkish = MAKELANGID(LANG_TURKISH, SUBLANG_TURKISH_TURKEY),
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LanguageMenuEntry
|
||||||
|
{
|
||||||
|
LPCWSTR Name;
|
||||||
|
Languages Language;
|
||||||
|
};
|
||||||
|
|
||||||
struct optionsStruct
|
struct optionsStruct
|
||||||
{
|
{
|
||||||
@@ -21,27 +56,36 @@ struct optionsStruct
|
|||||||
int LeftTableBumpKeyDft;
|
int LeftTableBumpKeyDft;
|
||||||
int RightTableBumpKeyDft;
|
int RightTableBumpKeyDft;
|
||||||
int BottomTableBumpKeyDft;
|
int BottomTableBumpKeyDft;
|
||||||
|
int Resolution;
|
||||||
|
bool UniformScaling;
|
||||||
|
bool AlternativeRender;
|
||||||
|
Languages Language;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class options
|
class options
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
static void ReadOptions();
|
||||||
static void init(HMENU menuHandle);
|
static void init(HMENU menuHandle);
|
||||||
static void uninit();
|
static void uninit();
|
||||||
static void path_init(LPCSTR regPath);
|
static void path_init(LPCSTR regPath);
|
||||||
static void path_uninit();
|
static void path_uninit();
|
||||||
static int get_int(LPCSTR optPath, LPCSTR lpValueName, int defaultValue);
|
static int get_int(LPCSTR optPath, LPCSTR lpValueName, int defaultValue);
|
||||||
static void set_int(LPCSTR optPath, LPCSTR lpValueName, int data);
|
static void set_int(LPCSTR optPath, LPCSTR lpValueName, int data);
|
||||||
static void get_string(LPCSTR optPath, LPCSTR lpValueName, LPSTR lpString1, LPCSTR lpString2, int iMaxLength);
|
static void get_string(LPCSTR optPath, LPCSTR lpValueName, LPSTR dst, LPCSTR defaultValue, int iMaxLength);
|
||||||
static void set_string(LPCSTR optPath, LPCSTR lpValueName, LPCSTR value);
|
static void set_string(LPCSTR optPath, LPCSTR lpValueName, LPCSTR value);
|
||||||
|
static void get_string(LPCSTR optPath, LPCWSTR lpValueName, LPWSTR dst, LPCWSTR defaultValue, int iMaxLength);
|
||||||
|
static void set_string(LPCSTR optPath, LPCWSTR lpValueName, LPCWSTR value);
|
||||||
static void menu_check(UINT uIDCheckItem, int check);
|
static void menu_check(UINT uIDCheckItem, int check);
|
||||||
static void menu_set(UINT uIDEnableItem, int enable);
|
static void menu_set(UINT uIDEnableItem, int enable);
|
||||||
static void toggle(UINT uIDCheckItem);
|
static void toggle(UINT uIDCheckItem);
|
||||||
|
static void update_resolution_menu();
|
||||||
|
static void init_resolution();
|
||||||
|
|
||||||
static void keyboard();
|
static void keyboard();
|
||||||
static INT_PTR _stdcall KeyMapDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
|
static INT_PTR _stdcall KeyMapDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||||
static LPSTR get_vk_key_name(unsigned __int16 vk, LPSTR keyName);
|
static LPWSTR get_vk_key_name(uint16_t vk, LPWSTR keyName);
|
||||||
|
|
||||||
static optionsStruct Options;
|
static optionsStruct Options;
|
||||||
private:
|
private:
|
||||||
@@ -52,4 +96,5 @@ private:
|
|||||||
static HMENU MenuHandle;
|
static HMENU MenuHandle;
|
||||||
static winhelp_entry keymap_help[18];
|
static winhelp_entry keymap_help[18];
|
||||||
static short vk_list[28];
|
static short vk_list[28];
|
||||||
|
static LanguageMenuEntry LanguageMenu[Menu1_LanguageMax - Menu1_Language];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -9,8 +9,7 @@ short partman::_field_size[] =
|
|||||||
2, -1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0
|
2, -1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
datFileStruct* partman::load_records(LPCSTR lpFileName, int resolution, bool fullTiltMode)
|
||||||
datFileStruct* partman::load_records(LPCSTR lpFileName)
|
|
||||||
{
|
{
|
||||||
_OFSTRUCT ReOpenBuff{};
|
_OFSTRUCT ReOpenBuff{};
|
||||||
datFileHeader header{};
|
datFileHeader header{};
|
||||||
@@ -26,7 +25,7 @@ datFileStruct* partman::load_records(LPCSTR lpFileName)
|
|||||||
_lclose(fileHandle);
|
_lclose(fileHandle);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
auto datFile = (datFileStruct*)memory::allocate(sizeof(datFileStruct));
|
auto datFile = memory::allocate<datFileStruct>();
|
||||||
if (!datFile)
|
if (!datFile)
|
||||||
{
|
{
|
||||||
_lclose(fileHandle);
|
_lclose(fileHandle);
|
||||||
@@ -39,7 +38,7 @@ datFileStruct* partman::load_records(LPCSTR lpFileName)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
int lenOfStr = lstrlenA(header.Description);
|
int lenOfStr = lstrlenA(header.Description);
|
||||||
auto descriptionBuf = static_cast<char*>(memory::allocate(lenOfStr + 1));
|
auto descriptionBuf = memory::allocate(lenOfStr + 1);
|
||||||
datFile->Description = descriptionBuf;
|
datFile->Description = descriptionBuf;
|
||||||
if (!descriptionBuf)
|
if (!descriptionBuf)
|
||||||
{
|
{
|
||||||
@@ -52,7 +51,7 @@ datFileStruct* partman::load_records(LPCSTR lpFileName)
|
|||||||
|
|
||||||
if (header.Unknown)
|
if (header.Unknown)
|
||||||
{
|
{
|
||||||
auto unknownBuf = static_cast<char*>(memory::allocate(header.Unknown));
|
auto unknownBuf = memory::allocate(header.Unknown);
|
||||||
if (!unknownBuf)
|
if (!unknownBuf)
|
||||||
{
|
{
|
||||||
_lclose(fileHandle);
|
_lclose(fileHandle);
|
||||||
@@ -65,7 +64,7 @@ datFileStruct* partman::load_records(LPCSTR lpFileName)
|
|||||||
memory::free(unknownBuf);
|
memory::free(unknownBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto groupDataBuf = (datGroupData**)memory::allocate(sizeof(void*) * header.NumberOfGroups);
|
auto groupDataBuf = memory::allocate<datGroupData*>(header.NumberOfGroups);
|
||||||
datFile->GroupData = groupDataBuf;
|
datFile->GroupData = groupDataBuf;
|
||||||
if (!groupDataBuf)
|
if (!groupDataBuf)
|
||||||
{
|
{
|
||||||
@@ -80,16 +79,15 @@ datFileStruct* partman::load_records(LPCSTR lpFileName)
|
|||||||
{
|
{
|
||||||
auto entryCount = _lread_char(fileHandle);
|
auto entryCount = _lread_char(fileHandle);
|
||||||
auto groupDataSize = entryCount <= 0 ? 0 : entryCount - 1;
|
auto groupDataSize = entryCount <= 0 ? 0 : entryCount - 1;
|
||||||
auto groupData = reinterpret_cast<datGroupData*>(memory::allocate(
|
auto groupData = memory::allocate<datGroupData>(1, sizeof(datEntryData) * groupDataSize);
|
||||||
sizeof(datEntryData) * groupDataSize + sizeof(datGroupData)));
|
|
||||||
datFile->GroupData[groupIndex] = groupData;
|
datFile->GroupData[groupIndex] = groupData;
|
||||||
if (!groupData)
|
if (!groupData)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
groupData->EntryCount = entryCount;
|
groupData->EntryCount = 0;
|
||||||
datEntryData* entryData = groupData->Entries;
|
|
||||||
for (auto entryIndex = 0; entryIndex < entryCount; ++entryIndex)
|
for (auto entryIndex = 0; entryIndex < entryCount; ++entryIndex)
|
||||||
{
|
{
|
||||||
|
auto entryData = &groupData->Entries[groupData->EntryCount];
|
||||||
auto entryType = static_cast<datFieldTypes>(_lread_char(fileHandle));
|
auto entryType = static_cast<datFieldTypes>(_lread_char(fileHandle));
|
||||||
entryData->EntryType = entryType;
|
entryData->EntryType = entryType;
|
||||||
|
|
||||||
@@ -100,17 +98,28 @@ datFileStruct* partman::load_records(LPCSTR lpFileName)
|
|||||||
if (entryType == datFieldTypes::Bitmap8bit)
|
if (entryType == datFieldTypes::Bitmap8bit)
|
||||||
{
|
{
|
||||||
_hread(fileHandle, &bmpHeader, sizeof(dat8BitBmpHeader));
|
_hread(fileHandle, &bmpHeader, sizeof(dat8BitBmpHeader));
|
||||||
auto bmp = reinterpret_cast<gdrv_bitmap8*>(memory::allocate(sizeof(gdrv_bitmap8)));
|
if (bmpHeader.Resolution != resolution && bmpHeader.Resolution != -1)
|
||||||
|
{
|
||||||
|
_llseek(fileHandle, bmpHeader.Size, 1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto bmp = memory::allocate<gdrv_bitmap8>();
|
||||||
entryData->Buffer = reinterpret_cast<char*>(bmp);
|
entryData->Buffer = reinterpret_cast<char*>(bmp);
|
||||||
if (!bmp)
|
if (!bmp)
|
||||||
{
|
{
|
||||||
abort = true;
|
abort = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (bmpHeader.IsFlagSet(bmp8Flags::DibBitmap)
|
int bmpRez;
|
||||||
? gdrv::create_bitmap(bmp, bmpHeader.Width, bmpHeader.Height)
|
if (bmpHeader.IsFlagSet(bmp8Flags::Spliced))
|
||||||
: gdrv::create_raw_bitmap(bmp, bmpHeader.Width, bmpHeader.Height,
|
bmpRez = gdrv::create_spliced_bitmap(bmp, bmpHeader.Width, bmpHeader.Height, bmpHeader.Size);
|
||||||
bmpHeader.IsFlagSet(bmp8Flags::RawBmpUnaligned)))
|
else if (bmpHeader.IsFlagSet(bmp8Flags::DibBitmap))
|
||||||
|
bmpRez = gdrv::create_bitmap(bmp, bmpHeader.Width, bmpHeader.Height);
|
||||||
|
else
|
||||||
|
bmpRez = gdrv::create_raw_bitmap(bmp, bmpHeader.Width, bmpHeader.Height,
|
||||||
|
bmpHeader.IsFlagSet(bmp8Flags::RawBmpUnaligned));
|
||||||
|
if (bmpRez)
|
||||||
{
|
{
|
||||||
abort = true;
|
abort = true;
|
||||||
break;
|
break;
|
||||||
@@ -121,10 +130,22 @@ datFileStruct* partman::load_records(LPCSTR lpFileName)
|
|||||||
}
|
}
|
||||||
else if (entryType == datFieldTypes::Bitmap16bit)
|
else if (entryType == datFieldTypes::Bitmap16bit)
|
||||||
{
|
{
|
||||||
|
/*Full tilt has extra byte(@0:resolution) in zMap*/
|
||||||
|
if (fullTiltMode)
|
||||||
|
{
|
||||||
|
char zMapResolution = _lread_char(fileHandle);
|
||||||
|
fieldSize--;
|
||||||
|
if (zMapResolution != resolution && zMapResolution != -1)
|
||||||
|
{
|
||||||
|
_llseek(fileHandle, fieldSize, 1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_hread(fileHandle, &zMapHeader, sizeof(dat16BitBmpHeader));
|
_hread(fileHandle, &zMapHeader, sizeof(dat16BitBmpHeader));
|
||||||
int length = fieldSize - sizeof(dat16BitBmpHeader);
|
int length = fieldSize - sizeof(dat16BitBmpHeader);
|
||||||
|
|
||||||
auto zmap = reinterpret_cast<zmap_header_type*>(memory::allocate(sizeof(zmap_header_type) + length));
|
auto zmap = memory::allocate<zmap_header_type>(1, length);
|
||||||
zmap->Width = zMapHeader.Width;
|
zmap->Width = zMapHeader.Width;
|
||||||
zmap->Height = zMapHeader.Height;
|
zmap->Height = zMapHeader.Height;
|
||||||
zmap->Stride = zMapHeader.Stride;
|
zmap->Stride = zMapHeader.Stride;
|
||||||
@@ -133,7 +154,7 @@ datFileStruct* partman::load_records(LPCSTR lpFileName)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char* entryBuffer = static_cast<char*>(memory::allocate(fieldSize));
|
char* entryBuffer = memory::allocate(fieldSize);
|
||||||
entryData->Buffer = entryBuffer;
|
entryData->Buffer = entryBuffer;
|
||||||
if (!entryBuffer)
|
if (!entryBuffer)
|
||||||
{
|
{
|
||||||
@@ -144,9 +165,9 @@ datFileStruct* partman::load_records(LPCSTR lpFileName)
|
|||||||
}
|
}
|
||||||
|
|
||||||
entryData->FieldSize = fieldSize;
|
entryData->FieldSize = fieldSize;
|
||||||
datFile->NumberOfGroups = groupIndex + 1;
|
groupData->EntryCount++;
|
||||||
++entryData;
|
|
||||||
}
|
}
|
||||||
|
datFile->NumberOfGroups = groupIndex + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
_lclose(fileHandle);
|
_lclose(fileHandle);
|
||||||
@@ -159,30 +180,23 @@ datFileStruct* partman::load_records(LPCSTR lpFileName)
|
|||||||
|
|
||||||
void partman::unload_records(datFileStruct* datFile)
|
void partman::unload_records(datFileStruct* datFile)
|
||||||
{
|
{
|
||||||
for (int groupIndex = 0; groupIndex < datFile->NumberOfGroups; ++groupIndex)
|
for (auto groupIndex = 0; groupIndex < datFile->NumberOfGroups; ++groupIndex)
|
||||||
{
|
{
|
||||||
datGroupData* group = datFile->GroupData[groupIndex];
|
auto group = datFile->GroupData[groupIndex];
|
||||||
if (group)
|
if (!group)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (auto entryIndex = 0; entryIndex < group->EntryCount; ++entryIndex)
|
||||||
{
|
{
|
||||||
int entryIndex = 0;
|
auto entry = &group->Entries[entryIndex];
|
||||||
if (group->EntryCount > 0)
|
if (entry->Buffer)
|
||||||
{
|
{
|
||||||
datEntryData* entry = group->Entries;
|
if (entry->EntryType == datFieldTypes::Bitmap8bit)
|
||||||
do
|
gdrv::destroy_bitmap(reinterpret_cast<gdrv_bitmap8*>(entry->Buffer));
|
||||||
{
|
memory::free(entry->Buffer);
|
||||||
if (entry->Buffer)
|
|
||||||
{
|
|
||||||
if (entry->EntryType == datFieldTypes::Bitmap8bit)
|
|
||||||
gdrv::destroy_bitmap((gdrv_bitmap8*)entry->Buffer);
|
|
||||||
memory::free(entry->Buffer);
|
|
||||||
}
|
|
||||||
++entryIndex;
|
|
||||||
++entry;
|
|
||||||
}
|
|
||||||
while (entryIndex < group->EntryCount);
|
|
||||||
}
|
}
|
||||||
memory::free(group);
|
|
||||||
}
|
}
|
||||||
|
memory::free(group);
|
||||||
}
|
}
|
||||||
if (datFile->Description)
|
if (datFile->Description)
|
||||||
memory::free(datFile->Description);
|
memory::free(datFile->Description);
|
||||||
@@ -192,91 +206,45 @@ void partman::unload_records(datFileStruct* datFile)
|
|||||||
|
|
||||||
char* partman::field(datFileStruct* datFile, int groupIndex, datFieldTypes targetEntryType)
|
char* partman::field(datFileStruct* datFile, int groupIndex, datFieldTypes targetEntryType)
|
||||||
{
|
{
|
||||||
datGroupData* groupData = datFile->GroupData[groupIndex];
|
auto group = datFile->GroupData[groupIndex];
|
||||||
int entryCount = groupData->EntryCount;
|
for (auto entryIndex = 0; entryIndex < group->EntryCount; ++entryIndex)
|
||||||
int entryIndex = 0;
|
|
||||||
if (entryCount <= 0)
|
|
||||||
return nullptr;
|
|
||||||
datEntryData* entry = groupData->Entries;
|
|
||||||
while (true)
|
|
||||||
{
|
{
|
||||||
auto entryType = entry->EntryType;
|
auto entry = &group->Entries[entryIndex];
|
||||||
if (entryType == targetEntryType)
|
if (entry->EntryType == targetEntryType)
|
||||||
|
return entry->Buffer;
|
||||||
|
if (entry->EntryType > targetEntryType)
|
||||||
break;
|
break;
|
||||||
if (entryType > targetEntryType)
|
|
||||||
return nullptr;
|
|
||||||
++entryIndex;
|
|
||||||
++entry;
|
|
||||||
if (entryIndex < entryCount)
|
|
||||||
continue;
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
return entry->Buffer;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
char* partman::field_nth(datFileStruct* datFile, int groupIndex, datFieldTypes targetEntryType, int skipFirstN)
|
char* partman::field_nth(datFileStruct* datFile, int groupIndex, datFieldTypes targetEntryType, int skipFirstN)
|
||||||
{
|
{
|
||||||
datGroupData* groupData = datFile->GroupData[groupIndex];
|
auto group = datFile->GroupData[groupIndex];
|
||||||
int entryCount = groupData->EntryCount, skipCount = 0, entryIndex = 0;
|
for (auto skipCount = 0, entryIndex = 0; entryIndex < group->EntryCount; ++entryIndex)
|
||||||
if (0 < entryCount)
|
|
||||||
{
|
{
|
||||||
datEntryData* entry = groupData->Entries;
|
auto entry = &group->Entries[entryIndex];
|
||||||
do
|
if (entry->EntryType > targetEntryType)
|
||||||
{
|
break;
|
||||||
auto entryType = entry->EntryType;
|
if (entry->EntryType == targetEntryType)
|
||||||
if (entryType == targetEntryType)
|
if (skipCount++ == skipFirstN)
|
||||||
{
|
return entry->Buffer;
|
||||||
if (skipCount == skipFirstN)
|
|
||||||
{
|
|
||||||
return entry->Buffer;
|
|
||||||
}
|
|
||||||
skipCount++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (targetEntryType < entryType)
|
|
||||||
{
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
entryIndex++;
|
|
||||||
entry++;
|
|
||||||
}
|
|
||||||
while (entryIndex < entryCount);
|
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
int partman::field_size_nth(datFileStruct* datFile, int groupIndex, datFieldTypes targetEntryType, int skipFirstN)
|
int partman::field_size_nth(datFileStruct* datFile, int groupIndex, datFieldTypes targetEntryType, int skipFirstN)
|
||||||
{
|
{
|
||||||
datGroupData* groupData = datFile->GroupData[groupIndex];
|
auto group = datFile->GroupData[groupIndex];
|
||||||
int entryCount = groupData->EntryCount, skipCount = 0, entryIndex = 0;
|
for (auto skipCount = 0, entryIndex = 0; entryIndex < group->EntryCount; ++entryIndex)
|
||||||
if (0 < entryCount)
|
|
||||||
{
|
{
|
||||||
datEntryData* entry = groupData->Entries;
|
auto entry = &group->Entries[entryIndex];
|
||||||
do
|
if (entry->EntryType > targetEntryType)
|
||||||
{
|
return 0;
|
||||||
auto entryType = entry->EntryType;
|
if (entry->EntryType == targetEntryType)
|
||||||
if (entryType == targetEntryType)
|
if (skipCount++ == skipFirstN)
|
||||||
{
|
return entry->FieldSize;
|
||||||
if (skipCount == skipFirstN)
|
|
||||||
{
|
|
||||||
return entry->FieldSize;
|
|
||||||
}
|
|
||||||
skipCount++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (targetEntryType < entryType)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
entryIndex++;
|
|
||||||
entry++;
|
|
||||||
}
|
|
||||||
while (entryIndex < entryCount);
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -288,46 +256,28 @@ int partman::field_size(datFileStruct* datFile, int groupIndex, datFieldTypes ta
|
|||||||
|
|
||||||
int partman::record_labeled(datFileStruct* datFile, LPCSTR targetGroupName)
|
int partman::record_labeled(datFileStruct* datFile, LPCSTR targetGroupName)
|
||||||
{
|
{
|
||||||
int trgGroupNameLen = lstrlenA(targetGroupName);
|
auto targetLength = lstrlenA(targetGroupName);
|
||||||
int groupIndex = datFile->NumberOfGroups;
|
for (int groupIndex = datFile->NumberOfGroups - 1; groupIndex >= 0; --groupIndex)
|
||||||
while (true)
|
|
||||||
{
|
{
|
||||||
if (--groupIndex < 0)
|
auto groupName = field(datFile, groupIndex, datFieldTypes::GroupName);
|
||||||
return -1;
|
if (!groupName)
|
||||||
char* groupName = field(datFile, groupIndex, datFieldTypes::GroupName);
|
continue;
|
||||||
if (groupName)
|
|
||||||
{
|
int index;
|
||||||
int index = 0;
|
for (index = 0; index < targetLength; index++)
|
||||||
bool found = trgGroupNameLen == 0;
|
if (targetGroupName[index] != groupName[index])
|
||||||
if (trgGroupNameLen > 0)
|
|
||||||
{
|
|
||||||
LPCSTR targetNamePtr = targetGroupName;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if (*targetNamePtr != targetNamePtr[groupName - targetGroupName])
|
|
||||||
break;
|
|
||||||
++index;
|
|
||||||
++targetNamePtr;
|
|
||||||
}
|
|
||||||
while (index < trgGroupNameLen);
|
|
||||||
found = index == trgGroupNameLen;
|
|
||||||
}
|
|
||||||
if (found && !targetGroupName[index] && !groupName[index])
|
|
||||||
break;
|
break;
|
||||||
}
|
if (index == targetLength && !targetGroupName[index] && !groupName[index])
|
||||||
|
return groupIndex;
|
||||||
}
|
}
|
||||||
return groupIndex;
|
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* partman::field_labeled(datFileStruct* datFile, LPCSTR lpString, datFieldTypes fieldType)
|
char* partman::field_labeled(datFileStruct* datFile, LPCSTR lpString, datFieldTypes fieldType)
|
||||||
{
|
{
|
||||||
char* result;
|
auto groupIndex = record_labeled(datFile, lpString);
|
||||||
int groupIndex = record_labeled(datFile, lpString);
|
return groupIndex < 0 ? nullptr : field(datFile, groupIndex, fieldType);
|
||||||
if (groupIndex < 0)
|
|
||||||
result = nullptr;
|
|
||||||
else
|
|
||||||
result = field(datFile, groupIndex, fieldType);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char partman::_lread_char(HFILE hFile)
|
char partman::_lread_char(HFILE hFile)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
enum class datFieldTypes : __int16
|
enum class datFieldTypes : int16_t
|
||||||
{
|
{
|
||||||
ShortValue = 0,
|
ShortValue = 0,
|
||||||
//, does not have the 32bits size value, but a 16bits value(see above).
|
//, does not have the 32bits size value, but a 16bits value(see above).
|
||||||
@@ -28,7 +28,8 @@ enum class datFieldTypes : __int16
|
|||||||
enum class bmp8Flags : unsigned char
|
enum class bmp8Flags : unsigned char
|
||||||
{
|
{
|
||||||
RawBmpUnaligned = 1 << 0,
|
RawBmpUnaligned = 1 << 0,
|
||||||
DibBitmap = 1 << 1,
|
DibBitmap = 1 << 1,
|
||||||
|
Spliced = 1 << 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -56,7 +57,7 @@ struct datEntryData
|
|||||||
|
|
||||||
struct datGroupData
|
struct datGroupData
|
||||||
{
|
{
|
||||||
__int16 EntryCount;
|
int16_t EntryCount;
|
||||||
datEntryData Entries[1];
|
datEntryData Entries[1];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -71,11 +72,11 @@ struct datFileStruct
|
|||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
struct dat8BitBmpHeader
|
struct dat8BitBmpHeader
|
||||||
{
|
{
|
||||||
char Unknown1;
|
char Resolution;
|
||||||
__int16 Width;
|
int16_t Width;
|
||||||
__int16 Height;
|
int16_t Height;
|
||||||
__int16 XPosition;
|
int16_t XPosition;
|
||||||
__int16 YPosition;
|
int16_t YPosition;
|
||||||
int Size;
|
int Size;
|
||||||
bmp8Flags Flags;
|
bmp8Flags Flags;
|
||||||
|
|
||||||
@@ -93,12 +94,12 @@ static_assert(sizeof(dat8BitBmpHeader) == 14, "Wrong size of dat8BitBmpHeader");
|
|||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
struct __declspec(align(1)) dat16BitBmpHeader
|
struct __declspec(align(1)) dat16BitBmpHeader
|
||||||
{
|
{
|
||||||
__int16 Width;
|
int16_t Width;
|
||||||
__int16 Height;
|
int16_t Height;
|
||||||
__int16 Stride;
|
int16_t Stride;
|
||||||
int Unknown0;
|
int Unknown0;
|
||||||
__int16 Unknown1_0;
|
int16_t Unknown1_0;
|
||||||
__int16 Unknown1_1;
|
int16_t Unknown1_1;
|
||||||
};
|
};
|
||||||
|
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
@@ -108,7 +109,7 @@ static_assert(sizeof(dat16BitBmpHeader) == 14, "Wrong size of zmap_header_type")
|
|||||||
class partman
|
class partman
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static datFileStruct* load_records(LPCSTR lpFileName);
|
static datFileStruct* load_records(LPCSTR lpFileName, int resolution, bool fullTiltMode);
|
||||||
static void unload_records(datFileStruct* datFile);
|
static void unload_records(datFileStruct* datFile);
|
||||||
static char* field_nth(datFileStruct* datFile, int groupIndex, datFieldTypes targetEntryType, int skipFirstN);
|
static char* field_nth(datFileStruct* datFile, int groupIndex, datFieldTypes targetEntryType, int skipFirstN);
|
||||||
static char* field(datFileStruct* datFile, int groupIndex, datFieldTypes entryType);
|
static char* field(datFileStruct* datFile, int groupIndex, datFieldTypes entryType);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "control.h"
|
#include "control.h"
|
||||||
|
#include "fullscrn.h"
|
||||||
#include "high_score.h"
|
#include "high_score.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "pinball.h"
|
#include "pinball.h"
|
||||||
@@ -25,9 +26,11 @@
|
|||||||
|
|
||||||
TPinballTable* pb::MainTable = nullptr;
|
TPinballTable* pb::MainTable = nullptr;
|
||||||
datFileStruct* pb::record_table = nullptr;
|
datFileStruct* pb::record_table = nullptr;
|
||||||
int pb::time_ticks = 0, pb::demo_mode = 0, pb::cheat_mode = 0, pb::game_mode = 2, pb::mode_countdown_, pb::state;
|
int pb::time_ticks = 0, pb::demo_mode = 0, pb::game_mode = 2, pb::mode_countdown_, pb::state, pb::frameCounter = 0;
|
||||||
float pb::time_now, pb::time_next, pb::ball_speed_limit;
|
float pb::time_now, pb::time_next, pb::ball_speed_limit;
|
||||||
high_score_struct pb::highscore_table[5];
|
high_score_struct pb::highscore_table[5];
|
||||||
|
bool pb::FullTiltMode = false, pb::cheat_mode = false;
|
||||||
|
|
||||||
|
|
||||||
int pb::init()
|
int pb::init()
|
||||||
{
|
{
|
||||||
@@ -38,7 +41,7 @@ int pb::init()
|
|||||||
++memory::critical_allocation;
|
++memory::critical_allocation;
|
||||||
lstrcpyA(datFileName, winmain::DatFileName);
|
lstrcpyA(datFileName, winmain::DatFileName);
|
||||||
pinball::make_path_name(dataFilePath, datFileName, 300);
|
pinball::make_path_name(dataFilePath, datFileName, 300);
|
||||||
record_table = partman::load_records(dataFilePath);
|
record_table = partman::load_records(dataFilePath, fullscrn::GetResolution(), FullTiltMode);
|
||||||
|
|
||||||
auto useBmpFont = 0;
|
auto useBmpFont = 0;
|
||||||
pinball::get_rc_int(158, &useBmpFont);
|
pinball::get_rc_int(158, &useBmpFont);
|
||||||
@@ -46,29 +49,32 @@ int pb::init()
|
|||||||
score::load_msg_font("pbmsg_ft");
|
score::load_msg_font("pbmsg_ft");
|
||||||
|
|
||||||
if (!record_table)
|
if (!record_table)
|
||||||
return (int)&record_table->NumberOfGroups + 1;
|
return 1;
|
||||||
|
|
||||||
auto plt = (PALETTEENTRY*)partman::field_labeled(record_table, "background", datFieldTypes::Palette);
|
auto plt = (PALETTEENTRY*)partman::field_labeled(record_table, "background", datFieldTypes::Palette);
|
||||||
gdrv::display_palette(plt);
|
gdrv::display_palette(plt);
|
||||||
|
|
||||||
auto tableSize = (__int16*)partman::field_labeled(record_table, "table_size", datFieldTypes::ShortArray);
|
|
||||||
auto backgroundBmp = (gdrv_bitmap8*)partman::field_labeled(record_table, "background", datFieldTypes::Bitmap8bit);
|
auto backgroundBmp = (gdrv_bitmap8*)partman::field_labeled(record_table, "background", datFieldTypes::Bitmap8bit);
|
||||||
auto cameraInfo = (float*)partman::field_labeled(record_table, "camera_info", datFieldTypes::FloatArray);
|
auto cameraInfoId = partman::record_labeled(record_table, "camera_info") + fullscrn::GetResolution();
|
||||||
|
auto cameraInfo = (float*)partman::field(record_table, cameraInfoId, datFieldTypes::FloatArray);
|
||||||
|
|
||||||
|
/*Full tilt: table size depends on resolution*/
|
||||||
|
auto resInfo = &fullscrn::resolution_array[fullscrn::GetResolution()];
|
||||||
|
|
||||||
if (cameraInfo)
|
if (cameraInfo)
|
||||||
{
|
{
|
||||||
memcpy(&projMat, cameraInfo, sizeof(float) * 4 * 3);
|
memcpy(&projMat, cameraInfo, sizeof(float) * 4 * 3);
|
||||||
cameraInfo += 12;
|
cameraInfo += 12;
|
||||||
|
|
||||||
auto projCenterX = tableSize[0] * 0.5f;
|
auto projCenterX = resInfo->TableWidth * 0.5f;
|
||||||
auto projCenterY = tableSize[1] * 0.5f;
|
auto projCenterY = resInfo->TableHeight * 0.5f;
|
||||||
auto projD = cameraInfo[0];
|
auto projD = cameraInfo[0];
|
||||||
proj::init(projMat, projD, projCenterX, projCenterY);
|
proj::init(projMat, projD, projCenterX, projCenterY);
|
||||||
zMin = cameraInfo[1];
|
zMin = cameraInfo[1];
|
||||||
zScaler = cameraInfo[2];
|
zScaler = cameraInfo[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
render::init(nullptr, zMin, zScaler, tableSize[0], tableSize[1]);
|
render::init(nullptr, zMin, zScaler, resInfo->TableWidth, resInfo->TableHeight);
|
||||||
gdrv::copy_bitmap(
|
gdrv::copy_bitmap(
|
||||||
&render::vscreen,
|
&render::vscreen,
|
||||||
backgroundBmp->Width,
|
backgroundBmp->Width,
|
||||||
@@ -94,7 +100,7 @@ int pb::init()
|
|||||||
MainTable = new TPinballTable();
|
MainTable = new TPinballTable();
|
||||||
|
|
||||||
high_score::read(highscore_table, &state);
|
high_score::read(highscore_table, &state);
|
||||||
ball_speed_limit = static_cast<TBall*>(MainTable->BallList->Get(0))->Offset * 200.0f;
|
ball_speed_limit = MainTable->BallList->Get(0)->Offset * 200.0f;
|
||||||
--memory::critical_allocation;
|
--memory::critical_allocation;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -123,14 +129,18 @@ void pb::reset_table()
|
|||||||
|
|
||||||
void pb::firsttime_setup()
|
void pb::firsttime_setup()
|
||||||
{
|
{
|
||||||
render::blit = 0;
|
render::update(false);
|
||||||
render::update();
|
|
||||||
render::blit = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void pb::paint()
|
void pb::paint()
|
||||||
{
|
{
|
||||||
render::paint();
|
render::paint();
|
||||||
|
if (score::msg_fontp == nullptr)
|
||||||
|
{
|
||||||
|
// DrawText writes to screen directly, text gets overwritten by full vScreen blit.
|
||||||
|
pinball::InfoTextBox->Draw(true);
|
||||||
|
pinball::MissTextBox->Draw(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void pb::mode_change(int mode)
|
void pb::mode_change(int mode)
|
||||||
@@ -189,7 +199,7 @@ void pb::toggle_demo()
|
|||||||
MainTable->Message(1024, 0.0);
|
MainTable->Message(1024, 0.0);
|
||||||
mode_change(2);
|
mode_change(2);
|
||||||
pinball::MissTextBox->Clear();
|
pinball::MissTextBox->Clear();
|
||||||
auto text = pinball::get_rc_string(24, 0);
|
auto text = pinball::get_rc_Wstring(24, 0);
|
||||||
pinball::InfoTextBox->Display(text, -1.0);
|
pinball::InfoTextBox->Display(text, -1.0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -209,7 +219,7 @@ void pb::replay_level(int demoMode)
|
|||||||
|
|
||||||
void pb::ballset(int x, int y)
|
void pb::ballset(int x, int y)
|
||||||
{
|
{
|
||||||
TBall* ball = static_cast<TBall*>(MainTable->BallList->Get(0));
|
TBall* ball = MainTable->BallList->Get(0);
|
||||||
ball->Acceleration.X = x * 30.0f;
|
ball->Acceleration.X = x * 30.0f;
|
||||||
ball->Acceleration.Y = y * 30.0f;
|
ball->Acceleration.Y = y * 30.0f;
|
||||||
ball->Speed = maths::normalize_2d(&ball->Acceleration);
|
ball->Speed = maths::normalize_2d(&ball->Acceleration);
|
||||||
@@ -217,6 +227,8 @@ void pb::ballset(int x, int y)
|
|||||||
|
|
||||||
int pb::frame(int time)
|
int pb::frame(int time)
|
||||||
{
|
{
|
||||||
|
static int frameTime = 0;
|
||||||
|
|
||||||
if (time > 100)
|
if (time > 100)
|
||||||
time = 100;
|
time = 100;
|
||||||
float timeMul = time * 0.001f;
|
float timeMul = time * 0.001f;
|
||||||
@@ -233,20 +245,42 @@ int pb::frame(int time)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto nudgeDec = nudge::nudge_count - timeMul;
|
auto nudgeDec = nudge::nudge_count - timeMul;
|
||||||
if (nudgeDec <= 0.0)
|
if (nudgeDec <= 0.0f)
|
||||||
nudgeDec = 0.0;
|
nudgeDec = 0.0;
|
||||||
nudge::nudge_count = nudgeDec;
|
nudge::nudge_count = nudgeDec;
|
||||||
}
|
}
|
||||||
timer::check();
|
timer::check();
|
||||||
render::update();
|
|
||||||
|
if (!options::Options.AlternativeRender)
|
||||||
|
{
|
||||||
|
render::update(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Screen update at UPS > screen refresh rate cause tearing.
|
||||||
|
// Especially noticeable on fast moving ball in scaled up window.
|
||||||
|
// Retained render prevents frame skip. The next best thing - complete refresh at fixed rate.
|
||||||
|
render::update(false);
|
||||||
|
|
||||||
|
// Frame time at 60 FPS = 16.(6) ms = (16 + 17 + 17) / 3
|
||||||
|
auto targetTime = frameCounter % 3 == 0 ? 16 : 17;
|
||||||
|
frameTime += time;
|
||||||
|
if (frameTime >= targetTime)
|
||||||
|
{
|
||||||
|
frameTime = min(frameTime - targetTime, 100);
|
||||||
|
render::shift(0, 0, 0, 0, MainTable->Width, MainTable->Height);
|
||||||
|
frameCounter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
score::update(MainTable->CurScoreStruct);
|
score::update(MainTable->CurScoreStruct);
|
||||||
if (!MainTable->TiltLockFlag)
|
if (!MainTable->TiltLockFlag)
|
||||||
{
|
{
|
||||||
if (nudge::nudge_count > 0.5)
|
if (nudge::nudge_count > 0.5f)
|
||||||
{
|
{
|
||||||
pinball::InfoTextBox->Display(pinball::get_rc_string(25, 0), 2.0);
|
pinball::InfoTextBox->Display(pinball::get_rc_Wstring(25, 0), 2.0);
|
||||||
}
|
}
|
||||||
if (nudge::nudge_count > 1.0)
|
if (nudge::nudge_count > 1.0f)
|
||||||
MainTable->tilt(time_now);
|
MainTable->tilt(time_now);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -257,9 +291,9 @@ void pb::timed_frame(float timeNow, float timeDelta, bool drawBalls)
|
|||||||
{
|
{
|
||||||
vector_type vec1{}, vec2{};
|
vector_type vec1{}, vec2{};
|
||||||
|
|
||||||
for (int i = 0; i < MainTable->BallList->Count(); i++)
|
for (int i = 0; i < MainTable->BallList->GetCount(); i++)
|
||||||
{
|
{
|
||||||
auto ball = static_cast<TBall*>(MainTable->BallList->Get(i));
|
auto ball = MainTable->BallList->Get(i);
|
||||||
if (ball->ActiveFlag != 0)
|
if (ball->ActiveFlag != 0)
|
||||||
{
|
{
|
||||||
auto collComp = ball->CollisionComp;
|
auto collComp = ball->CollisionComp;
|
||||||
@@ -282,13 +316,13 @@ void pb::timed_frame(float timeNow, float timeDelta, bool drawBalls)
|
|||||||
ball->Acceleration.Y = ball->Speed * ball->Acceleration.Y;
|
ball->Acceleration.Y = ball->Speed * ball->Acceleration.Y;
|
||||||
maths::vector_add(&ball->Acceleration, &vec2);
|
maths::vector_add(&ball->Acceleration, &vec2);
|
||||||
ball->Speed = maths::normalize_2d(&ball->Acceleration);
|
ball->Speed = maths::normalize_2d(&ball->Acceleration);
|
||||||
ball->InvAcceleration.X = ball->Acceleration.X == 0.0 ? 1000000000.0f : 1.0f / ball->Acceleration.X;
|
ball->InvAcceleration.X = ball->Acceleration.X == 0.0f ? 1.0e9f : 1.0f / ball->Acceleration.X;
|
||||||
ball->InvAcceleration.Y = ball->Acceleration.Y == 0.0 ? 1000000000.0f : 1.0f / ball->Acceleration.Y;
|
ball->InvAcceleration.Y = ball->Acceleration.Y == 0.0f ? 1.0e9f : 1.0f / ball->Acceleration.Y;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto timeDelta2 = timeDelta;
|
auto timeDelta2 = timeDelta;
|
||||||
auto timeNow2 = timeNow;
|
auto timeNow2 = timeNow;
|
||||||
for (auto index = 10; timeDelta2 > 0.000001 && index; --index)
|
for (auto index = 10; timeDelta2 > 0.000001f && index; --index)
|
||||||
{
|
{
|
||||||
auto time = collide(timeNow2, timeDelta2, ball);
|
auto time = collide(timeNow2, timeDelta2, ball);
|
||||||
timeDelta2 -= time;
|
timeDelta2 -= time;
|
||||||
@@ -300,9 +334,9 @@ void pb::timed_frame(float timeNow, float timeDelta, bool drawBalls)
|
|||||||
|
|
||||||
if (drawBalls)
|
if (drawBalls)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < MainTable->BallList->Count(); i++)
|
for (int i = 0; i < MainTable->BallList->GetCount(); i++)
|
||||||
{
|
{
|
||||||
auto ball = static_cast<TBall*>(MainTable->BallList->Get(i));
|
auto ball = MainTable->BallList->Get(i);
|
||||||
if (ball->ActiveFlag)
|
if (ball->ActiveFlag)
|
||||||
ball->Repaint();
|
ball->Repaint();
|
||||||
}
|
}
|
||||||
@@ -311,8 +345,8 @@ void pb::timed_frame(float timeNow, float timeDelta, bool drawBalls)
|
|||||||
|
|
||||||
void pb::window_size(int* width, int* height)
|
void pb::window_size(int* width, int* height)
|
||||||
{
|
{
|
||||||
*width = 600;
|
*width = fullscrn::resolution_array[fullscrn::GetResolution()].TableWidth;
|
||||||
*height = 416;
|
*height = fullscrn::resolution_array[fullscrn::GetResolution()].TableHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pb::pause_continue()
|
void pb::pause_continue()
|
||||||
@@ -324,7 +358,7 @@ void pb::pause_continue()
|
|||||||
{
|
{
|
||||||
if (MainTable)
|
if (MainTable)
|
||||||
MainTable->Message(1008, time_now);
|
MainTable->Message(1008, time_now);
|
||||||
pinball::InfoTextBox->Display(pinball::get_rc_string(22, 0), -1.0);
|
pinball::InfoTextBox->Display(pinball::get_rc_Wstring(22, 0), -1.0);
|
||||||
midi::music_stop();
|
midi::music_stop();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -333,17 +367,17 @@ void pb::pause_continue()
|
|||||||
MainTable->Message(1009, 0.0);
|
MainTable->Message(1009, 0.0);
|
||||||
if (!demo_mode)
|
if (!demo_mode)
|
||||||
{
|
{
|
||||||
char* text;
|
wchar_t* text;
|
||||||
float textTime;
|
float textTime;
|
||||||
if (game_mode == 2)
|
if (game_mode == 2)
|
||||||
{
|
{
|
||||||
textTime = -1.0;
|
textTime = -1.0;
|
||||||
text = pinball::get_rc_string(24, 0);
|
text = pinball::get_rc_Wstring(24, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
textTime = 5.0;
|
textTime = 5.0;
|
||||||
text = pinball::get_rc_string(23, 0);
|
text = pinball::get_rc_Wstring(23, 0);
|
||||||
}
|
}
|
||||||
pinball::InfoTextBox->Display(text, textTime);
|
pinball::InfoTextBox->Display(text, textTime);
|
||||||
}
|
}
|
||||||
@@ -398,7 +432,7 @@ void pb::keydown(int key)
|
|||||||
mode_countdown(-1);
|
mode_countdown(-1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
control::pbctrl_bdoor_controller(key);
|
control::pbctrl_bdoor_controller(static_cast<char>(key));
|
||||||
if (key == options::Options.LeftFlipperKey)
|
if (key == options::Options.LeftFlipperKey)
|
||||||
{
|
{
|
||||||
MainTable->Message(1000, time_now);
|
MainTable->Message(1000, time_now);
|
||||||
@@ -440,7 +474,7 @@ void pb::keydown(int key)
|
|||||||
{
|
{
|
||||||
case 'B':
|
case 'B':
|
||||||
TBall* ball;
|
TBall* ball;
|
||||||
if (MainTable->BallList->Count() <= 0)
|
if (MainTable->BallList->GetCount() <= 0)
|
||||||
{
|
{
|
||||||
ball = new TBall(MainTable);
|
ball = new TBall(MainTable);
|
||||||
}
|
}
|
||||||
@@ -448,11 +482,11 @@ void pb::keydown(int key)
|
|||||||
{
|
{
|
||||||
for (auto index = 0; ;)
|
for (auto index = 0; ;)
|
||||||
{
|
{
|
||||||
ball = static_cast<TBall*>(MainTable->BallList->Get(index));
|
ball = MainTable->BallList->Get(index);
|
||||||
if (!ball->ActiveFlag)
|
if (!ball->ActiveFlag)
|
||||||
break;
|
break;
|
||||||
++index;
|
++index;
|
||||||
if (index >= MainTable->BallList->Count())
|
if (index >= MainTable->BallList->GetCount())
|
||||||
{
|
{
|
||||||
ball = new TBall(MainTable);
|
ball = new TBall(MainTable);
|
||||||
break;
|
break;
|
||||||
@@ -468,13 +502,13 @@ void pb::keydown(int key)
|
|||||||
ball->Acceleration.X = 0.0;
|
ball->Acceleration.X = 0.0;
|
||||||
break;
|
break;
|
||||||
case 'H':
|
case 'H':
|
||||||
char String1[200];
|
wchar_t String1[200];
|
||||||
lstrcpyA(String1, pinball::get_rc_string(26, 0));
|
lstrcpyW(String1, pinball::get_rc_Wstring(26, 0));
|
||||||
high_score::show_and_set_high_score_dialog(highscore_table, 1000000000, 1, String1);
|
high_score::show_and_set_high_score_dialog(highscore_table, 1000000000, 1, String1);
|
||||||
break;
|
break;
|
||||||
case 'M':
|
case 'M':
|
||||||
char buffer[20];
|
char buffer[20];
|
||||||
sprintf_s(buffer, "%ld", memory::use_total);
|
sprintf_s(buffer, "%zu", memory::use_total);
|
||||||
MessageBoxA(winmain::hwnd_frame, buffer, "Mem:", 0x2000u);
|
MessageBoxA(winmain::hwnd_frame, buffer, "Mem:", 0x2000u);
|
||||||
break;
|
break;
|
||||||
case 'R':
|
case 'R':
|
||||||
@@ -522,7 +556,7 @@ void pb::end_game()
|
|||||||
{
|
{
|
||||||
int scores[4]{};
|
int scores[4]{};
|
||||||
int scoreIndex[4]{};
|
int scoreIndex[4]{};
|
||||||
char String1[200];
|
wchar_t String1[200];
|
||||||
|
|
||||||
mode_change(2);
|
mode_change(2);
|
||||||
int playerCount = MainTable->PlayerCount;
|
int playerCount = MainTable->PlayerCount;
|
||||||
@@ -545,7 +579,7 @@ void pb::end_game()
|
|||||||
scores[j] = scores[i];
|
scores[j] = scores[i];
|
||||||
scores[i] = score;
|
scores[i] = score;
|
||||||
|
|
||||||
int index = scoreIndex[j];
|
int index = scoreIndex[j];
|
||||||
scoreIndex[j] = scoreIndex[i];
|
scoreIndex[j] = scoreIndex[i];
|
||||||
scoreIndex[i] = index;
|
scoreIndex[i] = index;
|
||||||
}
|
}
|
||||||
@@ -559,7 +593,7 @@ void pb::end_game()
|
|||||||
int position = high_score::get_score_position(highscore_table, scores[i]);
|
int position = high_score::get_score_position(highscore_table, scores[i]);
|
||||||
if (position >= 0)
|
if (position >= 0)
|
||||||
{
|
{
|
||||||
lstrcpyA(String1, pinball::get_rc_string(scoreIndex[i] + 26, 0));
|
lstrcpyW(String1, pinball::get_rc_Wstring(scoreIndex[i] + 26, 0));
|
||||||
high_score::show_and_set_high_score_dialog(highscore_table, scores[i], position, String1);
|
high_score::show_and_set_high_score_dialog(highscore_table, scores[i], position, String1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -626,7 +660,7 @@ float pb::collide(float timeNow, float timeDelta, TBall* ball)
|
|||||||
TEdgeSegment* edge = nullptr;
|
TEdgeSegment* edge = nullptr;
|
||||||
auto distance = TTableLayer::edge_manager->FindCollisionDistance(&ray, ball, &edge);
|
auto distance = TTableLayer::edge_manager->FindCollisionDistance(&ray, ball, &edge);
|
||||||
ball->EdgeCollisionCount = 0;
|
ball->EdgeCollisionCount = 0;
|
||||||
if (distance >= 1000000000.0)
|
if (distance >= 1000000000.0f)
|
||||||
{
|
{
|
||||||
maxDistance = timeDelta * ball->Speed;
|
maxDistance = timeDelta * ball->Speed;
|
||||||
ball->RayMaxDistance = maxDistance;
|
ball->RayMaxDistance = maxDistance;
|
||||||
@@ -638,7 +672,7 @@ float pb::collide(float timeNow, float timeDelta, TBall* ball)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
edge->EdgeCollision(ball, distance);
|
edge->EdgeCollision(ball, distance);
|
||||||
if (ball->Speed > 0.000000001)
|
if (ball->Speed > 0.000000001f)
|
||||||
return fabs(distance / ball->Speed);
|
return fabs(distance / ball->Speed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,10 +10,12 @@ class pb
|
|||||||
public:
|
public:
|
||||||
static int time_ticks;
|
static int time_ticks;
|
||||||
static float ball_speed_limit, time_now, time_next;
|
static float ball_speed_limit, time_now, time_next;
|
||||||
static int cheat_mode, game_mode;
|
static int game_mode, frameCounter;
|
||||||
|
static bool cheat_mode;
|
||||||
static datFileStruct* record_table;
|
static datFileStruct* record_table;
|
||||||
static TPinballTable* MainTable;
|
static TPinballTable* MainTable;
|
||||||
static high_score_struct highscore_table[5];
|
static high_score_struct highscore_table[5];
|
||||||
|
static bool FullTiltMode;
|
||||||
|
|
||||||
static int init();
|
static int init();
|
||||||
static int uninit();
|
static int uninit();
|
||||||
@@ -38,7 +40,7 @@ public:
|
|||||||
static void tilt_no_more();
|
static void tilt_no_more();
|
||||||
static bool chk_highscore();
|
static bool chk_highscore();
|
||||||
static float collide(float timeNow, float timeDelta, TBall* ball);
|
static float collide(float timeNow, float timeDelta, TBall* ball);
|
||||||
private :
|
private:
|
||||||
static int demo_mode, mode_countdown_;
|
static int demo_mode, mode_countdown_;
|
||||||
static int state;
|
static int state;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <CommCtrl.h>
|
#include <CommCtrl.h>
|
||||||
#include <htmlhelp.h>
|
#include <htmlhelp.h>
|
||||||
|
#include <cstdint>
|
||||||
#include <type_traits> /*For control template*/
|
#include <type_traits> /*For control template*/
|
||||||
//#include <cstdlib>
|
//#include <cstdlib>
|
||||||
|
|
||||||
@@ -25,4 +26,13 @@
|
|||||||
/*Sound uses PlaySound*/
|
/*Sound uses PlaySound*/
|
||||||
#undef PlaySound
|
#undef PlaySound
|
||||||
|
|
||||||
|
|
||||||
|
inline size_t pgm_save(int width, int height, char* data, FILE* outfile)
|
||||||
|
{
|
||||||
|
size_t n = 0;
|
||||||
|
n += fprintf(outfile, "P5\n%d %d\n%d\n", width, height, 0xFF);
|
||||||
|
n += fwrite(data, 1, width * height, outfile);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
#endif //PCH_H
|
#endif //PCH_H
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ int pinball::quickFlag = 0;
|
|||||||
TTextBox* pinball::InfoTextBox;
|
TTextBox* pinball::InfoTextBox;
|
||||||
TTextBox* pinball::MissTextBox;
|
TTextBox* pinball::MissTextBox;
|
||||||
char pinball::getRcBuffer[6 * 256];
|
char pinball::getRcBuffer[6 * 256];
|
||||||
int pinball::rc_string_slot = 0;
|
wchar_t pinball::getRcWBuffer[256 * 6];
|
||||||
char pinball::WindowName[2]{};
|
int pinball::rc_string_slot = 0, pinball::rc_Wstring_slot = 0;
|
||||||
int pinball::LeftShift = -1;
|
int pinball::LeftShift = -1;
|
||||||
int pinball::RightShift = -1;
|
int pinball::RightShift = -1;
|
||||||
|
|
||||||
@@ -23,6 +23,16 @@ char* pinball::get_rc_string(int uID, int a2)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wchar_t* pinball::get_rc_Wstring(int uID, int a2)
|
||||||
|
{
|
||||||
|
auto result = &getRcWBuffer[256 * rc_Wstring_slot];
|
||||||
|
if (!LoadStringW(winmain::hinst, uID, result, 255))
|
||||||
|
*result = 0;
|
||||||
|
if (++rc_Wstring_slot >= 6)
|
||||||
|
rc_Wstring_slot = 0;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
int pinball::get_rc_int(int uID, int* dst)
|
int pinball::get_rc_int(int uID, int* dst)
|
||||||
{
|
{
|
||||||
char buffer[255];
|
char buffer[255];
|
||||||
|
|||||||
@@ -13,16 +13,17 @@ public:
|
|||||||
static int quickFlag;
|
static int quickFlag;
|
||||||
static TTextBox* InfoTextBox;
|
static TTextBox* InfoTextBox;
|
||||||
static TTextBox* MissTextBox;
|
static TTextBox* MissTextBox;
|
||||||
static char WindowName[2];
|
|
||||||
static int RightShift;
|
static int RightShift;
|
||||||
static int LeftShift;
|
static int LeftShift;
|
||||||
|
|
||||||
static char* get_rc_string(int uID, int a2);
|
static char* get_rc_string(int uID, int a2);
|
||||||
|
static wchar_t* get_rc_Wstring(int uID, int a2);
|
||||||
static int get_rc_int(int uID, int* dst);
|
static int get_rc_int(int uID, int* dst);
|
||||||
static void FindShiftKeys();
|
static void FindShiftKeys();
|
||||||
static void adjust_priority(int priority);
|
static void adjust_priority(int priority);
|
||||||
static int make_path_name(LPSTR lpFilename, LPCSTR lpString2, int nSize = 0x12Cu);
|
static int make_path_name(LPSTR lpFilename, LPCSTR lpString2, int nSize = 0x12Cu);
|
||||||
private:
|
private:
|
||||||
static char getRcBuffer[256 * 6];
|
static char getRcBuffer[256 * 6];
|
||||||
static int rc_string_slot;
|
static wchar_t getRcWBuffer[256 * 6];
|
||||||
|
static int rc_string_slot, rc_Wstring_slot;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ void proj::xform_to_2d(vector_type* vec, int* dst)
|
|||||||
vector_type dstVec2{};
|
vector_type dstVec2{};
|
||||||
|
|
||||||
matrix_vector_multiply(&matrix, vec, &dstVec2);
|
matrix_vector_multiply(&matrix, vec, &dstVec2);
|
||||||
if (0.0 == dstVec2.Z)
|
if (dstVec2.Z == 0.0f)
|
||||||
projCoef = 999999.88f;
|
projCoef = 999999.88f;
|
||||||
else
|
else
|
||||||
projCoef = d_ / dstVec2.Z;
|
projCoef = d_ / dstVec2.Z;
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
#include "render.h"
|
#include "render.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
|
||||||
int render::blit = 0;
|
|
||||||
int render::many_dirty, render::many_sprites, render::many_balls;
|
int render::many_dirty, render::many_sprites, render::many_balls;
|
||||||
render_sprite_type_struct **render::dirty_list, **render::sprite_list, **render::ball_list;
|
render_sprite_type_struct **render::dirty_list, **render::sprite_list, **render::ball_list;
|
||||||
zmap_header_type* render::background_zmap;
|
zmap_header_type* render::background_zmap;
|
||||||
@@ -18,9 +17,9 @@ void render::init(gdrv_bitmap8* bmp, float zMin, float zScaler, int width, int h
|
|||||||
zscaler = zScaler;
|
zscaler = zScaler;
|
||||||
zmin = zMin;
|
zmin = zMin;
|
||||||
zmax = 4294967300.0f / zScaler + zMin;
|
zmax = 4294967300.0f / zScaler + zMin;
|
||||||
sprite_list = reinterpret_cast<render_sprite_type_struct**>(memory::allocate(1000 * sizeof(void*)));
|
sprite_list = memory::allocate<render_sprite_type_struct*>(1000);
|
||||||
dirty_list = reinterpret_cast<render_sprite_type_struct**>(memory::allocate(1000 * sizeof(void*)));
|
dirty_list = memory::allocate<render_sprite_type_struct*>(1000);
|
||||||
ball_list = reinterpret_cast<render_sprite_type_struct**>(memory::allocate(20 * sizeof(void*)));
|
ball_list = memory::allocate<render_sprite_type_struct*>(20);
|
||||||
gdrv::create_bitmap(&vscreen, width, height);
|
gdrv::create_bitmap(&vscreen, width, height);
|
||||||
zdrv::create_zmap(&zscreen, width, height);
|
zdrv::create_zmap(&zscreen, width, height);
|
||||||
zdrv::fill(&zscreen, zscreen.Width, zscreen.Height, 0, 0, 0xFFFF);
|
zdrv::fill(&zscreen, zscreen.Width, zscreen.Height, 0, 0, 0xFFFF);
|
||||||
@@ -48,9 +47,9 @@ void render::uninit()
|
|||||||
{
|
{
|
||||||
gdrv::destroy_bitmap(&vscreen);
|
gdrv::destroy_bitmap(&vscreen);
|
||||||
zdrv::destroy_zmap(&zscreen);
|
zdrv::destroy_zmap(&zscreen);
|
||||||
for (int i = 0; i < many_sprites; ++i)
|
for (auto i = many_sprites - 1; i >= 0; --i)
|
||||||
remove_sprite(sprite_list[i]);
|
remove_sprite(sprite_list[i]);
|
||||||
for (int j = 0; j < many_balls; ++j)
|
for (auto j = many_balls - 1; j >= 0; --j)
|
||||||
remove_ball(ball_list[j]);
|
remove_ball(ball_list[j]);
|
||||||
memory::free(ball_list);
|
memory::free(ball_list);
|
||||||
memory::free(dirty_list);
|
memory::free(dirty_list);
|
||||||
@@ -60,83 +59,69 @@ void render::uninit()
|
|||||||
many_balls = 0;
|
many_balls = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void render::update()
|
void render::update(bool blit)
|
||||||
{
|
{
|
||||||
rectangle_type overlapRect{};
|
rectangle_type overlapRect{};
|
||||||
|
|
||||||
auto dirtyPtr = dirty_list;
|
|
||||||
for (int index = 0; index < many_dirty; ++dirtyPtr, ++index)
|
|
||||||
{
|
|
||||||
auto curSprite = *dirtyPtr;
|
|
||||||
if ((*dirtyPtr)->VisualType != VisualType::None)
|
|
||||||
{
|
|
||||||
if ((*dirtyPtr)->VisualType == VisualType::Sprite)
|
|
||||||
{
|
|
||||||
if (curSprite->BmpRectCopy.Width > 0)
|
|
||||||
maths::enclosing_box(&curSprite->BmpRectCopy, &curSprite->BmpRect, &curSprite->DirtyRect);
|
|
||||||
|
|
||||||
if (!maths::rectangle_clip(&curSprite->DirtyRect, &vscreen_rect, &curSprite->DirtyRect))
|
|
||||||
{
|
|
||||||
curSprite->DirtyRect.Width = -1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto yPos = curSprite->DirtyRect.YPosition;
|
|
||||||
auto width = curSprite->DirtyRect.Width;
|
|
||||||
auto xPos = curSprite->DirtyRect.XPosition;
|
|
||||||
auto height = curSprite->DirtyRect.Height;
|
|
||||||
zdrv::fill(&zscreen, width, height, xPos, yPos, 0xFFFF);
|
|
||||||
if (background_bitmap)
|
|
||||||
gdrv::copy_bitmap(&vscreen, width, height, xPos, yPos, background_bitmap, xPos, yPos);
|
|
||||||
else
|
|
||||||
gdrv::fill_bitmap(&vscreen, width, height, xPos, yPos, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!maths::rectangle_clip(&curSprite->BmpRect, &vscreen_rect, &curSprite->DirtyRect))
|
|
||||||
{
|
|
||||||
curSprite->DirtyRect.Width = -1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!curSprite->Bmp)
|
|
||||||
{
|
|
||||||
auto yPos = curSprite->DirtyRect.YPosition;
|
|
||||||
auto width = curSprite->DirtyRect.Width;
|
|
||||||
auto xPos = curSprite->DirtyRect.XPosition;
|
|
||||||
auto height = curSprite->DirtyRect.Height;
|
|
||||||
zdrv::fill(&zscreen, width, height, xPos, yPos, 0xFFFF);
|
|
||||||
if (background_bitmap)
|
|
||||||
gdrv::copy_bitmap(&vscreen, width, height, xPos, yPos, background_bitmap, xPos, yPos);
|
|
||||||
else
|
|
||||||
gdrv::fill_bitmap(&vscreen, width, height, xPos, yPos, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dirtyPtr = dirty_list;
|
|
||||||
for (int index = 0; index < many_dirty; ++index)
|
for (int index = 0; index < many_dirty; ++index)
|
||||||
{
|
{
|
||||||
auto sprite = *dirtyPtr;
|
auto curSprite = dirty_list[index];
|
||||||
if ((*dirtyPtr)->DirtyRect.Width > 0 && (sprite->VisualType == VisualType::None || sprite->VisualType ==
|
bool clearSprite = false;
|
||||||
VisualType::Sprite))
|
switch (curSprite->VisualType)
|
||||||
repaint(*dirtyPtr);
|
{
|
||||||
++dirtyPtr;
|
case VisualType::Sprite:
|
||||||
|
if (curSprite->BmpRectCopy.Width > 0)
|
||||||
|
maths::enclosing_box(&curSprite->BmpRectCopy, &curSprite->BmpRect, &curSprite->DirtyRect);
|
||||||
|
|
||||||
|
if (maths::rectangle_clip(&curSprite->DirtyRect, &vscreen_rect, &curSprite->DirtyRect))
|
||||||
|
clearSprite = true;
|
||||||
|
else
|
||||||
|
curSprite->DirtyRect.Width = -1;
|
||||||
|
break;
|
||||||
|
case VisualType::None:
|
||||||
|
if (maths::rectangle_clip(&curSprite->BmpRect, &vscreen_rect, &curSprite->DirtyRect))
|
||||||
|
clearSprite = !curSprite->Bmp;
|
||||||
|
else
|
||||||
|
curSprite->DirtyRect.Width = -1;
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clearSprite)
|
||||||
|
{
|
||||||
|
auto yPos = curSprite->DirtyRect.YPosition;
|
||||||
|
auto width = curSprite->DirtyRect.Width;
|
||||||
|
auto xPos = curSprite->DirtyRect.XPosition;
|
||||||
|
auto height = curSprite->DirtyRect.Height;
|
||||||
|
zdrv::fill(&zscreen, width, height, xPos, yPos, 0xFFFF);
|
||||||
|
if (background_bitmap)
|
||||||
|
gdrv::copy_bitmap(&vscreen, width, height, xPos, yPos, background_bitmap, xPos, yPos);
|
||||||
|
else
|
||||||
|
gdrv::fill_bitmap(&vscreen, width, height, xPos, yPos, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int index = 0; index < many_dirty; ++index)
|
||||||
|
{
|
||||||
|
auto sprite = dirty_list[index];
|
||||||
|
if (sprite->DirtyRect.Width > 0 && (sprite->VisualType == VisualType::None || sprite->VisualType ==
|
||||||
|
VisualType::Sprite))
|
||||||
|
repaint(sprite);
|
||||||
}
|
}
|
||||||
|
|
||||||
paint_balls();
|
|
||||||
if (blit)
|
if (blit)
|
||||||
{
|
{
|
||||||
|
paint_balls();
|
||||||
gdrv::start_blit_sequence();
|
gdrv::start_blit_sequence();
|
||||||
|
|
||||||
auto xPos = vscreen.XPosition + offset_x;
|
auto xPos = vscreen.XPosition + offset_x;
|
||||||
auto yPos = vscreen.YPosition + offset_y;
|
auto yPos = vscreen.YPosition + offset_y;
|
||||||
dirtyPtr = dirty_list;
|
|
||||||
for (int index = 0; index < many_dirty; ++dirtyPtr, ++index)
|
for (int index = 0; index < many_dirty; ++index)
|
||||||
{
|
{
|
||||||
auto sprite = *dirtyPtr;
|
auto sprite = dirty_list[index];
|
||||||
auto dirtyRect = &(*dirtyPtr)->DirtyRect;
|
auto dirtyRect = &sprite->DirtyRect;
|
||||||
auto width2 = (*dirtyPtr)->DirtyRect.Width;
|
auto width2 = sprite->DirtyRect.Width;
|
||||||
if (width2 > 0)
|
if (width2 > 0)
|
||||||
gdrv::blit_sequence(
|
gdrv::blit_sequence(
|
||||||
&vscreen,
|
&vscreen,
|
||||||
@@ -147,21 +132,16 @@ void render::update()
|
|||||||
width2,
|
width2,
|
||||||
dirtyRect->Height);
|
dirtyRect->Height);
|
||||||
|
|
||||||
auto rect = &sprite->BmpRectCopy;
|
sprite->BmpRectCopy = *dirtyRect;
|
||||||
rect->XPosition = dirtyRect->XPosition;
|
|
||||||
rect->YPosition = dirtyRect->YPosition;
|
|
||||||
rect->Width = dirtyRect->Width;
|
|
||||||
rect->Height = dirtyRect->Height;
|
|
||||||
|
|
||||||
if (sprite->UnknownFlag != 0)
|
if (sprite->UnknownFlag != 0)
|
||||||
remove_sprite(sprite);
|
remove_sprite(sprite);
|
||||||
}
|
}
|
||||||
|
|
||||||
dirtyPtr = ball_list;
|
for (int index = 0; index < many_balls; ++index)
|
||||||
for (int index = 0; index < many_balls; ++dirtyPtr, ++index)
|
|
||||||
{
|
{
|
||||||
auto rectCopy = &(*dirtyPtr)->BmpRectCopy;
|
auto sprite = ball_list[index];
|
||||||
auto dirtyRect = &(*dirtyPtr)->DirtyRect;
|
auto rectCopy = &sprite->BmpRectCopy;
|
||||||
|
auto dirtyRect = &sprite->DirtyRect;
|
||||||
if (maths::overlapping_box(dirtyRect, rectCopy, &overlapRect) && dirtyRect->Width > 0)
|
if (maths::overlapping_box(dirtyRect, rectCopy, &overlapRect) && dirtyRect->Width > 0)
|
||||||
{
|
{
|
||||||
if (overlapRect.Width > 0)
|
if (overlapRect.Width > 0)
|
||||||
@@ -198,13 +178,22 @@ void render::update()
|
|||||||
}
|
}
|
||||||
|
|
||||||
gdrv::end_blit_sequence();
|
gdrv::end_blit_sequence();
|
||||||
|
unpaint_balls();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int index = 0; index < many_dirty; ++index)
|
||||||
|
{
|
||||||
|
auto sprite = dirty_list[index];
|
||||||
|
sprite->BmpRectCopy = sprite->DirtyRect;
|
||||||
|
if (sprite->UnknownFlag != 0)
|
||||||
|
remove_sprite(sprite);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
many_dirty = 0;
|
many_dirty = 0;
|
||||||
unpaint_balls();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void render::paint()
|
void render::paint()
|
||||||
{
|
{
|
||||||
paint_balls();
|
paint_balls();
|
||||||
@@ -221,7 +210,7 @@ void render::sprite_modified(render_sprite_type_struct* sprite)
|
|||||||
render_sprite_type_struct* render::create_sprite(VisualType visualType, gdrv_bitmap8* bmp, zmap_header_type* zMap,
|
render_sprite_type_struct* render::create_sprite(VisualType visualType, gdrv_bitmap8* bmp, zmap_header_type* zMap,
|
||||||
int xPosition, int yPosition, rectangle_type* rect)
|
int xPosition, int yPosition, rectangle_type* rect)
|
||||||
{
|
{
|
||||||
auto sprite = (render_sprite_type_struct*)memory::allocate(sizeof(render_sprite_type_struct));
|
auto sprite = memory::allocate<render_sprite_type_struct>();
|
||||||
if (!sprite)
|
if (!sprite)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
sprite->BmpRect.YPosition = yPosition;
|
sprite->BmpRect.YPosition = yPosition;
|
||||||
@@ -278,7 +267,6 @@ render_sprite_type_struct* render::create_sprite(VisualType visualType, gdrv_bit
|
|||||||
|
|
||||||
void render::remove_sprite(render_sprite_type_struct* sprite)
|
void render::remove_sprite(render_sprite_type_struct* sprite)
|
||||||
{
|
{
|
||||||
int spriteCount = many_sprites;
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
if (many_sprites > 0)
|
if (many_sprites > 0)
|
||||||
{
|
{
|
||||||
@@ -287,13 +275,12 @@ void render::remove_sprite(render_sprite_type_struct* sprite)
|
|||||||
if (++index >= many_sprites)
|
if (++index >= many_sprites)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
while (index < spriteCount)
|
while (index < many_sprites)
|
||||||
{
|
{
|
||||||
sprite_list[index] = sprite_list[index + 1];
|
sprite_list[index] = sprite_list[index + 1];
|
||||||
spriteCount = many_sprites;
|
|
||||||
++index;
|
++index;
|
||||||
}
|
}
|
||||||
many_sprites = spriteCount - 1;
|
many_sprites--;
|
||||||
if (sprite->SpriteArray)
|
if (sprite->SpriteArray)
|
||||||
memory::free(sprite->SpriteArray);
|
memory::free(sprite->SpriteArray);
|
||||||
memory::free(sprite);
|
memory::free(sprite);
|
||||||
@@ -302,7 +289,6 @@ void render::remove_sprite(render_sprite_type_struct* sprite)
|
|||||||
|
|
||||||
void render::remove_ball(struct render_sprite_type_struct* ball)
|
void render::remove_ball(struct render_sprite_type_struct* ball)
|
||||||
{
|
{
|
||||||
int ballCount = many_balls;
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
if (many_balls > 0)
|
if (many_balls > 0)
|
||||||
{
|
{
|
||||||
@@ -311,13 +297,12 @@ void render::remove_ball(struct render_sprite_type_struct* ball)
|
|||||||
if (++index >= many_balls)
|
if (++index >= many_balls)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
while (index < ballCount)
|
while (index < many_balls)
|
||||||
{
|
{
|
||||||
ball_list[index] = ball_list[index + 1];
|
ball_list[index] = ball_list[index + 1];
|
||||||
ballCount = many_balls;
|
|
||||||
++index;
|
++index;
|
||||||
}
|
}
|
||||||
many_balls = ballCount - 1;
|
many_balls--;
|
||||||
memory::free(ball);
|
memory::free(ball);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -477,35 +462,21 @@ void render::paint_balls()
|
|||||||
|
|
||||||
void render::unpaint_balls()
|
void render::unpaint_balls()
|
||||||
{
|
{
|
||||||
auto ballPtr = &ball_list[many_balls - 1];
|
for (int index = many_balls - 1; index >= 0; index--)
|
||||||
if (many_balls - 1 >= 0)
|
|
||||||
{
|
{
|
||||||
gdrv_bitmap8* bitmapPtr = &ball_bitmap[many_balls - 1];
|
auto curBall = ball_list[index];
|
||||||
for (int index = many_balls; index > 0; index--)
|
if (curBall->DirtyRect.Width > 0)
|
||||||
{
|
gdrv::copy_bitmap(
|
||||||
struct render_sprite_type_struct* curBall = *ballPtr;
|
&vscreen,
|
||||||
rectangle_type* rect2 = &(*ballPtr)->DirtyRect;
|
curBall->DirtyRect.Width,
|
||||||
int width = (*ballPtr)->DirtyRect.Width;
|
curBall->DirtyRect.Height,
|
||||||
if (width > 0)
|
curBall->DirtyRect.XPosition,
|
||||||
gdrv::copy_bitmap(
|
curBall->DirtyRect.YPosition,
|
||||||
&vscreen,
|
&ball_bitmap[index],
|
||||||
width,
|
0,
|
||||||
(*ballPtr)->DirtyRect.Height,
|
0);
|
||||||
(*ballPtr)->DirtyRect.XPosition,
|
|
||||||
(*ballPtr)->DirtyRect.YPosition,
|
|
||||||
bitmapPtr,
|
|
||||||
0,
|
|
||||||
0);
|
|
||||||
|
|
||||||
rectangle_type* rectCopy = &curBall->BmpRectCopy;
|
curBall->BmpRectCopy = curBall->DirtyRect;
|
||||||
rectCopy->XPosition = rect2->XPosition;
|
|
||||||
rectCopy->YPosition = rect2->YPosition;
|
|
||||||
rectCopy->Width = rect2->Width;
|
|
||||||
rectCopy->Height = rect2->Height;
|
|
||||||
|
|
||||||
--ballPtr;
|
|
||||||
--bitmapPtr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -542,7 +513,7 @@ void render::build_occlude_list()
|
|||||||
if (!curSprite->UnknownFlag && curSprite->BoundingRect.Width != -1)
|
if (!curSprite->UnknownFlag && curSprite->BoundingRect.Width != -1)
|
||||||
{
|
{
|
||||||
if (!spriteArr)
|
if (!spriteArr)
|
||||||
spriteArr = reinterpret_cast<render_sprite_type_struct**>(memory::allocate(1000 * sizeof(void*)));
|
spriteArr = memory::allocate<render_sprite_type_struct*>(1000);
|
||||||
int occludeCount = 0;
|
int occludeCount = 0;
|
||||||
auto spritePtr2 = sprite_list;
|
auto spritePtr2 = sprite_list;
|
||||||
for (int i = 0; i < many_sprites; ++i, ++spritePtr2)
|
for (int i = 0; i < many_sprites; ++i, ++spritePtr2)
|
||||||
@@ -560,8 +531,7 @@ void render::build_occlude_list()
|
|||||||
occludeCount = 0;
|
occludeCount = 0;
|
||||||
if (occludeCount)
|
if (occludeCount)
|
||||||
{
|
{
|
||||||
curSprite->SpriteArray = reinterpret_cast<render_sprite_type_struct**>(memory::realloc(
|
curSprite->SpriteArray = memory::realloc(spriteArr, sizeof(void*) * occludeCount);
|
||||||
spriteArr, sizeof(void*) * occludeCount));
|
|
||||||
curSprite->SpriteCount = occludeCount;
|
curSprite->SpriteCount = occludeCount;
|
||||||
spriteArr = nullptr;
|
spriteArr = nullptr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ struct render_sprite_type_struct
|
|||||||
zmap_header_type* ZMap;
|
zmap_header_type* ZMap;
|
||||||
char UnknownFlag;
|
char UnknownFlag;
|
||||||
VisualType VisualType;
|
VisualType VisualType;
|
||||||
__int16 Depth;
|
int16_t Depth;
|
||||||
rectangle_type BmpRectCopy;
|
rectangle_type BmpRectCopy;
|
||||||
int ZMapOffestY;
|
int ZMapOffestY;
|
||||||
int ZMapOffestX;
|
int ZMapOffestX;
|
||||||
@@ -31,7 +31,6 @@ struct render_sprite_type_struct
|
|||||||
class render
|
class render
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static int blit;
|
|
||||||
static int many_dirty, many_sprites, many_balls;
|
static int many_dirty, many_sprites, many_balls;
|
||||||
static render_sprite_type_struct **dirty_list, **sprite_list, **ball_list;
|
static render_sprite_type_struct **dirty_list, **sprite_list, **ball_list;
|
||||||
static zmap_header_type* background_zmap;
|
static zmap_header_type* background_zmap;
|
||||||
@@ -43,7 +42,7 @@ public:
|
|||||||
|
|
||||||
static void init(gdrv_bitmap8* bmp, float zMin, float zScaler, int width, int height);
|
static void init(gdrv_bitmap8* bmp, float zMin, float zScaler, int width, int height);
|
||||||
static void uninit();
|
static void uninit();
|
||||||
static void update();
|
static void update(bool blit);
|
||||||
static void paint();
|
static void paint();
|
||||||
static void sprite_modified(render_sprite_type_struct* sprite);
|
static void sprite_modified(render_sprite_type_struct* sprite);
|
||||||
static render_sprite_type_struct* create_sprite(VisualType visualType, gdrv_bitmap8* bmp,
|
static render_sprite_type_struct* create_sprite(VisualType visualType, gdrv_bitmap8* bmp,
|
||||||
|
|||||||
@@ -224,25 +224,33 @@
|
|||||||
#define Menu1_2Players 409
|
#define Menu1_2Players 409
|
||||||
#define Menu1_3Players 410
|
#define Menu1_3Players 410
|
||||||
#define Menu1_4Players 411
|
#define Menu1_4Players 411
|
||||||
|
#define Menu1_MaximumResolution 500
|
||||||
#define DLG_HIGHSCORES_Score1 501
|
#define DLG_HIGHSCORES_Score1 501
|
||||||
#define KEYMAPPER_Default 501
|
#define KEYMAPPER_Default 501
|
||||||
|
#define Menu1_640x480 501
|
||||||
#define DLG_HIGHSCORES_Score2 502
|
#define DLG_HIGHSCORES_Score2 502
|
||||||
|
#define Menu1_800x600 502
|
||||||
#define DLG_HIGHSCORES_Score3 503
|
#define DLG_HIGHSCORES_Score3 503
|
||||||
|
#define Menu1_1024x768 503
|
||||||
#define DLG_HIGHSCORES_Score4 504
|
#define DLG_HIGHSCORES_Score4 504
|
||||||
#define DLG_HIGHSCORES_Score5 505
|
#define DLG_HIGHSCORES_Score5 505
|
||||||
|
#define Menu1_WindowUniformScale 600
|
||||||
#define DLG_HIGHSCORES_EditName1 601
|
#define DLG_HIGHSCORES_EditName1 601
|
||||||
#define DLG_HIGHSCORES_EditName2 602
|
#define DLG_HIGHSCORES_EditName2 602
|
||||||
#define DLG_HIGHSCORES_EditName3 603
|
#define DLG_HIGHSCORES_EditName3 603
|
||||||
#define DLG_HIGHSCORES_EditName4 604
|
#define DLG_HIGHSCORES_EditName4 604
|
||||||
#define DLG_HIGHSCORES_EditName5 605
|
#define DLG_HIGHSCORES_EditName5 605
|
||||||
|
#define Menu1_AlternativeRender 601
|
||||||
|
#define Menu1_Language 700
|
||||||
|
#define Menu1_LanguageMax 724
|
||||||
|
|
||||||
// Next default values for new objects
|
// Next default values for new objects
|
||||||
//
|
//
|
||||||
#ifdef APSTUDIO_INVOKED
|
#ifdef APSTUDIO_INVOKED
|
||||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||||
#define _APS_NEXT_RESOURCE_VALUE 204
|
#define _APS_NEXT_RESOURCE_VALUE 204
|
||||||
#define _APS_NEXT_COMMAND_VALUE 40004
|
#define _APS_NEXT_COMMAND_VALUE 40006
|
||||||
#define _APS_NEXT_CONTROL_VALUE 1001
|
#define _APS_NEXT_CONTROL_VALUE 1001
|
||||||
#define _APS_NEXT_SYMED_VALUE 102
|
#define _APS_NEXT_SYMED_VALUE 104
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
#include "score.h"
|
#include "score.h"
|
||||||
|
|
||||||
|
#include "fullscrn.h"
|
||||||
#include "loader.h"
|
#include "loader.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "partman.h"
|
#include "partman.h"
|
||||||
|
#include "pb.h"
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
#include "TDrain.h"
|
#include "TDrain.h"
|
||||||
#include "winmain.h"
|
#include "winmain.h"
|
||||||
@@ -16,23 +19,26 @@ int score::init()
|
|||||||
|
|
||||||
scoreStruct* score::create(LPCSTR fieldName, gdrv_bitmap8* renderBgBmp)
|
scoreStruct* score::create(LPCSTR fieldName, gdrv_bitmap8* renderBgBmp)
|
||||||
{
|
{
|
||||||
auto score = reinterpret_cast<scoreStruct*>(memory::allocate(sizeof(scoreStruct)));
|
auto score = memory::allocate<scoreStruct>();
|
||||||
if (!score)
|
if (!score)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
score->Score = -9999;
|
score->Score = -9999;
|
||||||
score->BackgroundBmp = renderBgBmp;
|
score->BackgroundBmp = renderBgBmp;
|
||||||
auto shortArr = reinterpret_cast<__int16*>(partman::field_labeled(loader::loader_table, fieldName,
|
|
||||||
datFieldTypes::ShortArray));
|
/*Full tilt: score box dimensions index is offset by resolution*/
|
||||||
if (!shortArr)
|
auto dimensionsId = partman::record_labeled(pb::record_table, fieldName) + fullscrn::GetResolution();
|
||||||
|
auto dimensions = reinterpret_cast<int16_t*>(partman::field(loader::loader_table, dimensionsId,
|
||||||
|
datFieldTypes::ShortArray));
|
||||||
|
if (!dimensions)
|
||||||
{
|
{
|
||||||
memory::free(score);
|
memory::free(score);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
int groupIndex = *shortArr++;
|
int groupIndex = *dimensions++;
|
||||||
score->OffsetX = *shortArr++;
|
score->OffsetX = *dimensions++;
|
||||||
score->OffsetY = *shortArr++;
|
score->OffsetY = *dimensions++;
|
||||||
score->Width = *shortArr++;
|
score->Width = *dimensions++;
|
||||||
score->Height = *shortArr;
|
score->Height = *dimensions;
|
||||||
|
|
||||||
for (int index = 0; index < 10; index++)
|
for (int index = 0; index < 10; index++)
|
||||||
{
|
{
|
||||||
@@ -45,13 +51,22 @@ scoreStruct* score::create(LPCSTR fieldName, gdrv_bitmap8* renderBgBmp)
|
|||||||
|
|
||||||
scoreStruct* score::dup(scoreStruct* score, int scoreIndex)
|
scoreStruct* score::dup(scoreStruct* score, int scoreIndex)
|
||||||
{
|
{
|
||||||
auto result = reinterpret_cast<scoreStruct*>(memory::allocate(sizeof(scoreStruct)));
|
auto result = memory::allocate<scoreStruct>();
|
||||||
if (result)
|
if (result)
|
||||||
memcpy(result, score, sizeof(scoreStruct));
|
memcpy(result, score, sizeof(scoreStruct));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void score::load_msg_font(LPCSTR lpName)
|
void score::load_msg_font(LPCSTR lpName)
|
||||||
|
{
|
||||||
|
/*3DPB stores font in resources, FT in dat. FT font has multiple resolutions*/
|
||||||
|
if (pb::FullTiltMode)
|
||||||
|
load_msg_font_FT(lpName);
|
||||||
|
else
|
||||||
|
load_msg_font_3DPB(lpName);
|
||||||
|
}
|
||||||
|
|
||||||
|
void score::load_msg_font_3DPB(LPCSTR lpName)
|
||||||
{
|
{
|
||||||
auto resHandle = FindResourceA(winmain::hinst, lpName, RT_RCDATA);
|
auto resHandle = FindResourceA(winmain::hinst, lpName, RT_RCDATA);
|
||||||
if (!resHandle)
|
if (!resHandle)
|
||||||
@@ -61,16 +76,16 @@ void score::load_msg_font(LPCSTR lpName)
|
|||||||
if (!resGlobal)
|
if (!resGlobal)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto rcData = static_cast<__int16*>(LockResource(resGlobal));
|
auto rcData = static_cast<int16_t*>(LockResource(resGlobal));
|
||||||
|
|
||||||
auto fontp = reinterpret_cast<score_msg_font_type*>(memory::allocate(sizeof(score_msg_font_type)));
|
auto fontp = memory::allocate<score_msg_font_type>();
|
||||||
msg_fontp = fontp;
|
msg_fontp = fontp;
|
||||||
if (!fontp)
|
if (!fontp)
|
||||||
{
|
{
|
||||||
FreeResource(resGlobal);
|
FreeResource(resGlobal);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memset(fontp->Chars, 0, sizeof(fontp->Chars));
|
memset(fontp->Chars, 0, sizeof fontp->Chars);
|
||||||
|
|
||||||
auto maxWidth = 0;
|
auto maxWidth = 0;
|
||||||
auto ptrToWidths = (char*)rcData + 6;
|
auto ptrToWidths = (char*)rcData + 6;
|
||||||
@@ -102,7 +117,7 @@ void score::load_msg_font(LPCSTR lpName)
|
|||||||
if (!width)
|
if (!width)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto bmp = reinterpret_cast<gdrv_bitmap8*>(memory::allocate(sizeof(gdrv_bitmap8)));
|
auto bmp = memory::allocate<gdrv_bitmap8>();
|
||||||
msg_fontp->Chars[charInd] = bmp;
|
msg_fontp->Chars[charInd] = bmp;
|
||||||
if (!bmp)
|
if (!bmp)
|
||||||
{
|
{
|
||||||
@@ -130,23 +145,56 @@ void score::load_msg_font(LPCSTR lpName)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memory::free(tmpCharBur);
|
||||||
if (charInd != 128)
|
if (charInd != 128)
|
||||||
unload_msg_font();
|
unload_msg_font();
|
||||||
FreeResource(resGlobal);
|
FreeResource(resGlobal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void score::load_msg_font_FT(LPCSTR lpName)
|
||||||
|
{
|
||||||
|
if (!pb::record_table)
|
||||||
|
return;
|
||||||
|
int groupIndex = partman::record_labeled(pb::record_table, lpName);
|
||||||
|
if (groupIndex < 0)
|
||||||
|
return;
|
||||||
|
msg_fontp = reinterpret_cast<score_msg_font_type*>(memory::allocate(sizeof(score_msg_font_type)));
|
||||||
|
if (!msg_fontp)
|
||||||
|
return;
|
||||||
|
|
||||||
|
memset(msg_fontp, 0, sizeof(score_msg_font_type));
|
||||||
|
auto gapArray = reinterpret_cast<int16_t*>(partman::field(pb::record_table, groupIndex, datFieldTypes::ShortArray));
|
||||||
|
if (gapArray)
|
||||||
|
msg_fontp->GapWidth = gapArray[fullscrn::GetResolution()];
|
||||||
|
else
|
||||||
|
msg_fontp->GapWidth = 0;
|
||||||
|
for (auto charIndex = 32; charIndex < 128; charIndex++, ++groupIndex)
|
||||||
|
{
|
||||||
|
auto bmp = reinterpret_cast<gdrv_bitmap8*>(partman::field(pb::record_table, groupIndex,
|
||||||
|
datFieldTypes::Bitmap8bit));
|
||||||
|
if (!bmp)
|
||||||
|
break;
|
||||||
|
if (!msg_fontp->Height)
|
||||||
|
msg_fontp->Height = bmp->Height;
|
||||||
|
msg_fontp->Chars[charIndex] = bmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void score::unload_msg_font()
|
void score::unload_msg_font()
|
||||||
{
|
{
|
||||||
if (msg_fontp)
|
if (msg_fontp)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 128; i++)
|
/*3DB creates bitmaps, FT just references them from partman*/
|
||||||
{
|
if (!pb::FullTiltMode)
|
||||||
if (msg_fontp->Chars[i])
|
for (int i = 0; i < 128; i++)
|
||||||
{
|
{
|
||||||
gdrv::destroy_bitmap(msg_fontp->Chars[i]);
|
if (msg_fontp->Chars[i])
|
||||||
memory::free(msg_fontp->Chars[i]);
|
{
|
||||||
|
gdrv::destroy_bitmap(msg_fontp->Chars[i]);
|
||||||
|
memory::free(msg_fontp->Chars[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
memory::free(msg_fontp);
|
||||||
msg_fontp = nullptr;
|
msg_fontp = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -191,7 +239,7 @@ void score::set(scoreStruct* score, int value)
|
|||||||
|
|
||||||
void score::update(scoreStruct* score)
|
void score::update(scoreStruct* score)
|
||||||
{
|
{
|
||||||
char scoreBuf[12];
|
char scoreBuf[12]{};
|
||||||
if (score && score->DirtyFlag && score->Score <= 1000000000)
|
if (score && score->DirtyFlag && score->Score <= 1000000000)
|
||||||
{
|
{
|
||||||
score->DirtyFlag = false;
|
score->DirtyFlag = false;
|
||||||
@@ -201,12 +249,11 @@ void score::update(scoreStruct* score)
|
|||||||
if (score->Score >= 0)
|
if (score->Score >= 0)
|
||||||
{
|
{
|
||||||
_ltoa_s(score->Score, scoreBuf, 10);
|
_ltoa_s(score->Score, scoreBuf, 10);
|
||||||
int len = strlen(scoreBuf);
|
for (ptrdiff_t index = strlen(scoreBuf) - 1; index >= 0; index--)
|
||||||
for (int index = len - 1; index >= 0; index--)
|
|
||||||
{
|
{
|
||||||
unsigned char curChar = scoreBuf[index];
|
unsigned char curChar = scoreBuf[index];
|
||||||
curChar -= '0';
|
curChar -= '0';
|
||||||
gdrv_bitmap8* bmp = score->CharBmp[curChar];
|
gdrv_bitmap8* bmp = score->CharBmp[curChar % 10];
|
||||||
x -= bmp->Width;
|
x -= bmp->Width;
|
||||||
int height = bmp->Height;
|
int height = bmp->Height;
|
||||||
int width = bmp->Width;
|
int width = bmp->Width;
|
||||||
|
|||||||
@@ -42,4 +42,7 @@ public:
|
|||||||
static void set(scoreStruct* score, int value);
|
static void set(scoreStruct* score, int value);
|
||||||
static void update(scoreStruct* score);
|
static void update(scoreStruct* score);
|
||||||
static void string_format(int score, char* str);
|
static void string_format(int score, char* str);
|
||||||
|
private :
|
||||||
|
static void load_msg_font_3DPB(LPCSTR lpName);
|
||||||
|
static void load_msg_font_FT(LPCSTR lpName);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,13 +6,14 @@
|
|||||||
#include "pinball.h"
|
#include "pinball.h"
|
||||||
|
|
||||||
HINSTANCE splash::HInstance;
|
HINSTANCE splash::HInstance;
|
||||||
|
HGDIOBJ splash::OriginalDcBitmap = nullptr;
|
||||||
|
|
||||||
splash_struct* splash::splash_screen(HINSTANCE hInstance, LPCSTR bmpName1, LPCSTR bmpName2)
|
splash_struct* splash::splash_screen(HINSTANCE hInstance, LPCSTR bmpName1, LPCSTR bmpName2)
|
||||||
{
|
{
|
||||||
WNDCLASSA WndClass{};
|
WNDCLASSA WndClass{};
|
||||||
tagRECT Rect{};
|
tagRECT Rect{};
|
||||||
|
|
||||||
auto splashStruct = reinterpret_cast<splash_struct*>(memory::allocate(sizeof(splash_struct)));
|
auto splashStruct = memory::allocate<splash_struct>();
|
||||||
if (!splashStruct)
|
if (!splashStruct)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
@@ -29,12 +30,12 @@ splash_struct* splash::splash_screen(HINSTANCE hInstance, LPCSTR bmpName1, LPCST
|
|||||||
WndClass.hIcon = nullptr;
|
WndClass.hIcon = nullptr;
|
||||||
WndClass.hCursor = LoadCursorA(nullptr, IDC_ARROW);
|
WndClass.hCursor = LoadCursorA(nullptr, IDC_ARROW);
|
||||||
WndClass.hbrBackground = nullptr;
|
WndClass.hbrBackground = nullptr;
|
||||||
WndClass.lpszMenuName = pinball::WindowName;
|
WndClass.lpszMenuName = "";
|
||||||
WndClass.lpszClassName = "3DPB_SPLASH_CLASS";
|
WndClass.lpszClassName = "3DPB_SPLASH_CLASS";
|
||||||
RegisterClassA(&WndClass);
|
RegisterClassA(&WndClass);
|
||||||
}
|
}
|
||||||
splashStruct->Bitmap = nullptr;
|
splashStruct->Bitmap = nullptr;
|
||||||
HWND windowHandle = CreateWindowExA(0, "3DPB_SPLASH_CLASS", pinball::WindowName, 0x80000000, -10, -10, 1, 1,
|
HWND windowHandle = CreateWindowExA(0, "3DPB_SPLASH_CLASS", "", 0x80000000, -10, -10, 1, 1,
|
||||||
nullptr, nullptr, HInstance, nullptr);
|
nullptr, nullptr, HInstance, nullptr);
|
||||||
splashStruct->WindowHandle = windowHandle;
|
splashStruct->WindowHandle = windowHandle;
|
||||||
if (!windowHandle)
|
if (!windowHandle)
|
||||||
@@ -75,7 +76,7 @@ void splash::splash_bitmap_setup(splash_struct* splashStruct)
|
|||||||
{
|
{
|
||||||
if (splashStruct->DrawingContext)
|
if (splashStruct->DrawingContext)
|
||||||
{
|
{
|
||||||
SelectObject(splashStruct->DrawingContext, bmpHandle1);
|
OriginalDcBitmap = SelectObject(splashStruct->DrawingContext, bmpHandle1);
|
||||||
if ((GetDeviceCaps(splashStruct->DrawingContext, RASTERCAPS) & RC_PALETTE) != 0
|
if ((GetDeviceCaps(splashStruct->DrawingContext, RASTERCAPS) & RC_PALETTE) != 0
|
||||||
|| GetDeviceCaps(splashStruct->DrawingContext, NUMCOLORS) >= 256)
|
|| GetDeviceCaps(splashStruct->DrawingContext, NUMCOLORS) >= 256)
|
||||||
{
|
{
|
||||||
@@ -85,6 +86,7 @@ void splash::splash_bitmap_setup(splash_struct* splashStruct)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
bmpHandle2 = LoadBitmapA(HInstance, splashStruct->BmpName2);
|
bmpHandle2 = LoadBitmapA(HInstance, splashStruct->BmpName2);
|
||||||
|
splashStruct->Palette = nullptr;
|
||||||
}
|
}
|
||||||
splashStruct->Bitmap = bmpHandle2;
|
splashStruct->Bitmap = bmpHandle2;
|
||||||
|
|
||||||
@@ -162,11 +164,11 @@ HBITMAP splash::load_title_bitmap(HMODULE hModule, HDC hdc, LPCSTR lpName, UINT
|
|||||||
return resBmp;
|
return resBmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
HPALETTE splash::splash_init_palette(LOGPALETTEx256* plpal)
|
HPALETTE splash::splash_init_palette(LOGPALETTE* plpal)
|
||||||
{
|
{
|
||||||
plpal->palVersion = 768;
|
plpal->palVersion = 768;
|
||||||
plpal->palNumEntries = 256;
|
plpal->palNumEntries = 256;
|
||||||
auto hPalette = CreatePalette(reinterpret_cast<const LOGPALETTE*>(plpal));
|
auto hPalette = CreatePalette(static_cast<const LOGPALETTE*>(plpal));
|
||||||
auto dc = GetDC(GetDesktopWindow());
|
auto dc = GetDC(GetDesktopWindow());
|
||||||
GetDeviceCaps(dc, RASTERCAPS);
|
GetDeviceCaps(dc, RASTERCAPS);
|
||||||
if (GetDeviceCaps(dc, SIZEPALETTE) != 256)
|
if (GetDeviceCaps(dc, SIZEPALETTE) != 256)
|
||||||
@@ -243,7 +245,11 @@ void splash::splash_destroy(splash_struct* splashStruct)
|
|||||||
splashStruct->Palette = nullptr;
|
splashStruct->Palette = nullptr;
|
||||||
|
|
||||||
if (splashStruct->DrawingContext)
|
if (splashStruct->DrawingContext)
|
||||||
|
{
|
||||||
|
if (OriginalDcBitmap)
|
||||||
|
SelectObject(splashStruct->DrawingContext, OriginalDcBitmap);
|
||||||
DeleteDC(splashStruct->DrawingContext);
|
DeleteDC(splashStruct->DrawingContext);
|
||||||
|
}
|
||||||
if (splashStruct->Bitmap)
|
if (splashStruct->Bitmap)
|
||||||
DeleteObject(splashStruct->Bitmap);
|
DeleteObject(splashStruct->Bitmap);
|
||||||
}
|
}
|
||||||
@@ -278,12 +284,15 @@ LRESULT splash::splash_message_handler(HWND hWnd, UINT Msg, WPARAM wParam, LPARA
|
|||||||
BeginPaint(hWnd, &Paint);
|
BeginPaint(hWnd, &Paint);
|
||||||
EndPaint(hWnd, &Paint);
|
EndPaint(hWnd, &Paint);
|
||||||
auto dc = GetDC(hWnd);
|
auto dc = GetDC(hWnd);
|
||||||
if (dc && splashStruct)
|
if (dc)
|
||||||
{
|
{
|
||||||
BitBlt(dc, 0, 0, 10000, 10000, dc, 0, 0, BLACKNESS);
|
if (splashStruct)
|
||||||
splash_paint(splashStruct, dc);
|
{
|
||||||
|
BitBlt(dc, 0, 0, 10000, 10000, dc, 0, 0, BLACKNESS);
|
||||||
|
splash_paint(splashStruct, dc);
|
||||||
|
}
|
||||||
|
ReleaseDC(hWnd, dc);
|
||||||
}
|
}
|
||||||
ReleaseDC(hWnd, dc);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case WM_ERASEBKGND:
|
case WM_ERASEBKGND:
|
||||||
|
|||||||
@@ -22,12 +22,14 @@ class splash
|
|||||||
public:
|
public:
|
||||||
static splash_struct* splash_screen(HINSTANCE hInstance, LPCSTR bmpName1, LPCSTR bmpName2);
|
static splash_struct* splash_screen(HINSTANCE hInstance, LPCSTR bmpName1, LPCSTR bmpName2);
|
||||||
static void splash_bitmap_setup(splash_struct* splashStruct);
|
static void splash_bitmap_setup(splash_struct* splashStruct);
|
||||||
static HBITMAP load_title_bitmap(HMODULE hModule, HDC hdc, LPCSTR lpName, UINT iStart, int iEnd, HPALETTE* palettePtr);
|
static HBITMAP load_title_bitmap(HMODULE hModule, HDC hdc, LPCSTR lpName, UINT iStart, int iEnd,
|
||||||
static HPALETTE splash_init_palette(LOGPALETTEx256* plpal);
|
HPALETTE* palettePtr);
|
||||||
|
static HPALETTE splash_init_palette(LOGPALETTE* plpal);
|
||||||
static void splash_paint(splash_struct* splashStruct, HDC dc);
|
static void splash_paint(splash_struct* splashStruct, HDC dc);
|
||||||
static void splash_destroy(splash_struct* splashStruct);
|
static void splash_destroy(splash_struct* splashStruct);
|
||||||
static void splash_hide(splash_struct* splashStruct);
|
static void splash_hide(splash_struct* splashStruct);
|
||||||
static LRESULT __stdcall splash_message_handler(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
|
static LRESULT __stdcall splash_message_handler(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
|
||||||
private:
|
private:
|
||||||
static HINSTANCE HInstance;
|
static HINSTANCE HInstance;
|
||||||
|
static HGDIOBJ OriginalDcBitmap;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ timer_struct* timer::TimerBuffer;
|
|||||||
|
|
||||||
int timer::init(int count)
|
int timer::init(int count)
|
||||||
{
|
{
|
||||||
auto buf = (timer_struct*)memory::allocate(sizeof(timer_struct) * count);
|
auto buf = memory::allocate<timer_struct>(count);
|
||||||
TimerBuffer = buf;
|
TimerBuffer = buf;
|
||||||
if (!buf)
|
if (!buf)
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -4,6 +4,8 @@
|
|||||||
class winmain
|
class winmain
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
static const DWORD WndStyle = WS_GROUP | WS_SYSMENU | WS_DLGFRAME | WS_BORDER | WS_MAXIMIZE | WS_CLIPCHILDREN |
|
||||||
|
WS_THICKFRAME | WS_MAXIMIZEBOX;
|
||||||
static char DatFileName[300];
|
static char DatFileName[300];
|
||||||
static int single_step;
|
static int single_step;
|
||||||
static HINSTANCE hinst;
|
static HINSTANCE hinst;
|
||||||
@@ -20,6 +22,7 @@ public:
|
|||||||
static void new_game();
|
static void new_game();
|
||||||
static void pause();
|
static void pause();
|
||||||
static void help_introduction(HINSTANCE a1, HWND a2);
|
static void help_introduction(HINSTANCE a1, HWND a2);
|
||||||
|
static void Restart();
|
||||||
private:
|
private:
|
||||||
static int return_value, bQuit, DispFrameRate, DispGRhistory, activated;
|
static int return_value, bQuit, DispFrameRate, DispGRhistory, activated;
|
||||||
static int has_focus, mouse_down, last_mouse_x, last_mouse_y, no_time_loss;
|
static int has_focus, mouse_down, last_mouse_x, last_mouse_y, no_time_loss;
|
||||||
@@ -27,6 +30,7 @@ private:
|
|||||||
static UINT iFrostUniqueMsg;
|
static UINT iFrostUniqueMsg;
|
||||||
static gdrv_bitmap8 gfr_display;
|
static gdrv_bitmap8 gfr_display;
|
||||||
static HCURSOR mouse_hsave;
|
static HCURSOR mouse_hsave;
|
||||||
|
static bool restart;
|
||||||
|
|
||||||
static HDC _BeginPaint(HWND hWnd, LPPAINTSTRUCT lpPaint);
|
static HDC _BeginPaint(HWND hWnd, LPPAINTSTRUCT lpPaint);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
#include "zdrv.h"
|
#include "zdrv.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
#include "pb.h"
|
||||||
|
|
||||||
|
|
||||||
int zdrv::create_zmap(zmap_header_type* zmap, int width, int height)
|
int zdrv::create_zmap(zmap_header_type* zmap, int width, int height)
|
||||||
{
|
{
|
||||||
int stride = pad(width);
|
int stride = pad(width);
|
||||||
zmap->Stride = stride;
|
zmap->Stride = stride;
|
||||||
auto bmpBuf = (unsigned short*)memory::allocate(2 * height * stride);
|
auto bmpBuf = memory::allocate<unsigned short>(height * stride);
|
||||||
zmap->ZPtr1 = bmpBuf;
|
zmap->ZPtr1 = bmpBuf;
|
||||||
if (!bmpBuf)
|
if (!bmpBuf)
|
||||||
return -1;
|
return -1;
|
||||||
@@ -35,22 +36,16 @@ int zdrv::destroy_zmap(zmap_header_type* zmap)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void zdrv::fill(zmap_header_type* zmap, int width, int height, int xOff, int yOff, unsigned __int16 fillChar)
|
void zdrv::fill(zmap_header_type* zmap, int width, int height, int xOff, int yOff, uint16_t fillWord)
|
||||||
{
|
{
|
||||||
int fillCharInt = fillChar | (fillChar << 16);
|
auto dstPtr = &zmap->ZPtr1[zmap->Stride * (zmap->Height - height - yOff) + xOff];
|
||||||
auto zmapPtr = &zmap->ZPtr1[xOff + zmap->Stride * (zmap->Height - height - yOff)];
|
for (int y = height; y > 0; --y)
|
||||||
|
|
||||||
for (int y = height; width > 0 && y > 0; y--)
|
|
||||||
{
|
{
|
||||||
char widthMod2 = width & 1;
|
for (int x = width; x > 0; --x)
|
||||||
unsigned int widthDiv2 = static_cast<unsigned int>(width) >> 1;
|
{
|
||||||
memset32(zmapPtr, fillCharInt, widthDiv2);
|
*dstPtr++ = fillWord;
|
||||||
|
}
|
||||||
auto lastShort = &zmapPtr[2 * widthDiv2];
|
dstPtr += zmap->Stride - width;
|
||||||
for (int i = widthMod2; i; --i)
|
|
||||||
*lastShort++ = fillChar;
|
|
||||||
|
|
||||||
zmapPtr += zmap->Stride;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,6 +54,13 @@ void zdrv::paint(int width, int height, gdrv_bitmap8* dstBmp, int dstBmpXOff, in
|
|||||||
int dstZMapXOff, int dstZMapYOff, gdrv_bitmap8* srcBmp, int srcBmpXOff, int srcBmpYOff,
|
int dstZMapXOff, int dstZMapYOff, gdrv_bitmap8* srcBmp, int srcBmpXOff, int srcBmpYOff,
|
||||||
zmap_header_type* srcZMap, int srcZMapXOff, int srcZMapYOff)
|
zmap_header_type* srcZMap, int srcZMapXOff, int srcZMapYOff)
|
||||||
{
|
{
|
||||||
|
if (srcBmp->BitmapType == BitmapType::Spliced)
|
||||||
|
{
|
||||||
|
/*Spliced bitmap is also a zMap, how convenient*/
|
||||||
|
paint_spliced_bmp(srcBmp->XPosition, srcBmp->YPosition, dstBmp, dstZMap, srcBmp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int dstHeightAbs = abs(dstBmp->Height);
|
int dstHeightAbs = abs(dstBmp->Height);
|
||||||
int srcHeightAbs = abs(srcBmp->Height);
|
int srcHeightAbs = abs(srcBmp->Height);
|
||||||
auto srcPtr = &srcBmp->BmpBufPtr1[srcBmp->Stride * (srcHeightAbs - height - srcBmpYOff) + srcBmpXOff];
|
auto srcPtr = &srcBmp->BmpBufPtr1[srcBmp->Stride * (srcHeightAbs - height - srcBmpYOff) + srcBmpXOff];
|
||||||
@@ -90,7 +92,7 @@ void zdrv::paint(int width, int height, gdrv_bitmap8* dstBmp, int dstBmpXOff, in
|
|||||||
|
|
||||||
void zdrv::paint_flat(int width, int height, gdrv_bitmap8* dstBmp, int dstBmpXOff, int dstBmpYOff,
|
void zdrv::paint_flat(int width, int height, gdrv_bitmap8* dstBmp, int dstBmpXOff, int dstBmpYOff,
|
||||||
zmap_header_type* zMap, int dstZMapXOff, int dstZMapYOff, gdrv_bitmap8* srcBmp, int srcBmpXOff,
|
zmap_header_type* zMap, int dstZMapXOff, int dstZMapYOff, gdrv_bitmap8* srcBmp, int srcBmpXOff,
|
||||||
int srcBmpYOff, unsigned __int16 depth)
|
int srcBmpYOff, uint16_t depth)
|
||||||
{
|
{
|
||||||
int dstHeightAbs = abs(dstBmp->Height);
|
int dstHeightAbs = abs(dstBmp->Height);
|
||||||
int srcHeightAbs = abs(srcBmp->Height);
|
int srcHeightAbs = abs(srcBmp->Height);
|
||||||
@@ -116,3 +118,41 @@ void zdrv::paint_flat(int width, int height, gdrv_bitmap8* dstBmp, int dstBmpXOf
|
|||||||
zPtr += zMap->Stride - width;
|
zPtr += zMap->Stride - width;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void zdrv::paint_spliced_bmp(int xPos, int yPos, gdrv_bitmap8* dstBmp, zmap_header_type* dstZmap, gdrv_bitmap8* srcBmp)
|
||||||
|
{
|
||||||
|
assertm(srcBmp->BitmapType == BitmapType::Spliced, "Wrong bmp type");
|
||||||
|
int xOffset = xPos - pb::MainTable->XOffset;
|
||||||
|
int yOffset = dstBmp->Height - srcBmp->Height - (yPos - pb::MainTable->YOffset);
|
||||||
|
if (yOffset < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto bmpDstPtr = &dstBmp->BmpBufPtr2[xOffset + yOffset * dstBmp->Stride];
|
||||||
|
auto zMapDstPtr = &dstZmap->ZPtr2[xOffset + yOffset * dstZmap->Stride];
|
||||||
|
auto bmpSrcPtr = reinterpret_cast<unsigned short*>(srcBmp->BmpBufPtr2);
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
auto stride = static_cast<short>(*bmpSrcPtr++);
|
||||||
|
if (stride < 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/*Stride is in terms of dst stride, hardcoded to match vScreen width in current resolution*/
|
||||||
|
zMapDstPtr += stride;
|
||||||
|
bmpDstPtr += stride;
|
||||||
|
for (auto count = *bmpSrcPtr++; count; count--)
|
||||||
|
{
|
||||||
|
auto depth = *bmpSrcPtr++;
|
||||||
|
auto charPtr = reinterpret_cast<char**>(&bmpSrcPtr);
|
||||||
|
if (*zMapDstPtr >= depth)
|
||||||
|
{
|
||||||
|
*bmpDstPtr = **charPtr;
|
||||||
|
*zMapDstPtr = depth;
|
||||||
|
}
|
||||||
|
|
||||||
|
(*charPtr)++;
|
||||||
|
++zMapDstPtr;
|
||||||
|
++bmpDstPtr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,12 +3,12 @@
|
|||||||
|
|
||||||
struct zmap_header_type
|
struct zmap_header_type
|
||||||
{
|
{
|
||||||
__int16 Width;
|
int Width;
|
||||||
__int16 Height;
|
int Height;
|
||||||
__int16 Stride;
|
int Stride;
|
||||||
unsigned __int16* ZPtr1;
|
uint16_t* ZPtr1;
|
||||||
unsigned __int16* ZPtr2;
|
uint16_t* ZPtr2;
|
||||||
unsigned __int16 ZBuffer[1];
|
uint16_t ZBuffer[1];
|
||||||
};
|
};
|
||||||
|
|
||||||
class zdrv
|
class zdrv
|
||||||
@@ -17,11 +17,13 @@ public:
|
|||||||
static int pad(int width);
|
static int pad(int width);
|
||||||
static int create_zmap(zmap_header_type* zmap, int width, int height);
|
static int create_zmap(zmap_header_type* zmap, int width, int height);
|
||||||
static int destroy_zmap(zmap_header_type* zmap);
|
static int destroy_zmap(zmap_header_type* zmap);
|
||||||
static void fill(zmap_header_type* zmap, int width, int height, int xOff, int yOff, unsigned __int16 fillChar);
|
static void fill(zmap_header_type* zmap, int width, int height, int xOff, int yOff, uint16_t fillWord);
|
||||||
static void paint(int width, int height, gdrv_bitmap8* dstBmp, int dstBmpXOff, int dstBmpYOff,
|
static void paint(int width, int height, gdrv_bitmap8* dstBmp, int dstBmpXOff, int dstBmpYOff,
|
||||||
zmap_header_type* dstZMap, int dstZMapXOff, int dstZMapYOff, gdrv_bitmap8* srcBmp, int srcBmpXOff,
|
zmap_header_type* dstZMap, int dstZMapXOff, int dstZMapYOff, gdrv_bitmap8* srcBmp, int srcBmpXOff,
|
||||||
int srcBmpYOff, zmap_header_type* srcZMap, int srcZMapXOff, int srcZMapYOff);
|
int srcBmpYOff, zmap_header_type* srcZMap, int srcZMapXOff, int srcZMapYOff);
|
||||||
static void paint_flat(int width, int height, gdrv_bitmap8* dstBmp, int dstBmpXOff, int dstBmpYOff,
|
static void paint_flat(int width, int height, gdrv_bitmap8* dstBmp, int dstBmpXOff, int dstBmpYOff,
|
||||||
zmap_header_type* zMap, int dstZMapXOff, int dstZMapYOff, gdrv_bitmap8* srcBmp,
|
zmap_header_type* zMap, int dstZMapXOff, int dstZMapYOff, gdrv_bitmap8* srcBmp,
|
||||||
int srcBmpXOff, int srcBmpYOff, unsigned __int16 depth);
|
int srcBmpXOff, int srcBmpYOff, uint16_t depth);
|
||||||
|
static void paint_spliced_bmp(int xPos, int yPos, gdrv_bitmap8* dstBmp, zmap_header_type* dstZmap,
|
||||||
|
gdrv_bitmap8* srcBmp);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user