@ -4,15 +4,26 @@
using namespace olc ;
class PGEX_SMX : public PGEX {
public :
PGEX_SMX ( ) : PGEX ( true ) { } ;
PGEX_SMX ( ) : PGEX ( true ) {
} ;
//UP is 0x2
//RIGHT is 0x20
//DOWN is 0x80
//LEFT is 0x08
//Add these bytes together to get the combination (all 4 held down is 0xAA
HWButton GetPanel ( Key k , int pad ) const {
std : : cout < < SMX_GetInputState ( pad ) ;
return panelState [ k - UP ] ;
} ;
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.
//SMX "screen" is 12x21
//Each panel is 4x7
static void SMXStateChangedCallback ( int pad , SMXUpdateCallbackReason reason , void * pUser )
@ -23,20 +34,64 @@ private:
static void SMXLogCallback ( const char * log )
{
printf ( " -> %s \n " , log ) ;
if ( logMessages ) {
printf ( " -> %s \n " , log ) ;
}
}
//The key enums are UP, DOWN, LEFT, RIGHT.
void SMXStateChanged ( int pad , SMXUpdateCallbackReason reason )
{
printf ( " Device %i state changed: %04x \n " , pad , SMX_GetInputState ( pad ) ) ;
if ( logMessages ) {
printf ( " Device %i state changed: %04x \n " , pad , SMX_GetInputState ( pad ) ) ;
}
int16_t state ( SMX_GetInputState ( pad ) ) ;
if ( state & 0x2 & & ! internal_panelState [ UP - UP ] . bPressed ) {
internal_panelState [ UP - UP ] = { true , false , true } ;
} else
if ( ! ( state & 0x2 ) & & ! internal_panelState [ UP - UP ] . bReleased ) {
internal_panelState [ UP - UP ] = { false , true , false } ;
}
if ( state & 0x20 & & ! internal_panelState [ RIGHT - UP ] . bPressed ) {
internal_panelState [ RIGHT - UP ] = { true , false , true } ;
} else
if ( ! ( state & 0x20 ) & & ! internal_panelState [ RIGHT - UP ] . bReleased ) {
internal_panelState [ RIGHT - UP ] = { false , true , false } ;
}
if ( state & 0x80 & & ! internal_panelState [ DOWN - UP ] . bPressed ) {
internal_panelState [ DOWN - UP ] = { true , false , true } ;
} else
if ( ! ( state & 0x80 ) & & ! internal_panelState [ DOWN - UP ] . bReleased ) {
internal_panelState [ DOWN - UP ] = { false , true , false } ;
}
if ( state & 0x8 & & ! internal_panelState [ LEFT - UP ] . bPressed ) {
internal_panelState [ LEFT - UP ] = { true , false , true } ;
} else
if ( ! ( state & 0x8 ) & & ! internal_panelState [ LEFT - UP ] . bReleased ) {
internal_panelState [ LEFT - UP ] = { false , true , false } ;
}
}
virtual void OnAfterUserCreate ( ) override {
SMX_Start ( SMXStateChangedCallback , this ) ;
} ;
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 i = 0 ; i < 4 ; i + + ) {
panelState [ i ] = internal_panelState [ i ] ;
internal_panelState [ i ] . bPressed = false ;
internal_panelState [ i ] . bReleased = false ;
}
return true ;
}
virtual void OnAfterUserUpdate ( float fElapsedTime ) override {
for ( int i = 0 ; i < 4 ; i + + ) {
panelState [ i ] . bPressed = false ;
panelState [ i ] . 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.
//Both pads receive data sequentially, and for now we can mimic the data on both ends.
@ -79,3 +134,5 @@ private:
SMX_SetLights2 ( lightData . data ( ) , lightData . size ( ) ) ;
}
} ;
bool PGEX_SMX : : logMessages = false ;