11 Commits

Author SHA1 Message Date
Muzychenko Andrey
331f1dc125 Added release version to about dialog. 2021-10-16 16:19:53 +03:00
Muzychenko Andrey
0d9610ddb6 Added new render mode with reduced tearing.
Available under new option Window->Alternative Rendering.
Issue #29.
2021-10-12 16:30:20 +03:00
Muzychenko Andrey
de76557325 Bug fixes from master:
Demangled and simplified cheat controller.
TKickout temp Z in FT mode.
Flipper animation frame advance.
Fuel bar graph light states.
2021-10-09 08:14:47 +03:00
Muzychenko Andrey
b995b02fd1 Added ARM/ARM64 build configurations.
Ref #21.
2021-10-04 10:03:16 +03:00
Muzychenko Andrey
de6c31802c Bug fixes from master: score saving and missing sub. 2021-09-30 08:59:56 +03:00
Muzychenko Andrey
86eaad5b79 Fixed off-by-one error in background blit. 2021-09-07 10:19:06 +03:00
Muzychenko Andrey
60e9f63607 Added Windows XP build configuration.
Improved background blit for unform scaling.
2021-09-07 10:09:07 +03:00
Muzychenko Andrey
10c83e8bf5 Fixed sound pops introduced by WaveMix upsampler.
This does not fix WINE issues, but at least you don’t have to up sample manually.
2021-08-19 09:29:32 +03:00
Muzychenko Andrey
d5b44e44e1 Improved wav duration calculation - now supports sample rates other than 11025.
Bumped build tool version to VS2019.
2021-08-18 12:44:26 +03:00
Muzychenko Andrey
dcd488c48c Merge pull request #5 from GeorgeMcMullen/midifix
Fix to the routine that opens the MIDI file.
2021-08-18 10:08:55 +03:00
George McMullen
db08631ab9 Fix to the routine that opens the MIDI file.
In the original source code for Space Cadet and its related games, the MIDI sound track is opened with MCI_OPEN_TYPE. According to Microsoft's documentation (https://docs.microsoft.com/en-us/windows/win32/multimedia/mci-open), this is for opening devices and not files. Windows' libraries were obviously robust enough to accommodate the error, but other platforms (i.e. WINE) expects things to be called the right way. The simple fix is to switch out MCI_OPEN_TYPE with MCI_OPEN_ELEMENT and move the info for the filename to the lpstrElementName variable.
2021-08-16 05:39:18 -07:00
34 changed files with 707 additions and 426 deletions

11
.gitignore vendored
View File

@@ -21,6 +21,9 @@ bld/
[Bb]in/
[Oo]bj/
[Ll]og/
ARM/
ARM64/
win32/
# Visual Studio 2015 cache/options directory
.vs/
@@ -263,3 +266,11 @@ __pycache__/
/Export
/DrMem
/Doc private
# Cmake stuff
/Libs
/out
# WinXp stuff
DebugWinXp/
ReleaseWinXp/

View File

@@ -1,26 +1,50 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.28307.705
# Visual Studio Version 16
VisualStudioVersion = 16.0.31624.102
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SpaceCadetPinball", "SpaceCadetPinball\SpaceCadetPinball.vcxproj", "{F7B78CC7-6984-4F79-9486-ABCF87DF9F06}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM = Debug|ARM
Debug|ARM64 = Debug|ARM64
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|ARM = Release|ARM
Release|ARM64 = Release|ARM64
Release|x64 = Release|x64
Release|x86 = Release|x86
ReleaseWinXp|ARM = ReleaseWinXp|ARM
ReleaseWinXp|ARM64 = ReleaseWinXp|ARM64
ReleaseWinXp|x64 = ReleaseWinXp|x64
ReleaseWinXp|x86 = ReleaseWinXp|x86
EndGlobalSection
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.Build.0 = Debug|x64
{F7B78CC7-6984-4F79-9486-ABCF87DF9F06}.Debug|x86.ActiveCfg = Debug|Win32
{F7B78CC7-6984-4F79-9486-ABCF87DF9F06}.Debug|x86.Build.0 = Debug|Win32
{F7B78CC7-6984-4F79-9486-ABCF87DF9F06}.Release|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.Build.0 = Release|x64
{F7B78CC7-6984-4F79-9486-ABCF87DF9F06}.Release|x86.ActiveCfg = Release|Win32
{F7B78CC7-6984-4F79-9486-ABCF87DF9F06}.Release|x86.Build.0 = Release|Win32
{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
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@@ -98,6 +98,7 @@ BEGIN
POPUP "&Window"
BEGIN
MENUITEM "&Uniform Scaling", Menu1_WindowUniformScale
MENUITEM "&Alternative Rendering", Menu1_AlternativeRender
END
END
POPUP "&Help"

View File

@@ -1,10 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</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">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
@@ -23,32 +55,86 @@
<ProjectGuid>{F7B78CC7-6984-4F79-9486-ABCF87DF9F06}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>SpaceCadetPinball</RootNamespace>
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<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>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<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>
<CharacterSet>NotSet</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<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>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<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>
<CharacterSet>NotSet</CharacterSet>
</PropertyGroup>
@@ -60,29 +146,84 @@
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup 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'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</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'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</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'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</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 Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<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 Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<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 Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</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'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
@@ -102,6 +243,25 @@
<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>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>Comctl32.lib;Winmm.lib;Htmlhelp.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
@@ -119,6 +279,23 @@
<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>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>Comctl32.lib;Winmm.lib;Htmlhelp.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
@@ -140,6 +317,69 @@
<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>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>Comctl32.lib;Winmm.lib;Htmlhelp.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
@@ -161,6 +401,69 @@
<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>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>Comctl32.lib;Winmm.lib;Htmlhelp.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="control.h" />
<ClInclude Include="fullscrn.h" />
@@ -242,9 +545,17 @@
<ClCompile Include="pb.cpp" />
<ClCompile Include="pch.cpp">
<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|ARM64'">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|ARM64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseWinXp|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseWinXp|ARM64'">Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="pinball.cpp" />
<ClCompile Include="proj.cpp" />

View File

@@ -22,14 +22,14 @@ TFlipper::TFlipper(TPinballTable* table, int groupIndex) : TCollisionComponent(t
Smoothness = visual.Smoothness;
auto collMult = *loader::query_float_attribute(groupIndex, 0, 803);
auto bmpCoef2 = *loader::query_float_attribute(groupIndex, 0, 805);
auto bmpCoef1 = *loader::query_float_attribute(groupIndex, 0, 804);
auto retractTime = *loader::query_float_attribute(groupIndex, 0, 805);
auto extendTime = *loader::query_float_attribute(groupIndex, 0, 804);
/*Full tilt hack: different flipper speed*/
if (pb::FullTiltMode)
{
bmpCoef2 = 0.08f;
bmpCoef1 = 0.04f;
retractTime = 0.08f;
extendTime = 0.04f;
}
auto vecT2 = reinterpret_cast<vector_type*>(loader::query_float_attribute(groupIndex, 0, 802));
auto vecT1 = reinterpret_cast<vector_type*>(loader::query_float_attribute(groupIndex, 0, 801));
@@ -42,8 +42,8 @@ TFlipper::TFlipper(TPinballTable* table, int groupIndex) : TCollisionComponent(t
origin,
vecT1,
vecT2,
bmpCoef1,
bmpCoef2,
extendTime,
retractTime,
collMult,
Elasticity,
Smoothness);
@@ -51,8 +51,8 @@ TFlipper::TFlipper(TPinballTable* table, int groupIndex) : TCollisionComponent(t
FlipperEdge = flipperEdge;
if (flipperEdge)
{
BmpCoef1 = flipperEdge->BmpCoef1 / static_cast<float>(ListBitmap->GetCount() - 1);
BmpCoef2 = flipperEdge->BmpCoef2 / static_cast<float>(ListBitmap->GetCount() - 1);
ExtendAnimationFrameTime = flipperEdge->ExtendTime / static_cast<float>(ListBitmap->GetCount() - 1);
RetractAnimationFrameTime = flipperEdge->RetractTime / static_cast<float>(ListBitmap->GetCount() - 1);
}
BmpIndex = 0;
InputTime = 0.0;
@@ -68,35 +68,30 @@ int TFlipper::Message(int code, float value)
if (code == 1 || code == 2 || code > 1008 && code <= 1011 || code == 1022)
{
float timerTime;
int soundIndex = 0, code2 = code;
int command = code;
if (code == 1)
{
control::handler(1, this);
TimerTime = BmpCoef1;
soundIndex = HardHitSoundId;
TimerTime = ExtendAnimationFrameTime;
loader::play_sound(HardHitSoundId);
}
else if (code == 2)
{
TimerTime = BmpCoef2;
soundIndex = SoftHitSoundId;
TimerTime = RetractAnimationFrameTime;
loader::play_sound(SoftHitSoundId);
}
else
{
code2 = 2;
TimerTime = BmpCoef2;
// Retract for all non-input messages
command = 2;
TimerTime = RetractAnimationFrameTime;
}
if (soundIndex)
loader::play_sound(soundIndex);
if (Timer)
{
timer::kill(Timer);
Timer = 0;
}
if (MessageField)
{
auto v10 = value - FlipperEdge->InputTime;
timerTime = v10 - floor(v10 / TimerTime) * TimerTime;
// Message arrived before animation is finished
auto inputDt = value - FlipperEdge->InputTime;
timerTime = inputDt - floor(inputDt / TimerTime) * TimerTime;
if (timerTime < 0.0f)
timerTime = 0.0;
}
@@ -104,10 +99,13 @@ int TFlipper::Message(int code, float value)
{
timerTime = TimerTime;
}
MessageField = code2;
MessageField = command;
InputTime = value;
if (Timer)
timer::kill(Timer);
Timer = timer::set(timerTime, this, TimerExpired);
FlipperEdge->SetMotion(code2, value);
FlipperEdge->SetMotion(command, value);
}
if (code == 1020 || code == 1024)
@@ -137,49 +135,43 @@ void TFlipper::Collision(TBall* ball, vector_type* nextPosition, vector_type* di
void TFlipper::TimerExpired(int timerId, void* caller)
{
auto flip = static_cast<TFlipper*>(caller);
int timer; // eax
int bmpCountSub1 = flip->ListBitmap->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;
auto bmpIndexAdvance = static_cast<int>(floor((pb::time_now - flip->InputTime) / flip->TimerTime + 0.5f));
int bmpCount = flip->ListBitmap->GetCount();
if (bmpIndexAdvance > bmpCount)
bmpIndexAdvance = bmpCount;
if (bmpIndexAdvance < 0)
bmpIndexAdvance = 0;
if (!bmpIndexAdvance)
bmpIndexAdvance = 1;
if (flip->MessageField == 1)
{
flip->BmpIndex += bmpIndexAdvance;
int countSub1 = flip->ListBitmap->GetCount() - 1;
if (flip->BmpIndex >= countSub1)
flip->BmpIndex = newBmpIndex;
if (flip->BmpIndex >= bmpCountSub1)
{
flip->BmpIndex = countSub1;
flip->BmpIndex = bmpCountSub1;
bmpIndexOutOfBounds = true;
}
}
if (flip->MessageField == 2)
{
flip->BmpIndex -= bmpIndexAdvance;
timer = 0;
flip->BmpIndex = bmpCountSub1 - newBmpIndex;
if (flip->BmpIndex <= 0)
{
flip->BmpIndex = 0;
bmpIndexOutOfBounds = true;
}
}
else
{
timer = 0;
}
if (bmpIndexOutOfBounds)
{
flip->MessageField = 0;
flip->Timer = 0;
}
else
timer = timer::set(flip->TimerTime, flip, TimerExpired);
flip->Timer = timer;
{
flip->Timer = timer::set(flip->TimerTime, flip, TimerExpired);
}
auto bmp = flip->ListBitmap->Get(flip->BmpIndex);
auto zMap = flip->ListZMap->Get(flip->BmpIndex);

View File

@@ -19,8 +19,8 @@ public:
int BmpIndex;
TFlipperEdge* FlipperEdge;
int Timer;
float BmpCoef1;
float BmpCoef2;
float ExtendAnimationFrameTime;
float RetractAnimationFrameTime;
float TimerTime;
float InputTime;
};

View File

@@ -12,15 +12,15 @@ line_type TFlipperEdge::lineA, TFlipperEdge::lineB;
circle_type TFlipperEdge::circlebase, TFlipperEdge::circleT1;
TFlipperEdge::TFlipperEdge(TCollisionComponent* collComp, char* activeFlag, unsigned int collisionGroup, TPinballTable* table,
vector_type* origin, vector_type* vecT1, vector_type* vecT2, float bmpCoef1, float bmpCoef2,
vector_type* origin, vector_type* vecT1, vector_type* vecT2, float extendTime, float retractTime,
float collMult, float elasticity, float smoothness): TEdgeSegment(collComp, activeFlag, collisionGroup)
{
vector_type crossProd{}, vecDir1{}, vecDir2{};
Elasticity = elasticity;
Smoothness = smoothness;
BmpCoef1 = bmpCoef1;
BmpCoef2 = bmpCoef2;
ExtendTime = extendTime;
RetractTime = retractTime;
CollisionMult = collMult;
T1Src = *vecT1;
@@ -78,9 +78,9 @@ TFlipperEdge::TFlipperEdge(TCollisionComponent* collComp, char* activeFlag, unsi
auto distance1 = sqrt(dy * dy + dx * dx) + table->CollisionCompOffset + vecT1->Z;
DistanceDivSq = distance1 * distance1;
float bmpCoef = min(BmpCoef1, BmpCoef2);
float minMoveTime = min(ExtendTime, RetractTime);
auto distance = maths::Distance(vecT1, vecT2);
CollisionTimeAdvance = bmpCoef / (distance / CircleT1Radius + distance / CircleT1Radius);
CollisionTimeAdvance = minMoveTime / (distance / CircleT1Radius + distance / CircleT1Radius);
TFlipperEdge::place_in_grid();
EdgeCollisionFlag = 0;
@@ -469,12 +469,12 @@ void TFlipperEdge::SetMotion(int code, float value)
case 1:
Angle2 = flipper_angle(value);
Angle1 = AngleMax;
AngleMult = BmpCoef1;
AngleMult = ExtendTime;
break;
case 2:
Angle2 = flipper_angle(value);
Angle1 = 0.0;
AngleMult = BmpCoef2;
AngleMult = RetractTime;
break;
case 1024:
FlipperFlag = 0;

View File

@@ -8,7 +8,7 @@ class TFlipperEdge : public TEdgeSegment
{
public:
TFlipperEdge(TCollisionComponent* collComp, char* activeFlag, unsigned int collisionGroup, TPinballTable* table,
vector_type* origin, vector_type* vecT1, vector_type* vecT2, float bmpCoef1, float bmpCoef2, float collMult,
vector_type* origin, vector_type* vecT1, vector_type* vecT2, float extendTime, float retractTime, float collMult,
float elasticity, float smoothness);
void port_draw() override;
float FindCollisionDistance(ray_type* ray) override;
@@ -50,8 +50,8 @@ public:
float InputTime;
float AngleStopTime;
float AngleMult;
float BmpCoef1;
float BmpCoef2;
float ExtendTime;
float RetractTime;
vector_type NextBallPosition;
static float flipper_sin_angle, flipper_cos_angle;

View File

@@ -5,6 +5,7 @@
#include "control.h"
#include "loader.h"
#include "objlist_class.h"
#include "pb.h"
#include "TBall.h"
#include "TCircle.h"
#include "timer.h"
@@ -44,7 +45,8 @@ TKickout::TKickout(TPinballTable* table, int groupIndex, bool someFlag): TCollis
}
Circle.RadiusSq = visual.FloatArr[2] * visual.FloatArr[2];
CollisionBallSetZ = loader::query_float_attribute(groupIndex, 0, 408)[2];
auto zAttr = loader::query_float_attribute(groupIndex, 0, 408);
CollisionBallSetZ = pb::FullTiltMode ? zAttr[3] : zAttr[2];
ThrowSpeedMult2 = visual.Kicker.ThrowBallMult * 0.01f;
BallAcceleration = visual.Kicker.ThrowBallAcceleration;
ThrowAngleMult = visual.Kicker.ThrowBallAngleMult;

View File

@@ -57,9 +57,8 @@ int TLightBargraph::Message(int code, float value)
TLightGroup::Message(45, static_cast<float>(timeIndex / 2));
if (!(timeIndex & 1))
TLightGroup::Message(46, 0.0);
float* timeArray = TimerTimeArray;
if (timeArray)
TimerBargraph = timer::set(timeArray[timeIndex], this, BargraphTimerExpired);
if (TimerTimeArray)
TimerBargraph = timer::set(TimerTimeArray[timeIndex], this, BargraphTimerExpired);
TimeIndex = timeIndex;
}
else

View File

@@ -374,31 +374,21 @@ int TLightGroup::Message(int code, float value)
}
case 45:
{
auto count = List->GetCount();
control::handler(code, this);
auto index = static_cast<int>(floor(value));
if (index >= 0)
if (index >= 0 && index < count)
{
auto count = List->GetCount();
if (index <= count)
// Turn off lights (index, end]
for (auto i = count - 1; i > index; i--)
{
auto countSub1 = count - 1;
if (countSub1 > index)
{
countSub1 = index;
for (auto i = countSub1, k = countSub1 - index; k != 0; i--, k--)
{
auto light = List->Get(i);
light->Message(20, 0.0);
}
}
if (countSub1 >= 0)
{
for (auto i = countSub1; i != 0; i--)
{
auto light = List->Get(i);
light->Message(19, 0.0);
}
}
List->Get(i)->Message(20, 0.0);
}
// Turn on lights [begin, index]
for (auto i = index; i >= 0; i--)
{
List->Get(i)->Message(19, 0.0);
}
}
break;
@@ -477,7 +467,7 @@ int TLightGroup::next_light_down()
{
for (int index = List->GetCount() - 1; index >= 0; --index)
{
if (!List->Get(index)->BmpIndex1)
if (List->Get(index)->BmpIndex1)
return index;
}
return -1;

View File

@@ -109,7 +109,7 @@ void TTextBox::Clear()
}
}
void TTextBox::Display(char* text, float time)
void TTextBox::Display(const char* text, float time)
{
if (!text)
return;

View File

@@ -21,7 +21,7 @@ public:
~TTextBox() override;
int Message(int code, float value) override;
void Clear();
void Display(char* text, float time);
void Display(const char* text, float time);
void Draw();
static void TimerExpired(int timerId, void* tb);

View File

@@ -3,7 +3,7 @@
#include "memory.h"
#include "pb.h"
TTextBoxMessage::TTextBoxMessage(char* text, float time)
TTextBoxMessage::TTextBoxMessage(const char* text, float time)
{
NextMessage = nullptr;
Time = time;

View File

@@ -7,7 +7,7 @@ public:
float Time;
int EndTicks;
TTextBoxMessage(char* text, float time);
TTextBoxMessage(const char* text, float time);
~TTextBoxMessage();
float TimeLeft() const;
void Refresh(float time);

View File

@@ -2377,6 +2377,12 @@ HPSTR WaveMix::SamplesPerSecAlign(HPSTR lpInData, DWORD nInSamplesPerSec, DWORD
}
}
// Dump raw PCM for analysis.
/*FILE* file;
fopen_s(&file,"wav1_dump.raw", "w");
fwrite(dataBufBup, 1, sampleSize * dwNumSamples2, file);
fclose(file);*/
GlobalUnlock(GlobalHandle(lpInDataBup));
GlobalFree(GlobalHandle(lpInDataBup));
return dataBufBup;
@@ -2427,7 +2433,7 @@ void WaveMix::RepSample(HPSTR lpOutData, HPSTR lpInData, unsigned nRep, int nByt
{
auto sample = *src;
auto dst2 = &dst[nChannels];
auto delta = (src[nChannels] - src[0]) / nRep;
auto delta = (src[nChannels] - src[0]) / static_cast<int>(nRep);
*dst = *src;
dst++;
for (auto repeatIndex = nRep - 1; repeatIndex; repeatIndex--)
@@ -2447,7 +2453,7 @@ void WaveMix::RepSample(HPSTR lpOutData, HPSTR lpInData, unsigned nRep, int nByt
{
auto sample = *src;
auto dst2 = &dst[nChannels];
auto delta = (src[nChannels] - src[0]) / nRep; /*Was dst[nChannels] - */
auto delta = (src[nChannels] - src[0]) / static_cast<int>(nRep); /*Was dst[nChannels] - */
*dst = *src;
++dst;
for (auto repeatIndex2 = nRep - 1; repeatIndex2; --repeatIndex2)

View File

@@ -28,8 +28,6 @@
#include "TPlunger.h"
#include "TWall.h"
int control::pbctrl_state;
int control_bump_scores1[] = {500, 1000, 1500, 2000};
int control_roll_scores1[] = {2000};
int control_bump_scores2[] = {1500, 2500, 3500, 4500};
@@ -528,7 +526,8 @@ component_tag_base* control::simple_components[142]
&control_soundwave7_tag
};
int control::table_unlimited_balls, control::waiting_deployment_flag;
int control::waiting_deployment_flag;
bool control::table_unlimited_balls = false;
int control::extraball_light_flag;
int control::RankRcArray[9] = {84, 85, 86, 87, 88, 89, 90, 91, 92};
int control::MissionRcArray[17] = {60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76};
@@ -631,212 +630,65 @@ void control::handler(int code, TPinballComponent* cmp)
MissionControl(code, cmp);
}
void control::pbctrl_bdoor_controller(int key)
void control::pbctrl_bdoor_controller(char key)
{
int v1; // eax
int v2; // eax
bool v3; // zf
if (!control_lite198_tag.Component->MessageField)
// Buffer large enough for longest cheat + null
static char cheatBuffer[11 + 1]{};
static char* bufferEnd = &cheatBuffer[11];
static const char* quotes[8]
{
if (key <= 'M')
{
if (key == 'M')
{
v2 = pbctrl_state;
if (pbctrl_state == 4 || pbctrl_state == 61 || pbctrl_state == 81 || pbctrl_state == 101)
goto LABEL_87;
v3 = pbctrl_state == 121;
}
else
{
if (key <= 'D')
{
if (key != 'D')
{
if (key == ' ')
{
if (pbctrl_state == 26)
{
pbctrl_state = 27;
return;
}
goto LABEL_77;
}
if (key != '1')
{
if (key != 'A')
{
if (key != 'B')
{
if (key == 'C')
{
if (!pbctrl_state)
{
pbctrl_state = 1;
return;
}
if (pbctrl_state == 11)
{
pbctrl_state = 12;
return;
}
}
goto LABEL_77;
}
v1 = pbctrl_state != 0 ? 0 : 81;
goto LABEL_88;
}
v2 = pbctrl_state;
if (pbctrl_state == 5 || pbctrl_state == 62 || pbctrl_state == 82 || pbctrl_state == 102)
goto LABEL_87;
v3 = pbctrl_state == 122;
goto LABEL_86;
}
v1 = pbctrl_state != 0 ? 0 : 61;
LABEL_88:
pbctrl_state = v1;
return;
}
if (pbctrl_state != 22 && pbctrl_state != 23)
goto LABEL_77;
LABEL_58:
++pbctrl_state;
return;
}
if (key != 'E')
{
switch (key)
{
case 'G':
v1 = pbctrl_state != 0 ? 0 : 101;
break;
case 'H':
v1 = pbctrl_state != 0 ? 0 : 21;
break;
case 'I':
v2 = pbctrl_state;
if (pbctrl_state == 1 || pbctrl_state == 10)
goto LABEL_87;
v3 = pbctrl_state == 21;
goto LABEL_86;
default:
goto LABEL_77;
}
goto LABEL_88;
}
v2 = pbctrl_state;
if (pbctrl_state == 3 || pbctrl_state == 24 || pbctrl_state == 28)
goto LABEL_87;
v3 = pbctrl_state == 44;
}
goto LABEL_86;
}
if (key <= 'S')
{
if (key == 'S')
{
v2 = pbctrl_state;
if (pbctrl_state == 12 || pbctrl_state == 29)
goto LABEL_87;
v3 = pbctrl_state == 45;
}
else
{
if (key != 'N')
{
if (key != 'O')
{
if (key != 'Q')
{
if (key == 'R')
{
if (!pbctrl_state)
{
pbctrl_state = 121;
return;
}
if (pbctrl_state == 7)
{
pbctrl_state = 8;
return;
}
}
goto LABEL_77;
}
v1 = pbctrl_state != 0 ? 0 : 41;
goto LABEL_88;
}
if (pbctrl_state != 8 && pbctrl_state != 42)
goto LABEL_77;
goto LABEL_58;
}
v2 = pbctrl_state;
if (pbctrl_state == 2 || pbctrl_state == 9)
goto LABEL_87;
v3 = pbctrl_state == 25;
}
LABEL_86:
if (v3)
{
LABEL_87:
v1 = v2 + 1;
goto LABEL_88;
}
LABEL_77:
pbctrl_state = 0;
return;
}
switch (key)
{
case 'T':
v2 = pbctrl_state;
if (pbctrl_state != 30)
{
if (pbctrl_state == 27 || pbctrl_state == 6)
goto LABEL_87;
v3 = pbctrl_state == 43;
goto LABEL_86;
}
pb::cheat_mode = 1;
break;
case 'U':
if (pbctrl_state == 41)
{
pbctrl_state = 42;
return;
}
goto LABEL_77;
case 'X':
if (pbctrl_state == 63)
{
table_add_extra_ball(2.0);
goto LABEL_76;
}
if (pbctrl_state != 83)
{
if (pbctrl_state == 103)
{
GravityWellKickoutControl(64, nullptr);
}
else
{
if (pbctrl_state != 123)
goto LABEL_77;
cheat_bump_rank();
}
LABEL_76:
TableG->CheatsUsed = 1;
goto LABEL_77;
}
table_unlimited_balls = 1;
break;
default:
goto LABEL_77;
}
TableG->CheatsUsed = 1;
goto LABEL_77;
"Hey, is that a screen saver?",
"I guess it has been a good week",
"She may already be a glue bottle",
"If you don't come in Saturday,\n...\n",
"don't even bother coming in Sunday.",
"Tomorrow already sucks",
"I knew it worked too good to be right.",
"World's most expensive flippers"
};
if (control_lite198_tag.Component->MessageField)
{
return;
}
std::memmove(&cheatBuffer[0], &cheatBuffer[1], 10);
cheatBuffer[10] = key;
if (strcmp(bufferEnd - 11, "HIDDEN TEST") == 0)
{
pb::cheat_mode ^= true;
}
else if (strcmp(bufferEnd - 4, "GMAX") == 0)
{
GravityWellKickoutControl(64, nullptr);
}
else if (strcmp(bufferEnd - 4, "1MAX") == 0)
{
table_add_extra_ball(2.0);
}
else if (strcmp(bufferEnd - 4, "BMAX") == 0)
{
table_unlimited_balls ^= true;
}
else if (strcmp(bufferEnd - 4, "RMAX") == 0)
{
cheat_bump_rank();
}
else if (pb::FullTiltMode && strcmp(bufferEnd - 5, "QUOTE") == 0)
{
// A sad developer easter egg type 'cheat' from Full Tilt
float time = 0;
for (auto quote : quotes)
control_mission_text_box_tag.Component->Display(quote, time += 3);
return;
}
else
{
return;
}
TableG->CheatsUsed = 1;
}
void control::table_add_extra_ball(float count)
@@ -902,9 +754,19 @@ void control::table_set_replay(float value)
control_info_text_box_tag.Component->Display(pinball::get_rc_string(0, 0), value);
}
int control::cheat_bump_rank()
void control::cheat_bump_rank()
{
return 0;
char Buffer[64]{};
auto rank = control_middle_circle_tag.Component->Message(37, 0.0);
if (rank < 9)
{
control_middle_circle_tag.Component->Message(41, 2.0f);
auto rankText = pinball::get_rc_string(RankRcArray[rank], 1);
snprintf(Buffer, sizeof Buffer, pinball::get_rc_string(83, 0), rankText);
control_mission_text_box_tag.Component->Display(Buffer, 8.0);
control_soundwave10_tag.Component->Play();
}
}
bool control::light_on(component_tag<TLight>* tag)
@@ -2329,7 +2191,7 @@ void control::PlungerControl(int code, TPinballComponent* caller)
}
else if (code == 1016)
{
table_unlimited_balls = 0;
table_unlimited_balls = false;
if (!control_middle_circle_tag.Component->Message(37, 0.0))
control_middle_circle_tag.Component->Message(32, 0.0);
if (!light_on(&control_lite200_tag))
@@ -2628,7 +2490,7 @@ void control::table_control_handler(int code)
{
if (code == 1011)
{
table_unlimited_balls = 0;
table_unlimited_balls = false;
control_lite77_tag.Component->Message(7, 0.0);
}
}

View File

@@ -65,14 +65,15 @@ public:
static TPinballTable* TableG;
static component_info score_components[88];
static component_tag_base* simple_components[142];
static int table_unlimited_balls, waiting_deployment_flag;
static int waiting_deployment_flag;
static bool table_unlimited_balls;
static int RankRcArray[9], MissionRcArray[17], mission_select_scores[17];
static component_tag_base *wormhole_tag_array1[3], *wormhole_tag_array2[3], *wormhole_tag_array3[3];
static void make_links(TPinballTable* table);
static TPinballComponent* make_component_link(component_tag_base* tag);
static void handler(int code, TPinballComponent* cmp);
static void pbctrl_bdoor_controller(int key);
static void pbctrl_bdoor_controller(char key);
static void table_add_extra_ball(float count);
static void table_set_bonus_hold();
static void table_set_bonus();
@@ -81,7 +82,7 @@ public:
static void table_set_multiball();
static void table_bump_ball_sink_lock();
static void table_set_replay(float value);
static int cheat_bump_rank();
static void cheat_bump_rank();
static bool light_on(component_tag<TLight>* tag);
static int SpecialAddScore(int score);
static int AddRankProgress(int rank);
@@ -182,6 +183,5 @@ public:
static void UnselectMissionController(int code, TPinballComponent* caller);
static void WaitingDeploymentController(int code, TPinballComponent* caller);
private:
static int pbctrl_state;
static int extraball_light_flag;
};

View File

@@ -28,8 +28,8 @@ const resolution_info fullscrn::resolution_array[3] =
};
float fullscrn::ScaleX = 1;
float fullscrn::ScaleY = 1;
float fullscrn::OffsetX = 0;
float fullscrn::OffsetY = 0;
int fullscrn::OffsetX = 0;
int fullscrn::OffsetY = 0;
void fullscrn::init(int width, int height, int isFullscreen, HWND winHandle, HMENU menuHandle, int changeDisplay)
{
@@ -450,13 +450,7 @@ void fullscrn::window_size_changed()
if (options::Options.UniformScaling)
{
ScaleY = ScaleX = min(ScaleX, ScaleY);
OffsetX = floor((client.right - res->TableWidth * ScaleX) / 2);
OffsetY = floor((client.bottom - res->TableHeight * ScaleY) / 2);
auto dc = GetDC(hWnd);
if (dc)
{
BitBlt(dc, 0, 0, client.right, client.bottom, dc, 0, 0, BLACKNESS);
ReleaseDC(hWnd, dc);
}
OffsetX = static_cast<int>(floor((client.right - res->TableWidth * ScaleX) / 2));
OffsetY = static_cast<int>(floor((client.bottom - res->TableHeight * ScaleY) / 2));
}
}

View File

@@ -30,8 +30,8 @@ public:
static const resolution_info resolution_array[3];
static float ScaleX;
static float ScaleY;
static float OffsetX;
static float OffsetY;
static int OffsetX;
static int OffsetY;
static void init(int width, int height, int isFullscreen, HWND winHandle, HMENU menuHandle, int changeDisplay);
static void shutdown();

View File

@@ -317,6 +317,25 @@ void gdrv::blit(gdrv_bitmap8* bmp, int xSrc, int ySrcOff, int xDest, int yDest,
void gdrv::blat(gdrv_bitmap8* bmp, int xDest, int yDest)
{
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);
RealizePalette(dc);
SetStretchBltMode(dc, stretchMode);

View File

@@ -99,7 +99,6 @@ int high_score::write(high_score_struct* table, int* ptrToSmth)
{
}
scoreSum += tablePtr->Score;
++position;
++tablePtr;
}
scramble_number_string(scoreSum, buf);

View File

@@ -135,6 +135,8 @@ int loader::get_sound_id(int groupIndex)
if (!sound_list[soundIndex].Loaded && !sound_list[soundIndex].WavePtr)
{
WaveHeader wavHeader{};
int soundGroupId = sound_list[soundIndex].GroupIndex;
sound_list[soundIndex].Duration = 0.0;
if (soundGroupId > 0 && !pinball::quickFlag)
@@ -150,9 +152,10 @@ int loader::get_sound_id(int groupIndex)
pinball::make_path_name(filePath, fileName2);
HFILE hFile = _lopen(filePath, 0);
sound_list[soundIndex].Duration = static_cast<float>(static_cast<double>(_llseek(hFile, 0, SEEK_END)) *
0.0000909090909090909);
_lread(hFile, &wavHeader, sizeof wavHeader);
_lclose(hFile);
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);
}
}

View File

@@ -48,6 +48,40 @@ struct visualStruct
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
{

View File

@@ -6,7 +6,7 @@
#include "pinball.h"
tagMCI_OPEN_PARMSA midi::mci_open_info;
char midi::midi_device_type[28];
char midi::midi_file_name[28];
HWND midi::midi_notify_hwnd;
int midi::midi_seq1_open, midi::midi_seq1_playing;
@@ -53,10 +53,10 @@ int midi::music_init(HWND hwnd)
mci_open_info.wDeviceID = 0;
midi_notify_hwnd = hwnd;
lstrcpyA(midi_device_type, pinball::get_rc_string(156, 0));
mci_open_info.lpstrElementName = nullptr;
mci_open_info.lpstrDeviceType = midi_device_type;
auto result = mciSendCommandA(0, MCI_OPEN, MCI_OPEN_TYPE | MCI_NOTIFY_SUPERSEDED, (DWORD_PTR)&mci_open_info);
lstrcpyA(midi_file_name, pinball::get_rc_string(156, 0));
mci_open_info.lpstrElementName = midi_file_name;
mci_open_info.lpstrDeviceType = nullptr;
auto result = mciSendCommandA(0, MCI_OPEN, MCI_OPEN_ELEMENT | MCI_NOTIFY_SUPERSEDED, (DWORD_PTR)&mci_open_info);
midi_seq1_open = result == 0;
return midi_seq1_open;
}

View File

@@ -59,7 +59,7 @@ public:
static void music_shutdown();
private:
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 int midi_seq1_open, midi_seq1_playing;

View File

@@ -108,6 +108,8 @@ void options::init(HMENU menuHandle)
Options.RightTableBumpKey = get_int(nullptr, "Right Table Bump key", Options.RightTableBumpKey);
Options.BottomTableBumpKey = get_int(nullptr, "Bottom Table Bump key", Options.BottomTableBumpKey);
Options.UniformScaling = get_int(nullptr, "Uniform scaling", true);
Options.AlternativeRender = get_int(nullptr, "Alternative Render", false);
menu_check(Menu1_Sounds, Options.Sounds);
Sound::Enable(0, 7, Options.Sounds);
menu_check(Menu1_Music, Options.Music);
@@ -117,6 +119,7 @@ void options::init(HMENU menuHandle)
menu_check(Menu1_3Players, Options.Players == 3);
menu_check(Menu1_4Players, Options.Players == 4);
menu_check(Menu1_WindowUniformScale, Options.UniformScaling);
menu_check(Menu1_AlternativeRender, Options.AlternativeRender);
auto tmpBuf = memory::allocate(0x1F4u);
if (tmpBuf)
{
@@ -149,6 +152,7 @@ void options::uninit()
set_int(nullptr, "Bottom Table Bump key", Options.BottomTableBumpKey);
set_int(nullptr, "Screen Resolution", Options.Resolution);
set_int(nullptr, "Uniform scaling", Options.UniformScaling);
set_int(nullptr, "Alternative Render", Options.AlternativeRender);
}
void options::path_init(LPCSTR regPath)
@@ -343,6 +347,12 @@ void options::toggle(UINT uIDCheckItem)
fullscrn::window_size_changed();
fullscrn::paint();
break;
case Menu1_AlternativeRender:
Options.AlternativeRender ^= true;
menu_check(Menu1_AlternativeRender, Options.AlternativeRender);
fullscrn::window_size_changed();
fullscrn::paint();
break;
default:
break;
}

View File

@@ -23,6 +23,7 @@ struct optionsStruct
int BottomTableBumpKeyDft;
int Resolution;
bool UniformScaling;
bool AlternativeRender;
};

View File

@@ -26,10 +26,10 @@
TPinballTable* pb::MainTable = 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;
high_score_struct pb::highscore_table[5];
bool pb::FullTiltMode = false;
bool pb::FullTiltMode = false, pb::cheat_mode = false;
int pb::init()
@@ -129,9 +129,7 @@ void pb::reset_table()
void pb::firsttime_setup()
{
render::blit = 0;
render::update();
render::blit = 1;
render::update(false);
}
void pb::paint()
@@ -223,6 +221,8 @@ void pb::ballset(int x, int y)
int pb::frame(int time)
{
static int frameTime = 0;
if (time > 100)
time = 100;
float timeMul = time * 0.001f;
@@ -244,7 +244,29 @@ int pb::frame(int time)
nudge::nudge_count = nudgeDec;
}
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);
if (!MainTable->TiltLockFlag)
{
@@ -288,8 +310,8 @@ void pb::timed_frame(float timeNow, float timeDelta, bool drawBalls)
ball->Acceleration.Y = ball->Speed * ball->Acceleration.Y;
maths::vector_add(&ball->Acceleration, &vec2);
ball->Speed = maths::normalize_2d(&ball->Acceleration);
ball->InvAcceleration.X = ball->Acceleration.X == 0.0f ? 1000000000.0f : 1.0f / ball->Acceleration.X;
ball->InvAcceleration.Y = ball->Acceleration.Y == 0.0f ? 1000000000.0f : 1.0f / ball->Acceleration.Y;
ball->InvAcceleration.X = ball->Acceleration.X == 0.0f ? 1.0e9f : 1.0f / ball->Acceleration.X;
ball->InvAcceleration.Y = ball->Acceleration.Y == 0.0f ? 1.0e9f : 1.0f / ball->Acceleration.Y;
}
auto timeDelta2 = timeDelta;
@@ -404,7 +426,7 @@ void pb::keydown(int key)
mode_countdown(-1);
return;
}
control::pbctrl_bdoor_controller(key);
control::pbctrl_bdoor_controller(static_cast<char>(key));
if (key == options::Options.LeftFlipperKey)
{
MainTable->Message(1000, time_now);

View File

@@ -10,7 +10,8 @@ class pb
public:
static int time_ticks;
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 TPinballTable* MainTable;
static high_score_struct highscore_table[5];

View File

@@ -2,7 +2,6 @@
#include "render.h"
#include "memory.h"
int render::blit = 0;
int render::many_dirty, render::many_sprites, render::many_balls;
render_sprite_type_struct **render::dirty_list, **render::sprite_list, **render::ball_list;
zmap_header_type* render::background_zmap;
@@ -60,83 +59,69 @@ void render::uninit()
many_balls = 0;
}
void render::update()
void render::update(bool blit)
{
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)
{
auto sprite = *dirtyPtr;
if ((*dirtyPtr)->DirtyRect.Width > 0 && (sprite->VisualType == VisualType::None || sprite->VisualType ==
VisualType::Sprite))
repaint(*dirtyPtr);
++dirtyPtr;
auto curSprite = dirty_list[index];
bool clearSprite = false;
switch (curSprite->VisualType)
{
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)
{
paint_balls();
gdrv::start_blit_sequence();
auto xPos = vscreen.XPosition + offset_x;
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 dirtyRect = &(*dirtyPtr)->DirtyRect;
auto width2 = (*dirtyPtr)->DirtyRect.Width;
auto sprite = dirty_list[index];
auto dirtyRect = &sprite->DirtyRect;
auto width2 = sprite->DirtyRect.Width;
if (width2 > 0)
gdrv::blit_sequence(
&vscreen,
@@ -147,21 +132,16 @@ void render::update()
width2,
dirtyRect->Height);
auto rect = &sprite->BmpRectCopy;
rect->XPosition = dirtyRect->XPosition;
rect->YPosition = dirtyRect->YPosition;
rect->Width = dirtyRect->Width;
rect->Height = dirtyRect->Height;
sprite->BmpRectCopy = *dirtyRect;
if (sprite->UnknownFlag != 0)
remove_sprite(sprite);
}
dirtyPtr = ball_list;
for (int index = 0; index < many_balls; ++dirtyPtr, ++index)
for (int index = 0; index < many_balls; ++index)
{
auto rectCopy = &(*dirtyPtr)->BmpRectCopy;
auto dirtyRect = &(*dirtyPtr)->DirtyRect;
auto sprite = ball_list[index];
auto rectCopy = &sprite->BmpRectCopy;
auto dirtyRect = &sprite->DirtyRect;
if (maths::overlapping_box(dirtyRect, rectCopy, &overlapRect) && dirtyRect->Width > 0)
{
if (overlapRect.Width > 0)
@@ -198,13 +178,22 @@ void render::update()
}
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;
unpaint_balls();
}
void render::paint()
{
paint_balls();
@@ -473,7 +462,7 @@ void render::paint_balls()
void render::unpaint_balls()
{
for (int index = many_balls-1; index >= 0; index--)
for (int index = many_balls - 1; index >= 0; index--)
{
auto curBall = ball_list[index];
if (curBall->DirtyRect.Width > 0)

View File

@@ -31,7 +31,6 @@ struct render_sprite_type_struct
class render
{
public:
static int blit;
static int many_dirty, many_sprites, many_balls;
static render_sprite_type_struct **dirty_list, **sprite_list, **ball_list;
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 uninit();
static void update();
static void update(bool blit);
static void paint();
static void sprite_modified(render_sprite_type_struct* sprite);
static render_sprite_type_struct* create_sprite(VisualType visualType, gdrv_bitmap8* bmp,

View File

@@ -240,6 +240,7 @@
#define DLG_HIGHSCORES_EditName3 603
#define DLG_HIGHSCORES_EditName4 604
#define DLG_HIGHSCORES_EditName5 605
#define Menu1_AlternativeRender 601
// Next default values for new objects
//

View File

@@ -220,7 +220,16 @@ int winmain::WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
if (prevTime)
{
char buf[60];
sprintf_s(buf, "Frames/sec = %02.02f", 300.0f / (static_cast<float>(curTime - prevTime) * 0.001f));
auto dt = static_cast<float>(curTime - prevTime) * 0.001f;
if (!options::Options.AlternativeRender)
sprintf_s(buf, "Frames/sec = %02.02f", 300.0f / dt);
else
{
sprintf_s(buf, "Updates/sec = %02.02f Frames/sec = %02.02f",
300.0f / dt, pb::frameCounter / dt);
pb::frameCounter = 0;
}
SetWindowTextA(hwnd_frame, buf);
if (DispGRhistory)
@@ -610,6 +619,7 @@ LRESULT CALLBACK winmain::message_handler(HWND hWnd, UINT Msg, WPARAM wParam, LP
case Menu1_800x600:
case Menu1_1024x768:
case Menu1_WindowUniformScale:
case Menu1_AlternativeRender:
options::toggle(wParamI);
break;
case Menu1_Help_Topics:
@@ -790,10 +800,11 @@ HDC winmain::_GetDC(HWND hWnd)
int winmain::a_dialog(HINSTANCE hInstance, HWND hWnd)
{
char appName[100];
char szOtherStuff[100];
char szOtherStuff[130];
lstrcpyA(appName, pinball::get_rc_string(38, 0));
lstrcpyA(szOtherStuff, pinball::get_rc_string(102, 0));
strcat_s(szOtherStuff, " Decompilation version 1.1.2");
auto icon = LoadIconA(hInstance, "ICON_1");
return ShellAboutA(hWnd, appName, szOtherStuff, icon);
}