Skip to content

Commit

Permalink
Cocoa Port: Do some refactoring on reading the client-side inputs.
Browse files Browse the repository at this point in the history
- Also make calculating the mic level average more efficient, as well
as updating the mic level average every 8th frame instead of every
frame.
  • Loading branch information
rogerman committed Sep 1, 2017
1 parent b4650e4 commit a86539e
Show file tree
Hide file tree
Showing 9 changed files with 402 additions and 211 deletions.
21 changes: 17 additions & 4 deletions desmume/src/addons/slot2_guitarGrip.cpp
Expand Up @@ -32,14 +32,17 @@ class Slot2_GuitarGrip : public ISlot2Interface

virtual void connect()
{
guitarKeyStatus = 0;
guitarKeyStatus = 0xFF;
}

virtual u8 readByte(u8 PROCNUM, u32 addr)
{
if (addr == 0x0A000000) return (~guitarKeyStatus);
return (addr & 1)?0xF9:0xFF;
if (addr == 0x0A000000)
return guitarKeyStatus;

return (addr & 1) ? 0xF9 : 0xFF;
}

virtual u16 readWord(u8 PROCNUM, u32 addr) { return 0xF9FF; }
virtual u32 readLong(u8 PROCNUM, u32 addr) { return 0xF9FFF9FF; }
};
Expand All @@ -48,5 +51,15 @@ ISlot2Interface* construct_Slot2_GuitarGrip() { return new Slot2_GuitarGrip(); }

void guitarGrip_setKey(bool green, bool red, bool yellow, bool blue)
{
guitarKeyStatus = 0 | (green << 6) | (red << 5) | (yellow << 4) | (blue << 3);
const u8 g = (green) ? (1 << 6) : 0;
const u8 r = (red) ? (1 << 5) : 0;
const u8 y = (yellow) ? (1 << 4) : 0;
const u8 b = (blue) ? (1 << 3) : 0;

guitarKeyStatus = ~(g | r | y | b);
}

void guitarGrip_setKey(u8 theKeys)
{
guitarKeyStatus = theKeys;
}
19 changes: 12 additions & 7 deletions desmume/src/addons/slot2_piano.cpp
Expand Up @@ -17,7 +17,7 @@

#include "../slot2.h"

static u16 pianoKeyStatus = 0;
static u16 pianoKeyStatus = 0;

class Slot2_EasyPiano : public ISlot2Interface
{
Expand All @@ -30,7 +30,7 @@ class Slot2_EasyPiano : public ISlot2Interface

virtual void connect()
{
pianoKeyStatus = 0;
pianoKeyStatus = 0xE7FF;
}

virtual u8 readByte(u8 PROCNUM, u32 addr)
Expand Down Expand Up @@ -61,10 +61,10 @@ class Slot2_EasyPiano : public ISlot2Interface

//LOG("PIANO: %04X\n",pianoKeyStatus);

if(addr == 0x09FFFFFE) return (~(pianoKeyStatus&0xFF));
if(addr == 0x09FFFFFF) return (~((pianoKeyStatus>>8)&0xFF))&~(0x18);
if (addr == 0x09FFFFFE) return ((pianoKeyStatus >> 0) & 0xFF);
if (addr == 0x09FFFFFF) return ((pianoKeyStatus >> 8) & 0xFF) & ~(0x18);

return (addr & 1)?0xE7:0xFF;
return (addr & 1) ? 0xE7 : 0xFF;
}
virtual u16 readWord(u8 PROCNUM, u32 addr)
{
Expand Down Expand Up @@ -99,7 +99,7 @@ void piano_setKey(bool c, bool cs, bool d, bool ds, bool e, bool f, bool fs, boo
//0x09FFFFFF:7 = ?

#define BIT_P(N,v) ((v)?(1<<(N)):0)
pianoKeyStatus =
pianoKeyStatus = ~(
BIT_P(0,c) |
BIT_P(1,cs) |
BIT_P(2,d) |
Expand All @@ -113,5 +113,10 @@ void piano_setKey(bool c, bool cs, bool d, bool ds, bool e, bool f, bool fs, boo
BIT_P(10,as) |
BIT_P(13,b) |
BIT_P(14,hic)
;
);
}

void piano_setKey(u16 theKeys)
{
pianoKeyStatus = theKeys;
}
25 changes: 24 additions & 1 deletion desmume/src/frontend/cocoa/ClientExecutionControl.cpp
Expand Up @@ -849,7 +849,30 @@ void ClientExecutionControl::FetchOutputPostNDSExec()
rtcGetTimeAsString(tempBuffer);
this->_ndsFrameInfo.rtcString = tempBuffer;
free(tempBuffer);


const UserInput &ndsInput = NDS_getFinalUserInput();

this->_ndsFrameInfo.inputState.value = 0xFFFFFFFFFFFFFFFFUL;
this->_ndsFrameInfo.inputState.A = (ndsInput.buttons.A) ? 0 : 1;
this->_ndsFrameInfo.inputState.B = (ndsInput.buttons.B) ? 0 : 1;
this->_ndsFrameInfo.inputState.Select = (ndsInput.buttons.T) ? 0 : 1;
this->_ndsFrameInfo.inputState.Start = (ndsInput.buttons.S) ? 0 : 1;
this->_ndsFrameInfo.inputState.Right = (ndsInput.buttons.R) ? 0 : 1;
this->_ndsFrameInfo.inputState.Left = (ndsInput.buttons.L) ? 0 : 1;
this->_ndsFrameInfo.inputState.Up = (ndsInput.buttons.U) ? 0 : 1;
this->_ndsFrameInfo.inputState.Down = (ndsInput.buttons.D) ? 0 : 1;
this->_ndsFrameInfo.inputState.R = (ndsInput.buttons.E) ? 0 : 1;
this->_ndsFrameInfo.inputState.L = (ndsInput.buttons.W) ? 0 : 1;
this->_ndsFrameInfo.inputState.X = (ndsInput.buttons.X) ? 0 : 1;
this->_ndsFrameInfo.inputState.Y = (ndsInput.buttons.Y) ? 0 : 1;
this->_ndsFrameInfo.inputState.Debug = (ndsInput.buttons.G) ? 0 : 1;
this->_ndsFrameInfo.inputState.Touch = (ndsInput.touch.isTouch) ? 0 : 1;
this->_ndsFrameInfo.inputState.Lid = (ndsInput.buttons.F) ? 0 : 1;
this->_ndsFrameInfo.inputState.Microphone = (ndsInput.mic.micButtonPressed != 0) ? 0 : 1;

this->_ndsFrameInfo.touchLocX = ndsInput.touch.touchX;
this->_ndsFrameInfo.touchLocY = ndsInput.touch.touchY;

pthread_mutex_unlock(&this->_mutexOutputPostNDSExec);
}

Expand Down
182 changes: 179 additions & 3 deletions desmume/src/frontend/cocoa/ClientExecutionControl.h
Expand Up @@ -60,7 +60,174 @@ enum CPUEmulationEngineID
CPUEmulationEngineID_DynamicRecompiler = 1
};

typedef struct ClientExecutionControlSettings
enum NDSInputID
{
NDSInputID_A = 0,
NDSInputID_B,
NDSInputID_Select,
NDSInputID_Start,
NDSInputID_Right,
NDSInputID_Left,
NDSInputID_Up,
NDSInputID_Down,
NDSInputID_R,
NDSInputID_L,

NDSInputID_X,
NDSInputID_Y,
NDSInputID_Debug,
NDSInputID_Touch,
NDSInputID_Lid,

NDSInputID_Microphone,

NDSInputID_GuitarGrip_Green,
NDSInputID_GuitarGrip_Red,
NDSInputID_GuitarGrip_Yellow,
NDSInputID_GuitarGrip_Blue,

NDSInputID_Piano_C,
NDSInputID_Piano_CSharp,
NDSInputID_Piano_D,
NDSInputID_Piano_DSharp,
NDSInputID_Piano_E,
NDSInputID_Piano_F,
NDSInputID_Piano_FSharp,
NDSInputID_Piano_G,
NDSInputID_Piano_GSharp,
NDSInputID_Piano_A,
NDSInputID_Piano_ASharp,
NDSInputID_Piano_B,
NDSInputID_Piano_HighC,

NDSInputID_Paddle,

NDSInputID_InputCount
};

typedef union
{
uint64_t value;

struct
{
uint16_t gbaKeys;
uint8_t ndsKeysExt;
uint8_t guitarGripKeys;
uint16_t easyPianoKeys;
uint8_t miscKeys;
uint8_t unused;
};

struct
{
#ifndef MSB_FIRST
uint8_t A:1;
uint8_t B:1;
uint8_t Select:1;
uint8_t Start:1;
uint8_t Right:1;
uint8_t Left:1;
uint8_t Up:1;
uint8_t Down:1;

uint8_t R:1;
uint8_t L:1;
uint8_t :6;

uint8_t X:1;
uint8_t Y:1;
uint8_t :1;
uint8_t Debug:1;
uint8_t :2;
uint8_t Touch:1;
uint8_t Lid:1;

uint8_t :3;
uint8_t GuitarGripBlue:1;
uint8_t GuitarGripYellow:1;
uint8_t GuitarGripRed:1;
uint8_t GuitarGripGreen:1;
uint8_t :1;

uint8_t PianoC:1;
uint8_t PianoCSharp:1;
uint8_t PianoD:1;
uint8_t PianoDSharp:1;
uint8_t PianoE:1;
uint8_t PianoF:1;
uint8_t PianoFSharp:1;
uint8_t PianoG:1;

uint8_t PianoGSharp:1;
uint8_t PianoA:1;
uint8_t PianoASharp:1;
uint8_t :2;
uint8_t PianoB:1;
uint8_t PianoHighC:1;
uint8_t :1;

uint8_t Paddle:1;
uint8_t Microphone:1;
uint8_t :6;

uint8_t :8;
#else
uint8_t Down:1;
uint8_t Up:1;
uint8_t Left:1;
uint8_t Right:1;
uint8_t Start:1;
uint8_t Select:1;
uint8_t B:1;
uint8_t A:1;

uint8_t :6
uint8_t L:1;
uint8_t R:1;

uint8_t Lid:1;
uint8_t Touch:1;
uint8_t :2;
uint8_t Debug:1;
uint8_t :1;
uint8_t Y:1;
uint8_t X:1;

uint8_t :1;
uint8_t GuitarGripGreen:1;
uint8_t GuitarGripRed:1;
uint8_t GuitarGripYellow:1;
uint8_t GuitarGripBlue:1;
uint8_t :3;

uint8_t PianoG:1;
uint8_t PianoFSharp:1;
uint8_t PianoF:1;
uint8_t PianoE:1;
uint8_t PianoDSharp:1;
uint8_t PianoD:1;
uint8_t PianoCSharp:1;
uint8_t PianoC:1;

uint8_t :1;
uint8_t PianoHighC:1;
uint8_t PianoB:1;
uint8_t :2;
uint8_t PianoASharp:1;
uint8_t PianoA:1;
uint8_t PianoGSharp:1;

uint8_t :6;
uint8_t Microphone:1;
uint8_t Paddle:1;

uint8_t :8;
#endif
};
} NDSInputState; // Each bit represents the Pressed/Released state of a single input. Pressed=0, Released=1

struct ClientExecutionControlSettings
{
CPUEmulationEngineID cpuEngineID;
uint8_t JITMaxBlockSize;
Expand Down Expand Up @@ -94,8 +261,7 @@ typedef struct ClientExecutionControlSettings

ExecutionBehavior execBehavior;
FrameJumpBehavior jumpBehavior;

} ClientExecutionControlSettings;
};

struct NDSFrameInfo
{
Expand All @@ -109,6 +275,10 @@ struct NDSFrameInfo
uint32_t cpuLoadAvgARM9;
uint32_t cpuLoadAvgARM7;

NDSInputState inputState;
uint16_t touchLocX;
uint16_t touchLocY;

void clear()
{
this->cpuEmulationEngineName = std::string();
Expand All @@ -119,6 +289,9 @@ struct NDSFrameInfo
this->lagFrameCount = 0;
this->cpuLoadAvgARM9 = 0;
this->cpuLoadAvgARM7 = 0;
this->inputState.value = 0xFFFFFFFFFFFFFFFFUL;
this->touchLocX = 0;
this->touchLocY = 0;
}

void copyFrom(const NDSFrameInfo &fromObject)
Expand All @@ -131,6 +304,9 @@ struct NDSFrameInfo
this->lagFrameCount = fromObject.lagFrameCount;
this->cpuLoadAvgARM9 = fromObject.cpuLoadAvgARM9;
this->cpuLoadAvgARM7 = fromObject.cpuLoadAvgARM7;
this->inputState = fromObject.inputState;
this->touchLocX = fromObject.touchLocX;
this->touchLocY = fromObject.touchLocY;
}
};

Expand Down
9 changes: 6 additions & 3 deletions desmume/src/frontend/cocoa/cocoa_core.mm
Expand Up @@ -1004,10 +1004,13 @@ - (void) stopReplay
continue;
}

// Make sure that the mic level is updated at least once per frame, regardless
// Make sure that the mic level is updated at least once every 8 frames, regardless
// of whether the NDS actually reads the mic or not.
[cdsController updateMicLevel];
[cdsController clearMicLevelMeasure];
if ((ndsFrameInfo.frameIndex & 0x07) == 0x07)
{
[cdsController updateMicLevel];
[cdsController clearMicLevelMeasure];
}

const uint8_t framesToSkip = execControl->GetFramesToSkip();

Expand Down

0 comments on commit a86539e

Please sign in to comment.