Fix up SMX PGEX to remove timing desync bugs and add second pad compatibility.
This commit is contained in:
parent
ecba99cd7e
commit
04636be072
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
#include "olcPixelGameEngine.h"
|
||||
#include "SMX.h"
|
||||
#include <assert.h>
|
||||
|
||||
using namespace olc;
|
||||
|
||||
@ -15,15 +16,17 @@ public:
|
||||
//LEFT is 0x08
|
||||
//Add these bytes together to get the combination (all 4 held down is 0xAA
|
||||
HWButton GetPanel(Key k,int pad=0)const{
|
||||
return panelState[k-UP];
|
||||
return panelState[k-UP][pad];
|
||||
};
|
||||
void EnableLogMessages(bool enabled){
|
||||
logMessages=enabled;
|
||||
}
|
||||
private:
|
||||
static bool logMessages;
|
||||
HWButton internal_panelState[4];
|
||||
HWButton panelState[4]; //We store the 4 main panel states, similar to how PGE does.
|
||||
HWButton internal_panelState[4][2];
|
||||
HWButton panelState[4][2]; //We store the 4 main panel states, similar to how PGE does.
|
||||
double totalElapsedTime{0.};
|
||||
double nextLightUpdate{0.};
|
||||
//SMX "screen" is 12x21
|
||||
//Each panel is 4x7
|
||||
static void SMXStateChangedCallback(int pad, SMXUpdateCallbackReason reason, void *pUser)
|
||||
@ -44,31 +47,57 @@ private:
|
||||
{
|
||||
if(logMessages){
|
||||
printf("Device %i state changed: %04x\n", pad, SMX_GetInputState(pad));
|
||||
printf("Device %i state changed: %04x\n", 1, SMX_GetInputState(1));
|
||||
}
|
||||
int16_t state(SMX_GetInputState(pad));
|
||||
if(state&0x2&&!internal_panelState[UP-UP].bPressed){
|
||||
internal_panelState[UP-UP]={true,false,true};
|
||||
int16_t state(SMX_GetInputState(0));
|
||||
if(state&0x2&&!internal_panelState[UP-UP][0].bPressed){
|
||||
internal_panelState[UP-UP][0]={true,false,true};
|
||||
}else
|
||||
if(!(state&0x2)&&!internal_panelState[UP-UP].bReleased){
|
||||
internal_panelState[UP-UP]={false,true,false};
|
||||
if(!(state&0x2)&&!internal_panelState[UP-UP][0].bReleased){
|
||||
internal_panelState[UP-UP][0]={false,true,false};
|
||||
}
|
||||
if(state&0x20&&!internal_panelState[RIGHT-UP].bPressed){
|
||||
internal_panelState[RIGHT-UP]={true,false,true};
|
||||
if(state&0x20&&!internal_panelState[RIGHT-UP][0].bPressed){
|
||||
internal_panelState[RIGHT-UP][0]={true,false,true};
|
||||
}else
|
||||
if(!(state&0x20)&&!internal_panelState[RIGHT-UP].bReleased){
|
||||
internal_panelState[RIGHT-UP]={false,true,false};
|
||||
if(!(state&0x20)&&!internal_panelState[RIGHT-UP][0].bReleased){
|
||||
internal_panelState[RIGHT-UP][0]={false,true,false};
|
||||
}
|
||||
if(state&0x80&&!internal_panelState[DOWN-UP].bPressed){
|
||||
internal_panelState[DOWN-UP]={true,false,true};
|
||||
if(state&0x80&&!internal_panelState[DOWN-UP][0].bPressed){
|
||||
internal_panelState[DOWN-UP][0]={true,false,true};
|
||||
}else
|
||||
if(!(state&0x80)&&!internal_panelState[DOWN-UP].bReleased){
|
||||
internal_panelState[DOWN-UP]={false,true,false};
|
||||
if(!(state&0x80)&&!internal_panelState[DOWN-UP][0].bReleased){
|
||||
internal_panelState[DOWN-UP][0]={false,true,false};
|
||||
}
|
||||
if(state&0x8&&!internal_panelState[LEFT-UP].bPressed){
|
||||
internal_panelState[LEFT-UP]={true,false,true};
|
||||
if(state&0x8&&!internal_panelState[LEFT-UP][0].bPressed){
|
||||
internal_panelState[LEFT-UP][0]={true,false,true};
|
||||
}else
|
||||
if(!(state&0x8)&&!internal_panelState[LEFT-UP].bReleased){
|
||||
internal_panelState[LEFT-UP]={false,true,false};
|
||||
if(!(state&0x8)&&!internal_panelState[LEFT-UP][0].bReleased){
|
||||
internal_panelState[LEFT-UP][0]={false,true,false};
|
||||
}
|
||||
state=SMX_GetInputState(1);
|
||||
if(state&0x2&&!internal_panelState[UP-UP][1].bPressed){
|
||||
internal_panelState[UP-UP][1]={true,false,true};
|
||||
}else
|
||||
if(!(state&0x2)&&!internal_panelState[UP-UP][1].bReleased){
|
||||
internal_panelState[UP-UP][1]={false,true,false};
|
||||
}
|
||||
if(state&0x20&&!internal_panelState[RIGHT-UP][1].bPressed){
|
||||
internal_panelState[RIGHT-UP][1]={true,false,true};
|
||||
}else
|
||||
if(!(state&0x20)&&!internal_panelState[RIGHT-UP][1].bReleased){
|
||||
internal_panelState[RIGHT-UP][1]={false,true,false};
|
||||
}
|
||||
if(state&0x80&&!internal_panelState[DOWN-UP][1].bPressed){
|
||||
internal_panelState[DOWN-UP][1]={true,false,true};
|
||||
}else
|
||||
if(!(state&0x80)&&!internal_panelState[DOWN-UP][1].bReleased){
|
||||
internal_panelState[DOWN-UP][1]={false,true,false};
|
||||
}
|
||||
if(state&0x8&&!internal_panelState[LEFT-UP][1].bPressed){
|
||||
internal_panelState[LEFT-UP][1]={true,false,true};
|
||||
}else
|
||||
if(!(state&0x8)&&!internal_panelState[LEFT-UP][1].bReleased){
|
||||
internal_panelState[LEFT-UP][1]={false,true,false};
|
||||
}
|
||||
}
|
||||
|
||||
@ -79,18 +108,29 @@ private:
|
||||
virtual bool OnBeforeUserUpdate(float& fElapsedTime){
|
||||
//We don't want the panel states changing in the middle of a frame, since the input polling is on a separate thread.
|
||||
//Copy over the internal button states to the current panel state.
|
||||
for(int pad=0;pad<2;pad++){
|
||||
for(int i=0;i<4;i++){
|
||||
panelState[i]=internal_panelState[i];
|
||||
internal_panelState[i].bPressed=false;
|
||||
internal_panelState[i].bReleased=false;
|
||||
panelState[i][pad]=internal_panelState[i][pad];
|
||||
internal_panelState[i][pad].bPressed=false;
|
||||
internal_panelState[i][pad].bReleased=false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void OnAfterUserUpdate(float fElapsedTime)override{
|
||||
double previousTotalElapsedTime{totalElapsedTime};
|
||||
totalElapsedTime=fmod(totalElapsedTime+fElapsedTime,10000.);
|
||||
if(previousTotalElapsedTime>totalElapsedTime){
|
||||
//We are in the past, so reset lastLightUpdate to keep lights running.
|
||||
nextLightUpdate=totalElapsedTime;
|
||||
}
|
||||
if(nextLightUpdate>totalElapsedTime)return; //Ignore light updates if not enough time has passed. We can only send light updates at 30 FPS.
|
||||
for(int pad=0;pad<2;pad++){
|
||||
for(int i=0;i<4;i++){
|
||||
panelState[i].bPressed=false;
|
||||
panelState[i].bReleased=false;
|
||||
panelState[i][pad].bPressed=false;
|
||||
panelState[i][pad].bReleased=false;
|
||||
}
|
||||
}
|
||||
std::string lightData;
|
||||
//The light data for an SMX dance pad is outlined in the docs but the code used to transform the PGE's pixels to SMX pad's lights will be annotated here.
|
||||
@ -105,7 +145,7 @@ private:
|
||||
col++;
|
||||
continue;
|
||||
}
|
||||
Pixel p(pge->GetDrawTarget()->GetPixel(x,y));
|
||||
Pixel p(pge->GetDrawTarget()->GetPixel(x+12*pad,y));
|
||||
lightData.append(1,p.r);
|
||||
lightData.append(1,p.g);
|
||||
lightData.append(1,p.b);
|
||||
@ -121,7 +161,7 @@ private:
|
||||
col++;
|
||||
continue;
|
||||
}
|
||||
Pixel p(pge->GetDrawTarget()->GetPixel(x,y));
|
||||
Pixel p(pge->GetDrawTarget()->GetPixel(x+12*pad,y));
|
||||
lightData.append(1,p.r);
|
||||
lightData.append(1,p.g);
|
||||
lightData.append(1,p.b);
|
||||
@ -131,6 +171,8 @@ private:
|
||||
}
|
||||
}
|
||||
}
|
||||
if(lightData.size()!=1350)throw;
|
||||
nextLightUpdate=totalElapsedTime+1/30.f;
|
||||
SMX_SetLights2( lightData.data(), lightData.size() );
|
||||
}
|
||||
};
|
||||
|
@ -1,12 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<configSections>
|
||||
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
|
||||
<section name="smx_config.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
|
||||
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<section name="smx_config.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false"/>
|
||||
</sectionGroup>
|
||||
</configSections>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/>
|
||||
</startup>
|
||||
<userSettings>
|
||||
<smx_config.Properties.Settings>
|
||||
@ -14,7 +14,7 @@
|
||||
<value>False</value>
|
||||
</setting>
|
||||
<setting name="CustomSensors" serializeAs="String">
|
||||
<value />
|
||||
<value/>
|
||||
</setting>
|
||||
<setting name="UseInnerSensorThresholds" serializeAs="String">
|
||||
<value>False</value>
|
||||
|
2
smx-config/Properties/Resources.Designer.cs
generated
2
smx-config/Properties/Resources.Designer.cs
generated
@ -19,7 +19,7 @@ namespace smx_config.Properties {
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources {
|
||||
|
2
smx-config/Properties/Settings.Designer.cs
generated
2
smx-config/Properties/Settings.Designer.cs
generated
@ -12,7 +12,7 @@ namespace smx_config.Properties {
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.9.0.0")]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.11.0.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
|
@ -9,7 +9,7 @@
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>smx_config</RootNamespace>
|
||||
<AssemblyName>SMXConfig</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
@ -29,6 +29,7 @@
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
|
Loading…
x
Reference in New Issue
Block a user