Cocoa Port: Add support for reporting inputs in the HUD.
- Also do a bunch of code refactoring.
This commit is contained in:
parent
17ff2b2d6e
commit
221fa5f72b
|
@ -92,6 +92,7 @@ void ClientDisplayView::__InstanceInit(const ClientDisplayViewProperties &props)
|
||||||
_showLagFrameCount = false;
|
_showLagFrameCount = false;
|
||||||
_showCPULoadAverage = false;
|
_showCPULoadAverage = false;
|
||||||
_showRTC = false;
|
_showRTC = false;
|
||||||
|
_showInputs = false;
|
||||||
|
|
||||||
_hudColorVideoFPS = 0xFFFFFFFF;
|
_hudColorVideoFPS = 0xFFFFFFFF;
|
||||||
_hudColorRender3DFPS = 0xFFFFFFFF;
|
_hudColorRender3DFPS = 0xFFFFFFFF;
|
||||||
|
@ -99,6 +100,9 @@ void ClientDisplayView::__InstanceInit(const ClientDisplayViewProperties &props)
|
||||||
_hudColorLagFrameCount = 0xFFFFFFFF;
|
_hudColorLagFrameCount = 0xFFFFFFFF;
|
||||||
_hudColorCPULoadAverage = 0xFFFFFFFF;
|
_hudColorCPULoadAverage = 0xFFFFFFFF;
|
||||||
_hudColorRTC = 0xFFFFFFFF;
|
_hudColorRTC = 0xFFFFFFFF;
|
||||||
|
_hudColorInputAppliedAndPending = 0xFFFFFFFF;
|
||||||
|
_hudColorInputAppliedOnly = 0xFF3030FF;
|
||||||
|
_hudColorInputPendingOnly = 0xFF00C000;
|
||||||
|
|
||||||
_clientFrameInfo.videoFPS = 0;
|
_clientFrameInfo.videoFPS = 0;
|
||||||
_ndsFrameInfo.clear();
|
_ndsFrameInfo.clear();
|
||||||
|
@ -106,6 +110,7 @@ void ClientDisplayView::__InstanceInit(const ClientDisplayViewProperties &props)
|
||||||
memset(&_emuDisplayInfo, 0, sizeof(_emuDisplayInfo));
|
memset(&_emuDisplayInfo, 0, sizeof(_emuDisplayInfo));
|
||||||
_hudString = "\x01"; // Char value 0x01 will represent the "text box" character, which will always be first in the string.
|
_hudString = "\x01"; // Char value 0x01 will represent the "text box" character, which will always be first in the string.
|
||||||
_outHudString = _hudString;
|
_outHudString = _hudString;
|
||||||
|
_hudInputString = "<^>vABXYLRSsgf x:000 y:000";
|
||||||
_hudNeedsUpdate = true;
|
_hudNeedsUpdate = true;
|
||||||
_allowViewUpdates = true;
|
_allowViewUpdates = true;
|
||||||
|
|
||||||
|
@ -167,7 +172,7 @@ void ClientDisplayView::_UpdateHUDString()
|
||||||
|
|
||||||
if (this->_showCPULoadAverage)
|
if (this->_showCPULoadAverage)
|
||||||
{
|
{
|
||||||
static char buffer[32];
|
char buffer[32];
|
||||||
memset(buffer, 0, sizeof(buffer));
|
memset(buffer, 0, sizeof(buffer));
|
||||||
snprintf(buffer, 25, "CPU Load Avg: %02d%% / %02d%%\n", this->_ndsFrameInfo.cpuLoadAvgARM9, this->_ndsFrameInfo.cpuLoadAvgARM7);
|
snprintf(buffer, 25, "CPU Load Avg: %02d%% / %02d%%\n", this->_ndsFrameInfo.cpuLoadAvgARM9, this->_ndsFrameInfo.cpuLoadAvgARM7);
|
||||||
|
|
||||||
|
@ -179,6 +184,25 @@ void ClientDisplayView::_UpdateHUDString()
|
||||||
ss << "RTC: " << this->_ndsFrameInfo.rtcString << "\n";
|
ss << "RTC: " << this->_ndsFrameInfo.rtcString << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this->_showInputs)
|
||||||
|
{
|
||||||
|
if ( (this->_ndsFrameInfo.inputStatesApplied.Touch == 0) || (this->_ndsFrameInfo.inputStatesPending.Touch == 0) )
|
||||||
|
{
|
||||||
|
char inputBuffer[HUD_INPUT_ELEMENT_LENGTH + 1];
|
||||||
|
uint8_t touchLocX = this->_ndsFrameInfo.touchLocXApplied;
|
||||||
|
uint8_t touchLocY = this->_ndsFrameInfo.touchLocYApplied;
|
||||||
|
|
||||||
|
if ( (this->_ndsFrameInfo.inputStatesApplied.Touch != 0) && (this->_ndsFrameInfo.inputStatesPending.Touch == 0) )
|
||||||
|
{
|
||||||
|
touchLocX = this->_ndsFrameInfo.touchLocXPending;
|
||||||
|
touchLocY = this->_ndsFrameInfo.touchLocYPending;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(inputBuffer, HUD_INPUT_ELEMENT_LENGTH + 1, "<^>vABXYLRSsgf x:%.3u y:%.3u", touchLocX, touchLocY);
|
||||||
|
this->_hudInputString = inputBuffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pthread_mutex_lock(&this->_mutexHUDString);
|
pthread_mutex_lock(&this->_mutexHUDString);
|
||||||
this->_hudString = ss.str();
|
this->_hudString = ss.str();
|
||||||
this->_hudNeedsUpdate = true;
|
this->_hudNeedsUpdate = true;
|
||||||
|
@ -292,6 +316,13 @@ void ClientDisplayView::SetupViewProperties()
|
||||||
if (didOrderChange)
|
if (didOrderChange)
|
||||||
{
|
{
|
||||||
this->_UpdateOrder();
|
this->_UpdateOrder();
|
||||||
|
|
||||||
|
if (this->_showInputs)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&this->_mutexHUDString);
|
||||||
|
this->_hudNeedsUpdate = true;
|
||||||
|
pthread_mutex_unlock(&this->_mutexHUDString);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (didRotationChange)
|
if (didRotationChange)
|
||||||
|
@ -567,6 +598,17 @@ void ClientDisplayView::SetHUDShowRTC(const bool visibleState)
|
||||||
this->UpdateView();
|
this->UpdateView();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ClientDisplayView::GetHUDShowInput() const
|
||||||
|
{
|
||||||
|
return this->_showInputs;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientDisplayView::SetHUDShowInput(const bool visibleState)
|
||||||
|
{
|
||||||
|
this->_SetHUDShowInfoItem(this->_showInputs, visibleState);
|
||||||
|
this->UpdateView();
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t ClientDisplayView::GetHUDColorVideoFPS() const
|
uint32_t ClientDisplayView::GetHUDColorVideoFPS() const
|
||||||
{
|
{
|
||||||
return this->_hudColorVideoFPS;
|
return this->_hudColorVideoFPS;
|
||||||
|
@ -663,6 +705,78 @@ void ClientDisplayView::SetHUDColorRTC(uint32_t color32)
|
||||||
this->UpdateView();
|
this->UpdateView();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t ClientDisplayView::GetHUDColorInputPendingAndApplied() const
|
||||||
|
{
|
||||||
|
return this->_hudColorInputAppliedAndPending;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientDisplayView::SetHUDColorInputPendingAndApplied(uint32_t color32)
|
||||||
|
{
|
||||||
|
this->_hudColorInputAppliedAndPending = color32;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&this->_mutexHUDString);
|
||||||
|
this->_hudNeedsUpdate = true;
|
||||||
|
pthread_mutex_unlock(&this->_mutexHUDString);
|
||||||
|
|
||||||
|
this->UpdateView();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t ClientDisplayView::GetHUDColorInputAppliedOnly() const
|
||||||
|
{
|
||||||
|
return this->_hudColorInputAppliedOnly;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientDisplayView::SetHUDColorInputAppliedOnly(uint32_t color32)
|
||||||
|
{
|
||||||
|
this->_hudColorInputAppliedOnly = color32;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&this->_mutexHUDString);
|
||||||
|
this->_hudNeedsUpdate = true;
|
||||||
|
pthread_mutex_unlock(&this->_mutexHUDString);
|
||||||
|
|
||||||
|
this->UpdateView();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t ClientDisplayView::GetHUDColorInputPendingOnly() const
|
||||||
|
{
|
||||||
|
return this->_hudColorInputPendingOnly;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientDisplayView::SetHUDColorInputPendingOnly(uint32_t color32)
|
||||||
|
{
|
||||||
|
this->_hudColorInputPendingOnly = color32;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&this->_mutexHUDString);
|
||||||
|
this->_hudNeedsUpdate = true;
|
||||||
|
pthread_mutex_unlock(&this->_mutexHUDString);
|
||||||
|
|
||||||
|
this->UpdateView();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t ClientDisplayView::GetInputColorUsingStates(bool pendingState, bool appliedState)
|
||||||
|
{
|
||||||
|
uint32_t color = this->_hudColorInputAppliedAndPending;
|
||||||
|
|
||||||
|
if (pendingState && appliedState)
|
||||||
|
{
|
||||||
|
color = this->_hudColorInputAppliedAndPending;
|
||||||
|
}
|
||||||
|
else if (appliedState)
|
||||||
|
{
|
||||||
|
color = this->_hudColorInputAppliedOnly;
|
||||||
|
}
|
||||||
|
else if (pendingState)
|
||||||
|
{
|
||||||
|
color = this->_hudColorInputPendingOnly;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
color = 0x80808080;
|
||||||
|
}
|
||||||
|
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
bool ClientDisplayView::HUDNeedsUpdate()
|
bool ClientDisplayView::HUDNeedsUpdate()
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&this->_mutexHUDString);
|
pthread_mutex_lock(&this->_mutexHUDString);
|
||||||
|
@ -1296,7 +1410,7 @@ void ClientDisplay3DView::SetHUDPositionVertices(float viewportWidth, float view
|
||||||
pthread_mutex_unlock(&this->_mutexHUDString);
|
pthread_mutex_unlock(&this->_mutexHUDString);
|
||||||
|
|
||||||
const char *cString = hudString.c_str();
|
const char *cString = hudString.c_str();
|
||||||
const size_t length = hudString.length();
|
const size_t textLength = (hudString.length() <= HUD_TEXT_MAX_CHARACTERS) ? hudString.length() : HUD_TEXT_MAX_CHARACTERS;
|
||||||
const float charSize = this->_glyphSize;
|
const float charSize = this->_glyphSize;
|
||||||
const float lineHeight = charSize * 0.8f;
|
const float lineHeight = charSize * 0.8f;
|
||||||
const float textBoxTextOffset = charSize * 0.25f;
|
const float textBoxTextOffset = charSize * 0.25f;
|
||||||
|
@ -1312,7 +1426,10 @@ void ClientDisplay3DView::SetHUDPositionVertices(float viewportWidth, float view
|
||||||
vtxPositionBufferPtr[6] = 0.0f; vtxPositionBufferPtr[7] = -textBoxTextOffset;
|
vtxPositionBufferPtr[6] = 0.0f; vtxPositionBufferPtr[7] = -textBoxTextOffset;
|
||||||
|
|
||||||
// Calculate the vertices of the remaining characters in the string.
|
// Calculate the vertices of the remaining characters in the string.
|
||||||
for (size_t i = 1, j = 8; i < length; i++, j+=8)
|
size_t i = 1;
|
||||||
|
size_t j = 8;
|
||||||
|
|
||||||
|
for (; i < textLength; i++, j+=8)
|
||||||
{
|
{
|
||||||
const char c = cString[i];
|
const char c = cString[i];
|
||||||
|
|
||||||
|
@ -1365,15 +1482,239 @@ void ClientDisplay3DView::SetHUDPositionVertices(float viewportWidth, float view
|
||||||
vtxPositionBufferPtr[4] += textBoxWidth;
|
vtxPositionBufferPtr[4] += textBoxWidth;
|
||||||
|
|
||||||
// Scale and translate the box
|
// Scale and translate the box
|
||||||
for (size_t i = 0; i < (length * 8); i+=2)
|
charLocX = textBoxTextOffset;
|
||||||
|
charLocY = 0.0;
|
||||||
|
|
||||||
|
for (size_t k = 0; k < (textLength * 8); k+=2)
|
||||||
{
|
{
|
||||||
// Scale
|
// Scale
|
||||||
vtxPositionBufferPtr[i+0] *= textBoxScale;
|
vtxPositionBufferPtr[k+0] *= textBoxScale;
|
||||||
vtxPositionBufferPtr[i+1] *= textBoxScale;
|
vtxPositionBufferPtr[k+1] *= textBoxScale;
|
||||||
|
|
||||||
// Translate
|
// Translate
|
||||||
vtxPositionBufferPtr[i+0] += boxOffset - (viewportWidth / 2.0f);
|
vtxPositionBufferPtr[k+0] += boxOffset - (viewportWidth / 2.0f);
|
||||||
vtxPositionBufferPtr[i+1] += (viewportHeight / 2.0f) - boxOffset;
|
vtxPositionBufferPtr[k+1] += (viewportHeight / 2.0f) - boxOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill in the vertices for the inputs.
|
||||||
|
const char *hudInputString = this->_hudInputString.c_str();
|
||||||
|
|
||||||
|
for (size_t k = 0; k < HUD_INPUT_ELEMENT_LENGTH; i++, j+=8, k++)
|
||||||
|
{
|
||||||
|
const char c = hudInputString[k];
|
||||||
|
const float charWidth = this->_glyphInfo[c].width * charSize / (float)this->_glyphTileSize;
|
||||||
|
|
||||||
|
vtxPositionBufferPtr[j+0] = charLocX; vtxPositionBufferPtr[j+1] = charLocY + charSize; // Top Left
|
||||||
|
vtxPositionBufferPtr[j+2] = charLocX + charWidth; vtxPositionBufferPtr[j+3] = charLocY + charSize; // Top Right
|
||||||
|
vtxPositionBufferPtr[j+4] = charLocX + charWidth; vtxPositionBufferPtr[j+5] = charLocY; // Bottom Right
|
||||||
|
vtxPositionBufferPtr[j+6] = charLocX; vtxPositionBufferPtr[j+7] = charLocY; // Bottom Left
|
||||||
|
charLocX += (charWidth + (charSize * 0.03f) + 0.10f);
|
||||||
|
}
|
||||||
|
|
||||||
|
float inputScale = 0.45 * this->_hudObjectScale;
|
||||||
|
if (inputScale < (0.45 * 1.0))
|
||||||
|
{
|
||||||
|
inputScale = 0.45 * 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inputScale /= this->_scaleFactor;
|
||||||
|
|
||||||
|
for (size_t k = (textLength * 8); k < ((textLength + HUD_INPUT_ELEMENT_LENGTH) * 8); k+=2)
|
||||||
|
{
|
||||||
|
// Scale
|
||||||
|
vtxPositionBufferPtr[k+0] *= inputScale;
|
||||||
|
vtxPositionBufferPtr[k+1] *= inputScale;
|
||||||
|
|
||||||
|
// Translate
|
||||||
|
vtxPositionBufferPtr[k+0] += boxOffset - (viewportWidth / 2.0f);
|
||||||
|
vtxPositionBufferPtr[k+1] += -(viewportHeight / 2.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->SetHUDTouchLinePositionVertices(vtxPositionBufferPtr + j);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientDisplay3DView::SetHUDTouchLinePositionVertices(float *vtxBufferPtr)
|
||||||
|
{
|
||||||
|
const float x = (this->_ndsFrameInfo.inputStatesApplied.Touch == 0) ? this->_ndsFrameInfo.touchLocXApplied : this->_ndsFrameInfo.touchLocXPending;
|
||||||
|
const float y = 191.0f - ((this->_ndsFrameInfo.inputStatesApplied.Touch == 0) ? this->_ndsFrameInfo.touchLocYApplied : this->_ndsFrameInfo.touchLocYPending);
|
||||||
|
const float w = this->_renderProperty.normalWidth / 2.0f;
|
||||||
|
const float h = this->_renderProperty.normalHeight / 2.0f;
|
||||||
|
|
||||||
|
if (this->_renderProperty.mode == ClientDisplayMode_Dual)
|
||||||
|
{
|
||||||
|
switch (this->_renderProperty.layout)
|
||||||
|
{
|
||||||
|
case ClientDisplayLayout_Horizontal:
|
||||||
|
{
|
||||||
|
if (this->_renderProperty.order == ClientDisplayOrder_MainFirst)
|
||||||
|
{
|
||||||
|
vtxBufferPtr[0] = x; vtxBufferPtr[1] = h; // Vertical line, top left
|
||||||
|
vtxBufferPtr[2] = x + 1.0f; vtxBufferPtr[3] = h; // Vertical line, top right
|
||||||
|
vtxBufferPtr[4] = x + 1.0f; vtxBufferPtr[5] = -h; // Vertical line, bottom right
|
||||||
|
vtxBufferPtr[6] = x; vtxBufferPtr[7] = -h; // Vertical line, bottom left
|
||||||
|
|
||||||
|
vtxBufferPtr[8] = 0.0f; vtxBufferPtr[9] = -h + y + 1.0f; // Horizontal line, top left
|
||||||
|
vtxBufferPtr[10] = w; vtxBufferPtr[11] = -h + y + 1.0f; // Horizontal line, top right
|
||||||
|
vtxBufferPtr[12] = w; vtxBufferPtr[13] = -h + y; // Horizontal line, bottom right
|
||||||
|
vtxBufferPtr[14] = 0.0f; vtxBufferPtr[15] = -h + y; // Horizontal line, bottom left
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vtxBufferPtr[0] = -w + x; vtxBufferPtr[1] = h; // Vertical line, top left
|
||||||
|
vtxBufferPtr[2] = -w + x + 1.0f; vtxBufferPtr[3] = h; // Vertical line, top right
|
||||||
|
vtxBufferPtr[4] = -w + x + 1.0f; vtxBufferPtr[5] = -h; // Vertical line, bottom right
|
||||||
|
vtxBufferPtr[6] = -w + x; vtxBufferPtr[7] = -h; // Vertical line, bottom left
|
||||||
|
|
||||||
|
vtxBufferPtr[8] = -w; vtxBufferPtr[9] = -h + y + 1.0f; // Horizontal line, top left
|
||||||
|
vtxBufferPtr[10] = 0.0f; vtxBufferPtr[11] = -h + y + 1.0f; // Horizontal line, top right
|
||||||
|
vtxBufferPtr[12] = 0.0f; vtxBufferPtr[13] = -h + y; // Horizontal line, bottom right
|
||||||
|
vtxBufferPtr[14] = -w; vtxBufferPtr[15] = -h + y; // Horizontal line, bottom left
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(vtxBufferPtr + (2 * 8), vtxBufferPtr + (0 * 8), sizeof(float) * (2 * 8)); // Unused lines
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ClientDisplayLayout_Hybrid_2_1:
|
||||||
|
{
|
||||||
|
vtxBufferPtr[0] = -w + (float)GPU_FRAMEBUFFER_NATIVE_WIDTH + (x/2.0f); vtxBufferPtr[1] = -h + 96.0f; // Minor bottom display, vertical line, top left
|
||||||
|
vtxBufferPtr[2] = -w + (float)GPU_FRAMEBUFFER_NATIVE_WIDTH + ((x+1.0f)/2.0f); vtxBufferPtr[3] = -h + 96.0f; // Minor bottom display, vertical line, top right
|
||||||
|
vtxBufferPtr[4] = -w + (float)GPU_FRAMEBUFFER_NATIVE_WIDTH + ((x+1.0f)/2.0f); vtxBufferPtr[5] = -h; // Minor bottom display, vertical line, bottom right
|
||||||
|
vtxBufferPtr[6] = -w + (float)GPU_FRAMEBUFFER_NATIVE_WIDTH + (x/2.0f); vtxBufferPtr[7] = -h; // Minor bottom display, vertical line, bottom left
|
||||||
|
|
||||||
|
vtxBufferPtr[8] = -w + (float)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[9] = -h + ((y+1.0f)/2.0f); // Minor bottom display, horizontal line, top left
|
||||||
|
vtxBufferPtr[10] = w; vtxBufferPtr[11] = -h + ((y+1.0f)/2.0f); // Minor bottom display, horizontal line, top right
|
||||||
|
vtxBufferPtr[12] = w; vtxBufferPtr[13] = -h + (y/2.0f); // Minor bottom display, horizontal line, bottom right
|
||||||
|
vtxBufferPtr[14] = -w + (float)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[15] = -h + (y/2.0f); // Minor bottom display, horizontal line, bottom left
|
||||||
|
|
||||||
|
if (this->_renderProperty.order == ClientDisplayOrder_MainFirst)
|
||||||
|
{
|
||||||
|
memcpy(vtxBufferPtr + (2 * 8), vtxBufferPtr + (0 * 8), sizeof(float) * (2 * 8)); // Unused lines
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vtxBufferPtr[16] = -w + x; vtxBufferPtr[17] = h; // Major display, vertical line, top left
|
||||||
|
vtxBufferPtr[18] = -w + x + 1.0f; vtxBufferPtr[19] = h; // Major display, vertical line, top right
|
||||||
|
vtxBufferPtr[20] = -w + x + 1.0f; vtxBufferPtr[21] = -h; // Major display, vertical line, bottom right
|
||||||
|
vtxBufferPtr[22] = -w + x; vtxBufferPtr[23] = -h; // Major display, vertical line, bottom left
|
||||||
|
|
||||||
|
vtxBufferPtr[24] = -w; vtxBufferPtr[25] = -h + y + 1.0f; // Major display, horizontal line, top left
|
||||||
|
vtxBufferPtr[26] = -w + (float)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[27] = -h + y + 1.0f; // Major display, horizontal line, top right
|
||||||
|
vtxBufferPtr[28] = -w + (float)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[29] = -h + y; // Major display, horizontal line, bottom right
|
||||||
|
vtxBufferPtr[30] = -w; vtxBufferPtr[31] = -h + y; // Major display, horizontal line, bottom left
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ClientDisplayLayout_Hybrid_16_9:
|
||||||
|
{
|
||||||
|
vtxBufferPtr[0] = -w + (float)GPU_FRAMEBUFFER_NATIVE_WIDTH + (x/3.0f); vtxBufferPtr[1] = -h + 64.0f; // Minor bottom display, vertical line, top left
|
||||||
|
vtxBufferPtr[2] = -w + (float)GPU_FRAMEBUFFER_NATIVE_WIDTH + ((x+1.0f)/3.0f); vtxBufferPtr[3] = -h + 64.0f; // Minor bottom display, vertical line, top right
|
||||||
|
vtxBufferPtr[4] = -w + (float)GPU_FRAMEBUFFER_NATIVE_WIDTH + ((x+1.0f)/3.0f); vtxBufferPtr[5] = -h; // Minor bottom display, vertical line, bottom right
|
||||||
|
vtxBufferPtr[6] = -w + (float)GPU_FRAMEBUFFER_NATIVE_WIDTH + (x/3.0f); vtxBufferPtr[7] = -h; // Minor bottom display, vertical line, bottom left
|
||||||
|
|
||||||
|
vtxBufferPtr[8] = -w + (float)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[9] = -h + ((y+1.0f)/3.0f); // Minor bottom display, horizontal line, top left
|
||||||
|
vtxBufferPtr[10] = w; vtxBufferPtr[11] = -h + ((y+1.0f)/3.0f); // Minor bottom display, horizontal line, top right
|
||||||
|
vtxBufferPtr[12] = w; vtxBufferPtr[13] = -h + (y/3.0f); // Minor bottom display, horizontal line, bottom right
|
||||||
|
vtxBufferPtr[14] = -w + (float)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[15] = -h + (y/3.0f); // Minor bottom display, horizontal line, bottom left
|
||||||
|
|
||||||
|
if (this->_renderProperty.order == ClientDisplayOrder_MainFirst)
|
||||||
|
{
|
||||||
|
memcpy(vtxBufferPtr + (2 * 8), vtxBufferPtr + (0 * 8), sizeof(float) * (2 * 8)); // Unused lines
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vtxBufferPtr[16] = -w + x; vtxBufferPtr[17] = h; // Major display, vertical line, top left
|
||||||
|
vtxBufferPtr[18] = -w + x + 1.0f; vtxBufferPtr[19] = h; // Major display, vertical line, top right
|
||||||
|
vtxBufferPtr[20] = -w + x + 1.0f; vtxBufferPtr[21] = -h; // Major display, vertical line, bottom right
|
||||||
|
vtxBufferPtr[22] = -w + x; vtxBufferPtr[23] = -h; // Major display, vertical line, bottom left
|
||||||
|
|
||||||
|
vtxBufferPtr[24] = -w; vtxBufferPtr[25] = -h + y + 1.0f; // Major display, horizontal line, top left
|
||||||
|
vtxBufferPtr[26] = -w + (float)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[27] = -h + y + 1.0f; // Major display, horizontal line, top right
|
||||||
|
vtxBufferPtr[28] = -w + (float)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[29] = -h + y; // Major display, horizontal line, bottom right
|
||||||
|
vtxBufferPtr[30] = -w; vtxBufferPtr[31] = -h + y; // Major display, horizontal line, bottom left
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ClientDisplayLayout_Hybrid_16_10:
|
||||||
|
{
|
||||||
|
vtxBufferPtr[0] = -w + (float)GPU_FRAMEBUFFER_NATIVE_WIDTH + (x/5.0f); vtxBufferPtr[1] = -h + 38.4f; // Minor bottom display, vertical line, top left
|
||||||
|
vtxBufferPtr[2] = -w + (float)GPU_FRAMEBUFFER_NATIVE_WIDTH + ((x+1.0f)/5.0f); vtxBufferPtr[3] = -h + 38.4f; // Minor bottom display, vertical line, top right
|
||||||
|
vtxBufferPtr[4] = -w + (float)GPU_FRAMEBUFFER_NATIVE_WIDTH + ((x+1.0f)/5.0f); vtxBufferPtr[5] = -h; // Minor bottom display, vertical line, bottom right
|
||||||
|
vtxBufferPtr[6] = -w + (float)GPU_FRAMEBUFFER_NATIVE_WIDTH + (x/5.0f); vtxBufferPtr[7] = -h; // Minor bottom display, vertical line, bottom left
|
||||||
|
|
||||||
|
vtxBufferPtr[8] = -w + (float)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[9] = -h + ((y+1.0f)/5.0f); // Minor bottom display, horizontal line, top left
|
||||||
|
vtxBufferPtr[10] = w; vtxBufferPtr[11] = -h + ((y+1.0f)/5.0f); // Minor bottom display, horizontal line, top right
|
||||||
|
vtxBufferPtr[12] = w; vtxBufferPtr[13] = -h + (y/5.0f); // Minor bottom display, horizontal line, bottom right
|
||||||
|
vtxBufferPtr[14] = -w + (float)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[15] = -h + (y/5.0f); // Minor bottom display, horizontal line, bottom left
|
||||||
|
|
||||||
|
if (this->_renderProperty.order == ClientDisplayOrder_MainFirst)
|
||||||
|
{
|
||||||
|
memcpy(vtxBufferPtr + (2 * 8), vtxBufferPtr + (0 * 8), sizeof(float) * (2 * 8)); // Unused lines
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vtxBufferPtr[16] = -w + x; vtxBufferPtr[17] = h; // Major display, vertical line, top left
|
||||||
|
vtxBufferPtr[18] = -w + x + 1.0f; vtxBufferPtr[19] = h; // Major display, vertical line, top right
|
||||||
|
vtxBufferPtr[20] = -w + x + 1.0f; vtxBufferPtr[21] = -h; // Major display, vertical line, bottom right
|
||||||
|
vtxBufferPtr[22] = -w + x; vtxBufferPtr[23] = -h; // Major display, vertical line, bottom left
|
||||||
|
|
||||||
|
vtxBufferPtr[24] = -w; vtxBufferPtr[25] = -h + y + 1.0f; // Major display, horizontal line, top left
|
||||||
|
vtxBufferPtr[26] = -w + (float)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[27] = -h + y + 1.0f; // Major display, horizontal line, top right
|
||||||
|
vtxBufferPtr[28] = -w + (float)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[29] = -h + y; // Major display, horizontal line, bottom right
|
||||||
|
vtxBufferPtr[30] = -w; vtxBufferPtr[31] = -h + y; // Major display, horizontal line, bottom left
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default: // Default to vertical orientation.
|
||||||
|
{
|
||||||
|
const float g = (float)this->_renderProperty.gapDistance;
|
||||||
|
|
||||||
|
if (this->_renderProperty.order == ClientDisplayOrder_MainFirst)
|
||||||
|
{
|
||||||
|
vtxBufferPtr[0] = -w + x; vtxBufferPtr[1] = -g/2.0f; // Vertical line, top left
|
||||||
|
vtxBufferPtr[2] = -w + x + 1.0f; vtxBufferPtr[3] = -g/2.0f; // Vertical line, top right
|
||||||
|
vtxBufferPtr[4] = -w + x + 1.0f; vtxBufferPtr[5] = -h; // Vertical line, bottom right
|
||||||
|
vtxBufferPtr[6] = -w + x; vtxBufferPtr[7] = -h; // Vertical line, bottom left
|
||||||
|
|
||||||
|
vtxBufferPtr[8] = -w; vtxBufferPtr[9] = -h + y + 1.0f; // Horizontal line, top left
|
||||||
|
vtxBufferPtr[10] = w; vtxBufferPtr[11] = -h + y + 1.0f; // Horizontal line, top right
|
||||||
|
vtxBufferPtr[12] = w; vtxBufferPtr[13] = -h + y; // Horizontal line, bottom right
|
||||||
|
vtxBufferPtr[14] = -w; vtxBufferPtr[15] = -h + y; // Horizontal line, bottom left
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vtxBufferPtr[0] = -w + x; vtxBufferPtr[1] = h; // Vertical line, top left
|
||||||
|
vtxBufferPtr[2] = -w + x + 1.0f; vtxBufferPtr[3] = h; // Vertical line, top right
|
||||||
|
vtxBufferPtr[4] = -w + x + 1.0f; vtxBufferPtr[5] = g/2.0f; // Vertical line, bottom right
|
||||||
|
vtxBufferPtr[6] = -w + x; vtxBufferPtr[7] = g/2.0f; // Vertical line, bottom left
|
||||||
|
|
||||||
|
vtxBufferPtr[8] = -w; vtxBufferPtr[9] = g/2.0f + y + 1.0f; // Horizontal line, top left
|
||||||
|
vtxBufferPtr[10] = w; vtxBufferPtr[11] = g/2.0f + y + 1.0f; // Horizontal line, top right
|
||||||
|
vtxBufferPtr[12] = w; vtxBufferPtr[13] = g/2.0f + y; // Horizontal line, bottom right
|
||||||
|
vtxBufferPtr[14] = -w; vtxBufferPtr[15] = g/2.0f + y; // Horizontal line, bottom left
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(vtxBufferPtr + (2 * 8), vtxBufferPtr + (0 * 8), sizeof(float) * (2 * 8)); // Unused lines
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // displayModeID == ClientDisplayMode_Main || displayModeID == ClientDisplayMode_Touch
|
||||||
|
{
|
||||||
|
vtxBufferPtr[0] = -w + x; vtxBufferPtr[1] = h; // Vertical line, top left
|
||||||
|
vtxBufferPtr[2] = -w + x + 1.0f; vtxBufferPtr[3] = h; // Vertical line, top right
|
||||||
|
vtxBufferPtr[4] = -w + x + 1.0f; vtxBufferPtr[5] = -h; // Vertical line, bottom right
|
||||||
|
vtxBufferPtr[6] = -w + x; vtxBufferPtr[7] = -h; // Vertical line, bottom left
|
||||||
|
|
||||||
|
vtxBufferPtr[8] = -w; vtxBufferPtr[9] = -h + y + 1.0f; // Horizontal line, top left
|
||||||
|
vtxBufferPtr[10] = w; vtxBufferPtr[11] = -h + y + 1.0f; // Horizontal line, top right
|
||||||
|
vtxBufferPtr[12] = w; vtxBufferPtr[13] = -h + y; // Horizontal line, bottom right
|
||||||
|
vtxBufferPtr[14] = -w; vtxBufferPtr[15] = -h + y; // Horizontal line, bottom left
|
||||||
|
|
||||||
|
memcpy(vtxBufferPtr + (2 * 8), vtxBufferPtr + (0 * 8), sizeof(float) * (2 * 8)); // Alternate lines
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1384,7 +1725,7 @@ void ClientDisplay3DView::SetHUDColorVertices(uint32_t *vtxColorBufferPtr)
|
||||||
pthread_mutex_unlock(&this->_mutexHUDString);
|
pthread_mutex_unlock(&this->_mutexHUDString);
|
||||||
|
|
||||||
const char *cString = hudString.c_str();
|
const char *cString = hudString.c_str();
|
||||||
const size_t length = hudString.length();
|
const size_t textLength = (hudString.length() <= HUD_TEXT_MAX_CHARACTERS) ? hudString.length() : HUD_TEXT_MAX_CHARACTERS;
|
||||||
uint32_t currentColor = 0x40000000;
|
uint32_t currentColor = 0x40000000;
|
||||||
|
|
||||||
// First, calculate the color of the text box.
|
// First, calculate the color of the text box.
|
||||||
|
@ -1433,7 +1774,10 @@ void ClientDisplay3DView::SetHUDColorVertices(uint32_t *vtxColorBufferPtr)
|
||||||
alreadyColoredRTC = true;
|
alreadyColoredRTC = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 1, j = 4; i < length; i++, j+=4)
|
size_t i = 1;
|
||||||
|
size_t j = 4;
|
||||||
|
|
||||||
|
for (; i < textLength; i++, j+=4)
|
||||||
{
|
{
|
||||||
const char c = cString[i];
|
const char c = cString[i];
|
||||||
|
|
||||||
|
@ -1478,6 +1822,51 @@ void ClientDisplay3DView::SetHUDColorVertices(uint32_t *vtxColorBufferPtr)
|
||||||
vtxColorBufferPtr[j+2] = currentColor; // Bottom Right
|
vtxColorBufferPtr[j+2] = currentColor; // Bottom Right
|
||||||
vtxColorBufferPtr[j+3] = currentColor; // Bottom Left
|
vtxColorBufferPtr[j+3] = currentColor; // Bottom Left
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fill in the vertices for the inputs.
|
||||||
|
// "<^>vABXYLRSsgf x:000 y:000";
|
||||||
|
|
||||||
|
uint32_t inputColors[HUD_INPUT_ELEMENT_LENGTH];
|
||||||
|
inputColors[ 0] = this->GetInputColorUsingStates( (this->_ndsFrameInfo.inputStatesPending.Left == 0), (this->_ndsFrameInfo.inputStatesApplied.Left == 0) );
|
||||||
|
inputColors[ 1] = this->GetInputColorUsingStates( (this->_ndsFrameInfo.inputStatesPending.Up == 0), (this->_ndsFrameInfo.inputStatesApplied.Up == 0) );
|
||||||
|
inputColors[ 2] = this->GetInputColorUsingStates( (this->_ndsFrameInfo.inputStatesPending.Right == 0), (this->_ndsFrameInfo.inputStatesApplied.Right == 0) );
|
||||||
|
inputColors[ 3] = this->GetInputColorUsingStates( (this->_ndsFrameInfo.inputStatesPending.Down == 0), (this->_ndsFrameInfo.inputStatesApplied.Down == 0) );
|
||||||
|
inputColors[ 4] = this->GetInputColorUsingStates( (this->_ndsFrameInfo.inputStatesPending.A == 0), (this->_ndsFrameInfo.inputStatesApplied.A == 0) );
|
||||||
|
inputColors[ 5] = this->GetInputColorUsingStates( (this->_ndsFrameInfo.inputStatesPending.B == 0), (this->_ndsFrameInfo.inputStatesApplied.B == 0) );
|
||||||
|
inputColors[ 6] = this->GetInputColorUsingStates( (this->_ndsFrameInfo.inputStatesPending.X == 0), (this->_ndsFrameInfo.inputStatesApplied.X == 0) );
|
||||||
|
inputColors[ 7] = this->GetInputColorUsingStates( (this->_ndsFrameInfo.inputStatesPending.Y == 0), (this->_ndsFrameInfo.inputStatesApplied.Y == 0) );
|
||||||
|
inputColors[ 8] = this->GetInputColorUsingStates( (this->_ndsFrameInfo.inputStatesPending.L == 0), (this->_ndsFrameInfo.inputStatesApplied.L == 0) );
|
||||||
|
inputColors[ 9] = this->GetInputColorUsingStates( (this->_ndsFrameInfo.inputStatesPending.R == 0), (this->_ndsFrameInfo.inputStatesApplied.R == 0) );
|
||||||
|
inputColors[10] = this->GetInputColorUsingStates( (this->_ndsFrameInfo.inputStatesPending.Start == 0), (this->_ndsFrameInfo.inputStatesApplied.Start == 0) );
|
||||||
|
inputColors[11] = this->GetInputColorUsingStates( (this->_ndsFrameInfo.inputStatesPending.Select == 0), (this->_ndsFrameInfo.inputStatesApplied.Select == 0) );
|
||||||
|
inputColors[12] = this->GetInputColorUsingStates( (this->_ndsFrameInfo.inputStatesPending.Debug == 0), (this->_ndsFrameInfo.inputStatesApplied.Debug == 0) );
|
||||||
|
inputColors[13] = this->GetInputColorUsingStates( (this->_ndsFrameInfo.inputStatesPending.Lid == 0), (this->_ndsFrameInfo.inputStatesApplied.Lid == 0) );
|
||||||
|
inputColors[14] = this->GetInputColorUsingStates( (this->_ndsFrameInfo.inputStatesPending.Touch == 0), (this->_ndsFrameInfo.inputStatesApplied.Touch == 0) );
|
||||||
|
|
||||||
|
uint32_t touchColor = inputColors[14];
|
||||||
|
|
||||||
|
for (size_t k = 15; k < HUD_INPUT_ELEMENT_LENGTH; k++)
|
||||||
|
{
|
||||||
|
inputColors[k] = touchColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t k = 0; k < HUD_INPUT_ELEMENT_LENGTH; i++, j+=4, k++)
|
||||||
|
{
|
||||||
|
vtxColorBufferPtr[j+0] = inputColors[k]; // Top Left
|
||||||
|
vtxColorBufferPtr[j+1] = inputColors[k]; // Top Right
|
||||||
|
vtxColorBufferPtr[j+2] = inputColors[k]; // Bottom Right
|
||||||
|
vtxColorBufferPtr[j+3] = inputColors[k]; // Bottom Left
|
||||||
|
}
|
||||||
|
|
||||||
|
touchColor = ((this->_ndsFrameInfo.inputStatesPending.Touch != 0) && (this->_ndsFrameInfo.inputStatesApplied.Touch != 0)) ? 0x00000000 : (touchColor & 0x00FFFFFF) | (0x60000000);
|
||||||
|
|
||||||
|
for (size_t k = 0; k < HUD_INPUT_TOUCH_LINE_ELEMENTS; i++, j+=4, k++)
|
||||||
|
{
|
||||||
|
vtxColorBufferPtr[j+0] = touchColor; // Top Left
|
||||||
|
vtxColorBufferPtr[j+1] = touchColor; // Top Right
|
||||||
|
vtxColorBufferPtr[j+2] = touchColor; // Bottom Right
|
||||||
|
vtxColorBufferPtr[j+3] = touchColor; // Bottom Left
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientDisplay3DView::SetHUDTextureCoordinates(float *texCoordBufferPtr)
|
void ClientDisplay3DView::SetHUDTextureCoordinates(float *texCoordBufferPtr)
|
||||||
|
@ -1487,9 +1876,10 @@ void ClientDisplay3DView::SetHUDTextureCoordinates(float *texCoordBufferPtr)
|
||||||
pthread_mutex_unlock(&this->_mutexHUDString);
|
pthread_mutex_unlock(&this->_mutexHUDString);
|
||||||
|
|
||||||
const char *cString = hudString.c_str();
|
const char *cString = hudString.c_str();
|
||||||
const size_t length = hudString.length();
|
const size_t textLength = hudString.length();
|
||||||
|
size_t i = 0;
|
||||||
|
|
||||||
for (size_t i = 0; i < length; i++)
|
for (; i < textLength; i++)
|
||||||
{
|
{
|
||||||
const char c = cString[i];
|
const char c = cString[i];
|
||||||
const float *glyphTexCoord = this->_glyphInfo[c].texCoord;
|
const float *glyphTexCoord = this->_glyphInfo[c].texCoord;
|
||||||
|
@ -1504,6 +1894,40 @@ void ClientDisplay3DView::SetHUDTextureCoordinates(float *texCoordBufferPtr)
|
||||||
hudTexCoord[6] = glyphTexCoord[6];
|
hudTexCoord[6] = glyphTexCoord[6];
|
||||||
hudTexCoord[7] = glyphTexCoord[7];
|
hudTexCoord[7] = glyphTexCoord[7];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *hudInputString = this->_hudInputString.c_str();
|
||||||
|
|
||||||
|
for (size_t k = 0; k < HUD_INPUT_ELEMENT_LENGTH; i++, k++)
|
||||||
|
{
|
||||||
|
const char c = hudInputString[k];
|
||||||
|
const float *glyphTexCoord = this->_glyphInfo[c].texCoord;
|
||||||
|
float *hudTexCoord = &texCoordBufferPtr[i * 8];
|
||||||
|
|
||||||
|
hudTexCoord[0] = glyphTexCoord[0];
|
||||||
|
hudTexCoord[1] = glyphTexCoord[1];
|
||||||
|
hudTexCoord[2] = glyphTexCoord[2];
|
||||||
|
hudTexCoord[3] = glyphTexCoord[3];
|
||||||
|
hudTexCoord[4] = glyphTexCoord[4];
|
||||||
|
hudTexCoord[5] = glyphTexCoord[5];
|
||||||
|
hudTexCoord[6] = glyphTexCoord[6];
|
||||||
|
hudTexCoord[7] = glyphTexCoord[7];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t k = 0; k < HUD_INPUT_TOUCH_LINE_ELEMENTS; i++, k++)
|
||||||
|
{
|
||||||
|
const char c = cString[0];
|
||||||
|
const float *glyphTexCoord = this->_glyphInfo[c].texCoord;
|
||||||
|
float *hudTexCoord = &texCoordBufferPtr[i * 8];
|
||||||
|
|
||||||
|
hudTexCoord[0] = glyphTexCoord[0];
|
||||||
|
hudTexCoord[1] = glyphTexCoord[1];
|
||||||
|
hudTexCoord[2] = glyphTexCoord[2];
|
||||||
|
hudTexCoord[3] = glyphTexCoord[3];
|
||||||
|
hudTexCoord[4] = glyphTexCoord[4];
|
||||||
|
hudTexCoord[5] = glyphTexCoord[5];
|
||||||
|
hudTexCoord[6] = glyphTexCoord[6];
|
||||||
|
hudTexCoord[7] = glyphTexCoord[7];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientDisplay3DView::SetScreenVertices(float *vtxBufferPtr)
|
void ClientDisplay3DView::SetScreenVertices(float *vtxBufferPtr)
|
||||||
|
|
|
@ -29,9 +29,12 @@
|
||||||
#include <ft2build.h>
|
#include <ft2build.h>
|
||||||
#include FT_FREETYPE_H
|
#include FT_FREETYPE_H
|
||||||
|
|
||||||
#define HUD_MAX_CHARACTERS 2048
|
#define HUD_TOTAL_ELEMENTS 1024
|
||||||
#define HUD_VERTEX_ATTRIBUTE_BUFFER_SIZE (sizeof(float) * HUD_MAX_CHARACTERS * (2 * 4))
|
#define HUD_INPUT_ELEMENT_LENGTH 26
|
||||||
#define HUD_VERTEX_COLOR_ATTRIBUTE_BUFFER_SIZE (sizeof(uint32_t) * HUD_MAX_CHARACTERS * 4)
|
#define HUD_INPUT_TOUCH_LINE_ELEMENTS 4
|
||||||
|
#define HUD_TEXT_MAX_CHARACTERS (HUD_TOTAL_ELEMENTS - HUD_INPUT_ELEMENT_LENGTH - HUD_INPUT_TOUCH_LINE_ELEMENTS)
|
||||||
|
#define HUD_VERTEX_ATTRIBUTE_BUFFER_SIZE (sizeof(float) * HUD_TOTAL_ELEMENTS * (2 * 4))
|
||||||
|
#define HUD_VERTEX_COLOR_ATTRIBUTE_BUFFER_SIZE (sizeof(uint32_t) * HUD_TOTAL_ELEMENTS * 4)
|
||||||
#define HUD_TEXTBOX_BASEGLYPHSIZE 64.0
|
#define HUD_TEXTBOX_BASEGLYPHSIZE 64.0
|
||||||
#define HUD_TEXTBOX_BASE_SCALE (1.0/3.0)
|
#define HUD_TEXTBOX_BASE_SCALE (1.0/3.0)
|
||||||
#define HUD_TEXTBOX_MIN_SCALE 0.70
|
#define HUD_TEXTBOX_MIN_SCALE 0.70
|
||||||
|
@ -160,6 +163,7 @@ protected:
|
||||||
bool _showLagFrameCount;
|
bool _showLagFrameCount;
|
||||||
bool _showCPULoadAverage;
|
bool _showCPULoadAverage;
|
||||||
bool _showRTC;
|
bool _showRTC;
|
||||||
|
bool _showInputs;
|
||||||
|
|
||||||
uint32_t _hudColorVideoFPS;
|
uint32_t _hudColorVideoFPS;
|
||||||
uint32_t _hudColorRender3DFPS;
|
uint32_t _hudColorRender3DFPS;
|
||||||
|
@ -167,12 +171,16 @@ protected:
|
||||||
uint32_t _hudColorLagFrameCount;
|
uint32_t _hudColorLagFrameCount;
|
||||||
uint32_t _hudColorCPULoadAverage;
|
uint32_t _hudColorCPULoadAverage;
|
||||||
uint32_t _hudColorRTC;
|
uint32_t _hudColorRTC;
|
||||||
|
uint32_t _hudColorInputAppliedAndPending;
|
||||||
|
uint32_t _hudColorInputAppliedOnly;
|
||||||
|
uint32_t _hudColorInputPendingOnly;
|
||||||
|
|
||||||
ClientFrameInfo _clientFrameInfo;
|
ClientFrameInfo _clientFrameInfo;
|
||||||
NDSFrameInfo _ndsFrameInfo;
|
NDSFrameInfo _ndsFrameInfo;
|
||||||
|
|
||||||
NDSDisplayInfo _emuDisplayInfo;
|
NDSDisplayInfo _emuDisplayInfo;
|
||||||
std::string _hudString;
|
std::string _hudString;
|
||||||
|
std::string _hudInputString;
|
||||||
std::string _outHudString;
|
std::string _outHudString;
|
||||||
bool _hudNeedsUpdate;
|
bool _hudNeedsUpdate;
|
||||||
bool _allowViewUpdates;
|
bool _allowViewUpdates;
|
||||||
|
@ -267,6 +275,8 @@ public:
|
||||||
virtual void SetHUDShowCPULoadAverage(const bool visibleState);
|
virtual void SetHUDShowCPULoadAverage(const bool visibleState);
|
||||||
bool GetHUDShowRTC() const;
|
bool GetHUDShowRTC() const;
|
||||||
virtual void SetHUDShowRTC(const bool visibleState);
|
virtual void SetHUDShowRTC(const bool visibleState);
|
||||||
|
bool GetHUDShowInput() const;
|
||||||
|
virtual void SetHUDShowInput(const bool visibleState);
|
||||||
uint32_t GetHUDColorVideoFPS() const;
|
uint32_t GetHUDColorVideoFPS() const;
|
||||||
virtual void SetHUDColorVideoFPS(uint32_t color32);
|
virtual void SetHUDColorVideoFPS(uint32_t color32);
|
||||||
uint32_t GetHUDColorRender3DFPS() const;
|
uint32_t GetHUDColorRender3DFPS() const;
|
||||||
|
@ -279,6 +289,13 @@ public:
|
||||||
virtual void SetHUDColorCPULoadAverage(uint32_t color32);
|
virtual void SetHUDColorCPULoadAverage(uint32_t color32);
|
||||||
uint32_t GetHUDColorRTC() const;
|
uint32_t GetHUDColorRTC() const;
|
||||||
virtual void SetHUDColorRTC(uint32_t color32);
|
virtual void SetHUDColorRTC(uint32_t color32);
|
||||||
|
uint32_t GetHUDColorInputPendingAndApplied() const;
|
||||||
|
virtual void SetHUDColorInputPendingAndApplied(uint32_t color32);
|
||||||
|
uint32_t GetHUDColorInputAppliedOnly() const;
|
||||||
|
virtual void SetHUDColorInputAppliedOnly(uint32_t color32);
|
||||||
|
uint32_t GetHUDColorInputPendingOnly() const;
|
||||||
|
virtual void SetHUDColorInputPendingOnly(uint32_t color32);
|
||||||
|
uint32_t GetInputColorUsingStates(bool pendingState, bool appliedState);
|
||||||
bool HUDNeedsUpdate();
|
bool HUDNeedsUpdate();
|
||||||
void ClearHUDNeedsUpdate();
|
void ClearHUDNeedsUpdate();
|
||||||
|
|
||||||
|
@ -340,6 +357,7 @@ public:
|
||||||
virtual void SetSourceDeposterize(const bool useDeposterize);
|
virtual void SetSourceDeposterize(const bool useDeposterize);
|
||||||
|
|
||||||
void SetHUDPositionVertices(float viewportWidth, float viewportHeight, float *vtxPositionBufferPtr);
|
void SetHUDPositionVertices(float viewportWidth, float viewportHeight, float *vtxPositionBufferPtr);
|
||||||
|
void SetHUDTouchLinePositionVertices(float *vtxBufferPtr);
|
||||||
void SetHUDColorVertices(uint32_t *vtxColorBufferPtr);
|
void SetHUDColorVertices(uint32_t *vtxColorBufferPtr);
|
||||||
void SetHUDTextureCoordinates(float *texCoordBufferPtr);
|
void SetHUDTextureCoordinates(float *texCoordBufferPtr);
|
||||||
void SetScreenVertices(float *vtxBufferPtr);
|
void SetScreenVertices(float *vtxBufferPtr);
|
||||||
|
|
|
@ -22,16 +22,34 @@
|
||||||
#include "GPU.h"
|
#include "GPU.h"
|
||||||
#include "movie.h"
|
#include "movie.h"
|
||||||
#include "rtc.h"
|
#include "rtc.h"
|
||||||
|
#include "slot2.h"
|
||||||
|
|
||||||
|
#include "audiosamplegenerator.h"
|
||||||
#include "ClientExecutionControl.h"
|
#include "ClientExecutionControl.h"
|
||||||
|
|
||||||
|
|
||||||
ClientExecutionControl::ClientExecutionControl()
|
ClientExecutionControl::ClientExecutionControl()
|
||||||
{
|
{
|
||||||
|
_nullSampleGenerator = new NullGenerator;
|
||||||
|
_internalNoiseGenerator = new InternalNoiseGenerator;
|
||||||
|
_whiteNoiseGenerator = new WhiteNoiseGenerator;
|
||||||
|
_sineWaveGenerator = new SineWaveGenerator(250.0, MIC_SAMPLE_RATE);
|
||||||
|
_selectedAudioFileGenerator = NULL;
|
||||||
|
|
||||||
_newSettingsPendingOnReset = true;
|
_newSettingsPendingOnReset = true;
|
||||||
_newSettingsPendingOnExecutionLoopStart = true;
|
_newSettingsPendingOnExecutionLoopStart = true;
|
||||||
_newSettingsPendingOnNDSExec = true;
|
_newSettingsPendingOnNDSExec = true;
|
||||||
|
|
||||||
|
_enableAutohold = false;
|
||||||
|
|
||||||
|
_touchLocXPending = _touchLocXProcessing = _touchLocXApplied = 0;
|
||||||
|
_touchLocYPending = _touchLocYProcessing = _touchLocYApplied = 0;
|
||||||
|
_touchPressurePending = _touchPressureProcessing = _touchPressureApplied = 50;
|
||||||
|
_paddleValuePending = _paddleValueProcessing = _paddleValueApplied = 0;
|
||||||
|
_paddleAdjustPending = _paddleAdjustProcessing = _paddleAdjustApplied = 0;
|
||||||
|
|
||||||
|
_softwareMicSampleGeneratorPending = _softwareMicSampleGeneratorProcessing = _softwareMicSampleGeneratorApplied = _nullSampleGenerator;
|
||||||
|
|
||||||
_needResetFramesToSkip = false;
|
_needResetFramesToSkip = false;
|
||||||
|
|
||||||
_frameTime = 0.0;
|
_frameTime = 0.0;
|
||||||
|
@ -83,9 +101,65 @@ ClientExecutionControl::ClientExecutionControl()
|
||||||
_cpuEmulationEngineNameOut = _ndsFrameInfo.cpuEmulationEngineName;
|
_cpuEmulationEngineNameOut = _ndsFrameInfo.cpuEmulationEngineName;
|
||||||
_slot1DeviceNameOut = _ndsFrameInfo.slot1DeviceName;
|
_slot1DeviceNameOut = _ndsFrameInfo.slot1DeviceName;
|
||||||
|
|
||||||
|
memset(_clientInputPending, 0, sizeof(_clientInputPending));
|
||||||
|
memset(_clientInputProcessing, 0, sizeof(_clientInputProcessing));
|
||||||
|
memset(_clientInputApplied, 0, sizeof(_clientInputApplied));
|
||||||
|
|
||||||
|
_userInputMap[NDSInputID_Debug] = 0;
|
||||||
|
_userInputMap[NDSInputID_R] = 1;
|
||||||
|
_userInputMap[NDSInputID_L] = 2;
|
||||||
|
_userInputMap[NDSInputID_X] = 3;
|
||||||
|
_userInputMap[NDSInputID_Y] = 4;
|
||||||
|
_userInputMap[NDSInputID_A] = 5;
|
||||||
|
_userInputMap[NDSInputID_B] = 6;
|
||||||
|
_userInputMap[NDSInputID_Start] = 7;
|
||||||
|
_userInputMap[NDSInputID_Select] = 8;
|
||||||
|
_userInputMap[NDSInputID_Up] = 9;
|
||||||
|
_userInputMap[NDSInputID_Down] = 10;
|
||||||
|
_userInputMap[NDSInputID_Left] = 11;
|
||||||
|
_userInputMap[NDSInputID_Right] = 12;
|
||||||
|
_userInputMap[NDSInputID_Lid] = 13;
|
||||||
|
|
||||||
|
_inputStateBitMap[NDSInputID_A] = NDSInputStateBit_A;
|
||||||
|
_inputStateBitMap[NDSInputID_B] = NDSInputStateBit_B;
|
||||||
|
_inputStateBitMap[NDSInputID_Select] = NDSInputStateBit_Select;
|
||||||
|
_inputStateBitMap[NDSInputID_Start] = NDSInputStateBit_Start;
|
||||||
|
_inputStateBitMap[NDSInputID_Right] = NDSInputStateBit_Right;
|
||||||
|
_inputStateBitMap[NDSInputID_Left] = NDSInputStateBit_Left;
|
||||||
|
_inputStateBitMap[NDSInputID_Up] = NDSInputStateBit_Up;
|
||||||
|
_inputStateBitMap[NDSInputID_Down] = NDSInputStateBit_Down;
|
||||||
|
_inputStateBitMap[NDSInputID_R] = NDSInputStateBit_R;
|
||||||
|
_inputStateBitMap[NDSInputID_L] = NDSInputStateBit_L;
|
||||||
|
_inputStateBitMap[NDSInputID_X] = NDSInputStateBit_X;
|
||||||
|
_inputStateBitMap[NDSInputID_Y] = NDSInputStateBit_Y;
|
||||||
|
_inputStateBitMap[NDSInputID_Debug] = NDSInputStateBit_Debug;
|
||||||
|
_inputStateBitMap[NDSInputID_Touch] = NDSInputStateBit_Touch;
|
||||||
|
_inputStateBitMap[NDSInputID_Lid] = NDSInputStateBit_Lid;
|
||||||
|
_inputStateBitMap[NDSInputID_Piano_C] = NDSInputStateBit_Piano_C;
|
||||||
|
_inputStateBitMap[NDSInputID_Piano_CSharp] = NDSInputStateBit_Piano_CSharp;
|
||||||
|
_inputStateBitMap[NDSInputID_Piano_D] = NDSInputStateBit_Piano_D;
|
||||||
|
_inputStateBitMap[NDSInputID_Piano_DSharp] = NDSInputStateBit_Piano_DSharp;
|
||||||
|
_inputStateBitMap[NDSInputID_Piano_E] = NDSInputStateBit_Piano_E;
|
||||||
|
_inputStateBitMap[NDSInputID_Piano_F] = NDSInputStateBit_Piano_F;
|
||||||
|
_inputStateBitMap[NDSInputID_Piano_FSharp] = NDSInputStateBit_Piano_FSharp;
|
||||||
|
_inputStateBitMap[NDSInputID_Piano_G] = NDSInputStateBit_Piano_G;
|
||||||
|
_inputStateBitMap[NDSInputID_Piano_GSharp] = NDSInputStateBit_Piano_GSharp;
|
||||||
|
_inputStateBitMap[NDSInputID_Piano_A] = NDSInputStateBit_Piano_A;
|
||||||
|
_inputStateBitMap[NDSInputID_Piano_ASharp] = NDSInputStateBit_Piano_ASharp;
|
||||||
|
_inputStateBitMap[NDSInputID_Piano_B] = NDSInputStateBit_Piano_B;
|
||||||
|
_inputStateBitMap[NDSInputID_Piano_HighC] = NDSInputStateBit_Piano_HighC;
|
||||||
|
_inputStateBitMap[NDSInputID_GuitarGrip_Green] = NDSInputStateBit_GuitarGrip_Green;
|
||||||
|
_inputStateBitMap[NDSInputID_GuitarGrip_Red] = NDSInputStateBit_GuitarGrip_Red;
|
||||||
|
_inputStateBitMap[NDSInputID_GuitarGrip_Yellow] = NDSInputStateBit_GuitarGrip_Yellow;
|
||||||
|
_inputStateBitMap[NDSInputID_GuitarGrip_Blue] = NDSInputStateBit_GuitarGrip_Blue;
|
||||||
|
_inputStateBitMap[NDSInputID_Paddle] = NDSInputStateBit_Paddle;
|
||||||
|
_inputStateBitMap[NDSInputID_Microphone] = NDSInputStateBit_Microphone;
|
||||||
|
_inputStateBitMap[NDSInputID_Reset] = NDSInputStateBit_Reset;
|
||||||
|
|
||||||
pthread_mutex_init(&_mutexSettingsPendingOnReset, NULL);
|
pthread_mutex_init(&_mutexSettingsPendingOnReset, NULL);
|
||||||
pthread_mutex_init(&_mutexSettingsPendingOnExecutionLoopStart, NULL);
|
pthread_mutex_init(&_mutexSettingsPendingOnExecutionLoopStart, NULL);
|
||||||
pthread_mutex_init(&_mutexSettingsPendingOnNDSExec, NULL);
|
pthread_mutex_init(&_mutexSettingsPendingOnNDSExec, NULL);
|
||||||
|
pthread_mutex_init(&_mutexInputsPending, NULL);
|
||||||
pthread_mutex_init(&_mutexOutputPostNDSExec, NULL);
|
pthread_mutex_init(&_mutexOutputPostNDSExec, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,7 +168,13 @@ ClientExecutionControl::~ClientExecutionControl()
|
||||||
pthread_mutex_destroy(&this->_mutexSettingsPendingOnReset);
|
pthread_mutex_destroy(&this->_mutexSettingsPendingOnReset);
|
||||||
pthread_mutex_destroy(&this->_mutexSettingsPendingOnExecutionLoopStart);
|
pthread_mutex_destroy(&this->_mutexSettingsPendingOnExecutionLoopStart);
|
||||||
pthread_mutex_destroy(&this->_mutexSettingsPendingOnNDSExec);
|
pthread_mutex_destroy(&this->_mutexSettingsPendingOnNDSExec);
|
||||||
|
pthread_mutex_destroy(&this->_mutexInputsPending);
|
||||||
pthread_mutex_destroy(&this->_mutexOutputPostNDSExec);
|
pthread_mutex_destroy(&this->_mutexOutputPostNDSExec);
|
||||||
|
|
||||||
|
delete this->_nullSampleGenerator;
|
||||||
|
delete this->_internalNoiseGenerator;
|
||||||
|
delete this->_whiteNoiseGenerator;
|
||||||
|
delete this->_sineWaveGenerator;
|
||||||
}
|
}
|
||||||
|
|
||||||
CPUEmulationEngineID ClientExecutionControl::GetCPUEmulationEngineID()
|
CPUEmulationEngineID ClientExecutionControl::GetCPUEmulationEngineID()
|
||||||
|
@ -118,7 +198,7 @@ const char* ClientExecutionControl::GetCPUEmulationEngineName()
|
||||||
void ClientExecutionControl::SetCPUEmulationEngineByID(CPUEmulationEngineID engineID)
|
void ClientExecutionControl::SetCPUEmulationEngineByID(CPUEmulationEngineID engineID)
|
||||||
{
|
{
|
||||||
#if !defined(__i386__) && !defined(__x86_64__)
|
#if !defined(__i386__) && !defined(__x86_64__)
|
||||||
engineID = CPUEmulationEngine_Interpreter;
|
engineID = CPUEmulationEngineID_Interpreter;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
pthread_mutex_lock(&this->_mutexSettingsPendingOnReset);
|
pthread_mutex_lock(&this->_mutexSettingsPendingOnReset);
|
||||||
|
@ -832,6 +912,406 @@ void ClientExecutionControl::ApplySettingsOnNDSExec()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ClientExecutionControl::GetEnableAutohold()
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&this->_mutexInputsPending);
|
||||||
|
const bool enable = this->_enableAutohold;
|
||||||
|
pthread_mutex_unlock(&this->_mutexInputsPending);
|
||||||
|
|
||||||
|
return enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientExecutionControl::SetEnableAutohold(bool enable)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&this->_mutexInputsPending);
|
||||||
|
this->_enableAutohold = enable;
|
||||||
|
pthread_mutex_unlock(&this->_mutexInputsPending);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientExecutionControl::ClearAutohold()
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&this->_mutexInputsPending);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < NDSInputID_InputCount; i++)
|
||||||
|
{
|
||||||
|
this->_clientInputPending[i].autohold = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&this->_mutexInputsPending);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientExecutionControl::SetClientInputStateUsingID(NDSInputID inputID, bool pressedState)
|
||||||
|
{
|
||||||
|
this->SetClientInputStateUsingID(inputID, pressedState, false, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientExecutionControl::SetClientInputStateUsingID(NDSInputID inputID, bool pressedState, bool isTurboEnabled, uint32_t turboPattern, uint32_t turboPatternLength)
|
||||||
|
{
|
||||||
|
if (inputID >= NDSInputID_InputCount)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_lock(&this->_mutexInputsPending);
|
||||||
|
|
||||||
|
if (this->_enableAutohold && pressedState)
|
||||||
|
{
|
||||||
|
this->_clientInputPending[inputID].autohold = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->_clientInputPending[inputID].isPressed = pressedState;
|
||||||
|
this->_clientInputPending[inputID].turbo = isTurboEnabled;
|
||||||
|
this->_clientInputPending[inputID].turboPattern = turboPattern;
|
||||||
|
this->_clientInputPending[inputID].turboPatternLength = (turboPatternLength > 32) ? 32 : turboPatternLength;
|
||||||
|
|
||||||
|
const uint64_t bitValue = (1 << _inputStateBitMap[inputID]);
|
||||||
|
this->_ndsFrameInfo.inputStatesPending.value = (this->_clientInputPending[inputID].isPressed) ? this->_ndsFrameInfo.inputStatesPending.value & ~bitValue : this->_ndsFrameInfo.inputStatesPending.value | bitValue;
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&this->_mutexInputsPending);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientExecutionControl::SetClientTouchState(bool pressedState, uint8_t touchLocX, uint8_t touchLocY, uint8_t touchPressure)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&this->_mutexInputsPending);
|
||||||
|
|
||||||
|
this->_clientInputPending[NDSInputID_Touch].isPressed = pressedState;
|
||||||
|
this->_touchLocXPending = touchLocX;
|
||||||
|
this->_touchLocYPending = touchLocY;
|
||||||
|
this->_touchPressurePending = touchPressure;
|
||||||
|
|
||||||
|
this->_ndsFrameInfo.inputStatesPending.Touch = (this->_clientInputPending[NDSInputID_Touch].isPressed) ? 0 : 1;
|
||||||
|
this->_ndsFrameInfo.touchLocXPending = this->_touchLocXPending;
|
||||||
|
this->_ndsFrameInfo.touchLocYPending = this->_touchLocYPending;
|
||||||
|
this->_ndsFrameInfo.touchPressurePending = this->_touchPressurePending;
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&this->_mutexInputsPending);
|
||||||
|
}
|
||||||
|
|
||||||
|
double ClientExecutionControl::GetSineWaveFrequency()
|
||||||
|
{
|
||||||
|
return this->_sineWaveGenerator->getFrequency();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientExecutionControl::SetSineWaveFrequency(double freq)
|
||||||
|
{
|
||||||
|
this->_sineWaveGenerator->setFrequency(freq);
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioGenerator* ClientExecutionControl::GetClientSoftwareMicSampleGenerator()
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&this->_mutexInputsPending);
|
||||||
|
AudioGenerator *softwareMicSampleGenerator = this->_softwareMicSampleGeneratorPending;
|
||||||
|
pthread_mutex_unlock(&this->_mutexInputsPending);
|
||||||
|
|
||||||
|
return softwareMicSampleGenerator;
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioGenerator* ClientExecutionControl::GetClientSoftwareMicSampleGeneratorApplied()
|
||||||
|
{
|
||||||
|
return this->_softwareMicSampleGeneratorApplied;
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioSampleBlockGenerator* ClientExecutionControl::GetClientSelectedAudioFileGenerator()
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&this->_mutexInputsPending);
|
||||||
|
AudioSampleBlockGenerator *selectedAudioFileGenerator = this->_selectedAudioFileGenerator;
|
||||||
|
pthread_mutex_unlock(&this->_mutexInputsPending);
|
||||||
|
|
||||||
|
return selectedAudioFileGenerator;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientExecutionControl::SetClientSelectedAudioFileGenerator(AudioSampleBlockGenerator *selectedAudioFileGenerator)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&this->_mutexInputsPending);
|
||||||
|
this->_selectedAudioFileGenerator = selectedAudioFileGenerator;
|
||||||
|
pthread_mutex_unlock(&this->_mutexInputsPending);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ClientExecutionControl::GetClientSoftwareMicState()
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&this->_mutexInputsPending);
|
||||||
|
const bool isPressed = this->_clientInputPending[NDSInputID_Microphone].isPressed;
|
||||||
|
pthread_mutex_unlock(&this->_mutexInputsPending);
|
||||||
|
|
||||||
|
return isPressed;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ClientExecutionControl::GetClientSoftwareMicStateApplied()
|
||||||
|
{
|
||||||
|
return this->_clientInputApplied[NDSInputID_Microphone].isPressed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientExecutionControl::SetClientSoftwareMicState(bool pressedState, MicrophoneMode micMode)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&this->_mutexInputsPending);
|
||||||
|
|
||||||
|
this->_clientInputPending[NDSInputID_Microphone].isPressed = pressedState;
|
||||||
|
this->_ndsFrameInfo.inputStatesPending.Microphone = (this->_clientInputPending[NDSInputID_Microphone].isPressed) ? 0 : 1;
|
||||||
|
|
||||||
|
if (pressedState)
|
||||||
|
{
|
||||||
|
switch (micMode)
|
||||||
|
{
|
||||||
|
case MicrophoneMode_InternalNoise:
|
||||||
|
this->_softwareMicSampleGeneratorPending = this->_internalNoiseGenerator;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MicrophoneMode_WhiteNoise:
|
||||||
|
this->_softwareMicSampleGeneratorPending = this->_whiteNoiseGenerator;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MicrophoneMode_SineWave:
|
||||||
|
this->_softwareMicSampleGeneratorPending = this->_sineWaveGenerator;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MicrophoneMode_AudioFile:
|
||||||
|
if (this->_selectedAudioFileGenerator != NULL)
|
||||||
|
{
|
||||||
|
this->_softwareMicSampleGeneratorPending = this->_selectedAudioFileGenerator;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
this->_softwareMicSampleGeneratorPending = this->_nullSampleGenerator;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->_softwareMicSampleGeneratorPending = this->_nullSampleGenerator;
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&this->_mutexInputsPending);
|
||||||
|
}
|
||||||
|
|
||||||
|
int16_t ClientExecutionControl::GetClientPaddleAdjust()
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&this->_mutexInputsPending);
|
||||||
|
const int16_t paddleAdjust = this->_paddleAdjustPending;
|
||||||
|
pthread_mutex_unlock(&this->_mutexInputsPending);
|
||||||
|
|
||||||
|
return paddleAdjust;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientExecutionControl::SetClientPaddleAdjust(int16_t paddleAdjust)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&this->_mutexInputsPending);
|
||||||
|
|
||||||
|
this->_paddleAdjustPending = paddleAdjust;
|
||||||
|
this->_paddleValuePending = this->_paddleValueApplied + paddleAdjust;
|
||||||
|
this->_ndsFrameInfo.paddleValuePending = this->_paddleValuePending;
|
||||||
|
this->_ndsFrameInfo.paddleAdjustPending = this->_paddleAdjustPending;
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&this->_mutexInputsPending);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientExecutionControl::ProcessInputs()
|
||||||
|
{
|
||||||
|
// Before we begin input processing, we need to send all pending inputs to the core code.
|
||||||
|
pthread_mutex_lock(&this->_mutexInputsPending);
|
||||||
|
|
||||||
|
NDS_setPad(this->_clientInputPending[NDSInputID_Right].isPressed,
|
||||||
|
this->_clientInputPending[NDSInputID_Left].isPressed,
|
||||||
|
this->_clientInputPending[NDSInputID_Down].isPressed,
|
||||||
|
this->_clientInputPending[NDSInputID_Up].isPressed,
|
||||||
|
this->_clientInputPending[NDSInputID_Select].isPressed,
|
||||||
|
this->_clientInputPending[NDSInputID_Start].isPressed,
|
||||||
|
this->_clientInputPending[NDSInputID_B].isPressed,
|
||||||
|
this->_clientInputPending[NDSInputID_A].isPressed,
|
||||||
|
this->_clientInputPending[NDSInputID_Y].isPressed,
|
||||||
|
this->_clientInputPending[NDSInputID_X].isPressed,
|
||||||
|
this->_clientInputPending[NDSInputID_L].isPressed,
|
||||||
|
this->_clientInputPending[NDSInputID_R].isPressed,
|
||||||
|
this->_clientInputPending[NDSInputID_Debug].isPressed,
|
||||||
|
this->_clientInputPending[NDSInputID_Lid].isPressed);
|
||||||
|
|
||||||
|
if (this->_clientInputPending[NDSInputID_Touch].isPressed)
|
||||||
|
{
|
||||||
|
NDS_setTouchPos((u16)this->_touchLocXPending, (u16)this->_touchLocYPending);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NDS_releaseTouch();
|
||||||
|
}
|
||||||
|
|
||||||
|
NDS_setMic(this->_clientInputPending[NDSInputID_Microphone].isPressed);
|
||||||
|
|
||||||
|
// Copy all pending inputs for further processing.
|
||||||
|
for (size_t i = 0; i < NDSInputID_InputCount; i++)
|
||||||
|
{
|
||||||
|
this->_clientInputProcessing[i].isPressed = this->_clientInputPending[i].isPressed;
|
||||||
|
this->_clientInputProcessing[i].autohold = this->_clientInputPending[i].autohold;
|
||||||
|
this->_clientInputProcessing[i].turbo = this->_clientInputPending[i].turbo;
|
||||||
|
|
||||||
|
if ( (this->_clientInputProcessing[i].turboPattern != this->_clientInputPending[i].turboPattern) ||
|
||||||
|
(this->_clientInputProcessing[i].turboPatternLength != this->_clientInputPending[i].turboPatternLength) )
|
||||||
|
{
|
||||||
|
this->_clientInputProcessing[i].turboPatternStep = 0;
|
||||||
|
this->_clientInputProcessing[i].turboPattern = this->_clientInputPending[i].turboPattern;
|
||||||
|
this->_clientInputProcessing[i].turboPatternLength = this->_clientInputPending[i].turboPatternLength;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this->_touchLocXProcessing = this->_touchLocXPending;
|
||||||
|
this->_touchLocYProcessing = this->_touchLocYPending;
|
||||||
|
this->_touchPressureProcessing = this->_touchPressurePending;
|
||||||
|
this->_paddleAdjustProcessing = this->_paddleAdjustPending;
|
||||||
|
this->_paddleValueProcessing = this->_paddleValuePending;
|
||||||
|
this->_softwareMicSampleGeneratorProcessing = this->_softwareMicSampleGeneratorPending;
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&this->_mutexInputsPending);
|
||||||
|
|
||||||
|
// Begin processing the input based on current parameters.
|
||||||
|
NDS_beginProcessingInput();
|
||||||
|
UserInput &processedInput = NDS_getProcessingUserInput();
|
||||||
|
|
||||||
|
if (movieMode == MOVIEMODE_PLAY)
|
||||||
|
{
|
||||||
|
FCEUMOV_HandlePlayback();
|
||||||
|
|
||||||
|
this->_clientInputProcessing[NDSInputID_A].isPressed = processedInput.buttons.A;
|
||||||
|
this->_clientInputProcessing[NDSInputID_B].isPressed = processedInput.buttons.B;
|
||||||
|
this->_clientInputProcessing[NDSInputID_Select].isPressed = processedInput.buttons.T;
|
||||||
|
this->_clientInputProcessing[NDSInputID_Start].isPressed = processedInput.buttons.S;
|
||||||
|
this->_clientInputProcessing[NDSInputID_Right].isPressed = processedInput.buttons.R;
|
||||||
|
this->_clientInputProcessing[NDSInputID_Left].isPressed = processedInput.buttons.L;
|
||||||
|
this->_clientInputProcessing[NDSInputID_Up].isPressed = processedInput.buttons.U;
|
||||||
|
this->_clientInputProcessing[NDSInputID_Down].isPressed = processedInput.buttons.D;
|
||||||
|
this->_clientInputProcessing[NDSInputID_R].isPressed = processedInput.buttons.E;
|
||||||
|
this->_clientInputProcessing[NDSInputID_L].isPressed = processedInput.buttons.W;
|
||||||
|
this->_clientInputProcessing[NDSInputID_X].isPressed = processedInput.buttons.X;
|
||||||
|
this->_clientInputProcessing[NDSInputID_Y].isPressed = processedInput.buttons.Y;
|
||||||
|
this->_clientInputProcessing[NDSInputID_Debug].isPressed = processedInput.buttons.G;
|
||||||
|
this->_clientInputProcessing[NDSInputID_Touch].isPressed = processedInput.touch.isTouch;
|
||||||
|
this->_clientInputProcessing[NDSInputID_Lid].isPressed = processedInput.buttons.F;
|
||||||
|
this->_clientInputProcessing[NDSInputID_Microphone].isPressed = (processedInput.mic.micButtonPressed != 0);
|
||||||
|
|
||||||
|
this->_touchLocXProcessing = processedInput.touch.touchX >> 4;
|
||||||
|
this->_touchLocYProcessing = processedInput.touch.touchY >> 4;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (this->GetExecutionBehaviorApplied() != ExecutionBehavior_FrameJump)
|
||||||
|
{
|
||||||
|
size_t i = 0;
|
||||||
|
|
||||||
|
// First process the inputs that exist in the core code's UserInput struct. The core code will
|
||||||
|
// use this struct for its own purposes later.
|
||||||
|
for (; i <= NDSInputID_Lid; i++)
|
||||||
|
{
|
||||||
|
bool &pressedState = (i != NDSInputID_Touch) ? processedInput.buttons.array[this->_userInputMap[(NDSInputID)i]] : processedInput.touch.isTouch;
|
||||||
|
pressedState = (this->_clientInputProcessing[i].isPressed || this->_clientInputProcessing[i].autohold);
|
||||||
|
this->_clientInputProcessing[i].isPressed = pressedState;
|
||||||
|
|
||||||
|
if (this->_clientInputProcessing[i].turbo)
|
||||||
|
{
|
||||||
|
const bool turboPressedState = ( ((this->_clientInputProcessing[i].turboPattern >> this->_clientInputProcessing[i].turboPatternStep) & 0x00000001) == 1 );
|
||||||
|
pressedState = (pressedState && turboPressedState);
|
||||||
|
this->_clientInputProcessing[i].isPressed = pressedState;
|
||||||
|
|
||||||
|
this->_clientInputProcessing[i].turboPatternStep++;
|
||||||
|
if (this->_clientInputProcessing[i].turboPatternStep >= this->_clientInputProcessing[i].turboPatternLength)
|
||||||
|
{
|
||||||
|
this->_clientInputProcessing[i].turboPatternStep = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process the remaining inputs.
|
||||||
|
for (i = NDSInputID_Piano_C; i < NDSInputID_InputCount; i++)
|
||||||
|
{
|
||||||
|
bool &pressedState = this->_clientInputProcessing[i].isPressed;
|
||||||
|
pressedState = (this->_clientInputProcessing[i].isPressed || this->_clientInputProcessing[i].autohold);
|
||||||
|
|
||||||
|
if (this->_clientInputProcessing[i].turbo)
|
||||||
|
{
|
||||||
|
const bool turboPressedState = ( ((this->_clientInputProcessing[i].turboPattern >> this->_clientInputProcessing[i].turboPatternStep) & 0x00000001) == 1 );
|
||||||
|
pressedState = (pressedState && turboPressedState);
|
||||||
|
|
||||||
|
this->_clientInputProcessing[i].turboPatternStep++;
|
||||||
|
if (this->_clientInputProcessing[i].turboPatternStep >= this->_clientInputProcessing[i].turboPatternLength)
|
||||||
|
{
|
||||||
|
this->_clientInputProcessing[i].turboPatternStep = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memset(&processedInput, 0, sizeof(UserInput));
|
||||||
|
memset(this->_clientInputProcessing, 0, sizeof(this->_clientInputProcessing));
|
||||||
|
|
||||||
|
this->_softwareMicSampleGeneratorProcessing = this->_nullSampleGenerator;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientExecutionControl::ApplyInputs()
|
||||||
|
{
|
||||||
|
NDS_endProcessingInput();
|
||||||
|
|
||||||
|
this->_touchLocXApplied = this->_touchLocXProcessing;
|
||||||
|
this->_touchLocYApplied = this->_touchLocYProcessing;
|
||||||
|
this->_touchPressureApplied = this->_touchPressureProcessing;
|
||||||
|
this->_paddleAdjustApplied = this->_paddleAdjustProcessing;
|
||||||
|
this->_paddleValueApplied = this->_paddleValueProcessing;
|
||||||
|
|
||||||
|
memcpy(this->_clientInputApplied, this->_clientInputProcessing, sizeof(this->_clientInputProcessing));
|
||||||
|
CommonSettings.StylusPressure = (int)this->_touchPressureApplied;
|
||||||
|
this->_softwareMicSampleGeneratorApplied = this->_softwareMicSampleGeneratorProcessing;
|
||||||
|
|
||||||
|
if (!this->_clientInputApplied[NDSInputID_Microphone].isPressed)
|
||||||
|
{
|
||||||
|
this->_internalNoiseGenerator->setSamplePosition(0);
|
||||||
|
this->_sineWaveGenerator->setCyclePosition(0.0);
|
||||||
|
|
||||||
|
if (this->_selectedAudioFileGenerator != NULL)
|
||||||
|
{
|
||||||
|
this->_selectedAudioFileGenerator->setSamplePosition(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup the inputs from SLOT-2 devices.
|
||||||
|
const NDS_SLOT2_TYPE slot2DeviceType = slot2_GetSelectedType();
|
||||||
|
switch (slot2DeviceType)
|
||||||
|
{
|
||||||
|
case NDS_SLOT2_GUITARGRIP:
|
||||||
|
guitarGrip_setKey(this->_clientInputApplied[NDSInputID_GuitarGrip_Green].isPressed,
|
||||||
|
this->_clientInputApplied[NDSInputID_GuitarGrip_Red].isPressed,
|
||||||
|
this->_clientInputApplied[NDSInputID_GuitarGrip_Yellow].isPressed,
|
||||||
|
this->_clientInputApplied[NDSInputID_GuitarGrip_Blue].isPressed);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NDS_SLOT2_EASYPIANO:
|
||||||
|
piano_setKey(this->_clientInputApplied[NDSInputID_Piano_C].isPressed,
|
||||||
|
this->_clientInputApplied[NDSInputID_Piano_CSharp].isPressed,
|
||||||
|
this->_clientInputApplied[NDSInputID_Piano_D].isPressed,
|
||||||
|
this->_clientInputApplied[NDSInputID_Piano_DSharp].isPressed,
|
||||||
|
this->_clientInputApplied[NDSInputID_Piano_E].isPressed,
|
||||||
|
this->_clientInputApplied[NDSInputID_Piano_F].isPressed,
|
||||||
|
this->_clientInputApplied[NDSInputID_Piano_FSharp].isPressed,
|
||||||
|
this->_clientInputApplied[NDSInputID_Piano_G].isPressed,
|
||||||
|
this->_clientInputApplied[NDSInputID_Piano_GSharp].isPressed,
|
||||||
|
this->_clientInputApplied[NDSInputID_Piano_A].isPressed,
|
||||||
|
this->_clientInputApplied[NDSInputID_Piano_ASharp].isPressed,
|
||||||
|
this->_clientInputApplied[NDSInputID_Piano_B].isPressed,
|
||||||
|
this->_clientInputApplied[NDSInputID_Piano_HighC].isPressed);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NDS_SLOT2_PADDLE:
|
||||||
|
Paddle_SetValue((uint16_t)this->_paddleValueApplied);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (movieMode == MOVIEMODE_RECORD)
|
||||||
|
{
|
||||||
|
FCEUMOV_HandleRecording();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ClientExecutionControl::FetchOutputPostNDSExec()
|
void ClientExecutionControl::FetchOutputPostNDSExec()
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&this->_mutexOutputPostNDSExec);
|
pthread_mutex_lock(&this->_mutexOutputPostNDSExec);
|
||||||
|
@ -850,48 +1330,47 @@ void ClientExecutionControl::FetchOutputPostNDSExec()
|
||||||
this->_ndsFrameInfo.rtcString = tempBuffer;
|
this->_ndsFrameInfo.rtcString = tempBuffer;
|
||||||
free(tempBuffer);
|
free(tempBuffer);
|
||||||
|
|
||||||
const UserInput &ndsInputsPending = NDS_getRawUserInput();
|
this->_ndsFrameInfo.inputStatesApplied.value = INPUT_STATES_CLEAR_VALUE;
|
||||||
const UserInput &ndsInputsApplied = NDS_getFinalUserInput();
|
this->_ndsFrameInfo.inputStatesApplied.A = (this->_clientInputApplied[NDSInputID_A].isPressed) ? 0 : 1;
|
||||||
|
this->_ndsFrameInfo.inputStatesApplied.B = (this->_clientInputApplied[NDSInputID_B].isPressed) ? 0 : 1;
|
||||||
this->_ndsFrameInfo.inputStatesPending.value = INPUT_STATES_CLEAR_VALUE;
|
this->_ndsFrameInfo.inputStatesApplied.Select = (this->_clientInputApplied[NDSInputID_Select].isPressed) ? 0 : 1;
|
||||||
this->_ndsFrameInfo.inputStatesPending.A = (ndsInputsPending.buttons.A) ? 0 : 1;
|
this->_ndsFrameInfo.inputStatesApplied.Start = (this->_clientInputApplied[NDSInputID_Start].isPressed) ? 0 : 1;
|
||||||
this->_ndsFrameInfo.inputStatesPending.B = (ndsInputsPending.buttons.B) ? 0 : 1;
|
this->_ndsFrameInfo.inputStatesApplied.Right = (this->_clientInputApplied[NDSInputID_Right].isPressed) ? 0 : 1;
|
||||||
this->_ndsFrameInfo.inputStatesPending.Select = (ndsInputsPending.buttons.T) ? 0 : 1;
|
this->_ndsFrameInfo.inputStatesApplied.Left = (this->_clientInputApplied[NDSInputID_Left].isPressed) ? 0 : 1;
|
||||||
this->_ndsFrameInfo.inputStatesPending.Start = (ndsInputsPending.buttons.S) ? 0 : 1;
|
this->_ndsFrameInfo.inputStatesApplied.Up = (this->_clientInputApplied[NDSInputID_Up].isPressed) ? 0 : 1;
|
||||||
this->_ndsFrameInfo.inputStatesPending.Right = (ndsInputsPending.buttons.R) ? 0 : 1;
|
this->_ndsFrameInfo.inputStatesApplied.Down = (this->_clientInputApplied[NDSInputID_Down].isPressed) ? 0 : 1;
|
||||||
this->_ndsFrameInfo.inputStatesPending.Left = (ndsInputsPending.buttons.L) ? 0 : 1;
|
this->_ndsFrameInfo.inputStatesApplied.R = (this->_clientInputApplied[NDSInputID_R].isPressed) ? 0 : 1;
|
||||||
this->_ndsFrameInfo.inputStatesPending.Up = (ndsInputsPending.buttons.U) ? 0 : 1;
|
this->_ndsFrameInfo.inputStatesApplied.L = (this->_clientInputApplied[NDSInputID_L].isPressed) ? 0 : 1;
|
||||||
this->_ndsFrameInfo.inputStatesPending.Down = (ndsInputsPending.buttons.D) ? 0 : 1;
|
this->_ndsFrameInfo.inputStatesApplied.X = (this->_clientInputApplied[NDSInputID_X].isPressed) ? 0 : 1;
|
||||||
this->_ndsFrameInfo.inputStatesPending.R = (ndsInputsPending.buttons.E) ? 0 : 1;
|
this->_ndsFrameInfo.inputStatesApplied.Y = (this->_clientInputApplied[NDSInputID_Y].isPressed) ? 0 : 1;
|
||||||
this->_ndsFrameInfo.inputStatesPending.L = (ndsInputsPending.buttons.W) ? 0 : 1;
|
this->_ndsFrameInfo.inputStatesApplied.Debug = (this->_clientInputApplied[NDSInputID_Debug].isPressed) ? 0 : 1;
|
||||||
this->_ndsFrameInfo.inputStatesPending.X = (ndsInputsPending.buttons.X) ? 0 : 1;
|
this->_ndsFrameInfo.inputStatesApplied.Touch = (this->_clientInputApplied[NDSInputID_Touch].isPressed) ? 0 : 1;
|
||||||
this->_ndsFrameInfo.inputStatesPending.Y = (ndsInputsPending.buttons.Y) ? 0 : 1;
|
this->_ndsFrameInfo.inputStatesApplied.Lid = (this->_clientInputApplied[NDSInputID_Lid].isPressed) ? 0 : 1;
|
||||||
this->_ndsFrameInfo.inputStatesPending.Debug = (ndsInputsPending.buttons.G) ? 0 : 1;
|
this->_ndsFrameInfo.inputStatesApplied.PianoC = (this->_clientInputApplied[NDSInputID_Piano_C].isPressed) ? 0 : 1;
|
||||||
this->_ndsFrameInfo.inputStatesPending.Touch = (ndsInputsPending.touch.isTouch) ? 0 : 1;
|
this->_ndsFrameInfo.inputStatesApplied.PianoCSharp = (this->_clientInputApplied[NDSInputID_Piano_CSharp].isPressed) ? 0 : 1;
|
||||||
this->_ndsFrameInfo.inputStatesPending.Lid = (ndsInputsPending.buttons.F) ? 0 : 1;
|
this->_ndsFrameInfo.inputStatesApplied.PianoD = (this->_clientInputApplied[NDSInputID_Piano_D].isPressed) ? 0 : 1;
|
||||||
this->_ndsFrameInfo.inputStatesPending.Microphone = (ndsInputsPending.mic.micButtonPressed != 0) ? 0 : 1;
|
this->_ndsFrameInfo.inputStatesApplied.PianoDSharp = (this->_clientInputApplied[NDSInputID_Piano_DSharp].isPressed) ? 0 : 1;
|
||||||
this->_ndsFrameInfo.touchLocXPending = ndsInputsPending.touch.touchX >> 4;
|
this->_ndsFrameInfo.inputStatesApplied.PianoE = (this->_clientInputApplied[NDSInputID_Piano_E].isPressed) ? 0 : 1;
|
||||||
this->_ndsFrameInfo.touchLocYPending = ndsInputsPending.touch.touchY >> 4;
|
this->_ndsFrameInfo.inputStatesApplied.PianoF = (this->_clientInputApplied[NDSInputID_Piano_F].isPressed) ? 0 : 1;
|
||||||
|
this->_ndsFrameInfo.inputStatesApplied.PianoFSharp = (this->_clientInputApplied[NDSInputID_Piano_FSharp].isPressed) ? 0 : 1;
|
||||||
this->_ndsFrameInfo.inputStatesApplied.value = INPUT_STATES_CLEAR_VALUE;
|
this->_ndsFrameInfo.inputStatesApplied.PianoG = (this->_clientInputApplied[NDSInputID_Piano_G].isPressed) ? 0 : 1;
|
||||||
this->_ndsFrameInfo.inputStatesApplied.A = (ndsInputsApplied.buttons.A) ? 0 : 1;
|
this->_ndsFrameInfo.inputStatesApplied.PianoGSharp = (this->_clientInputApplied[NDSInputID_Piano_GSharp].isPressed) ? 0 : 1;
|
||||||
this->_ndsFrameInfo.inputStatesApplied.B = (ndsInputsApplied.buttons.B) ? 0 : 1;
|
this->_ndsFrameInfo.inputStatesApplied.PianoA = (this->_clientInputApplied[NDSInputID_Piano_A].isPressed) ? 0 : 1;
|
||||||
this->_ndsFrameInfo.inputStatesApplied.Select = (ndsInputsApplied.buttons.T) ? 0 : 1;
|
this->_ndsFrameInfo.inputStatesApplied.PianoASharp = (this->_clientInputApplied[NDSInputID_Piano_ASharp].isPressed) ? 0 : 1;
|
||||||
this->_ndsFrameInfo.inputStatesApplied.Start = (ndsInputsApplied.buttons.S) ? 0 : 1;
|
this->_ndsFrameInfo.inputStatesApplied.PianoB = (this->_clientInputApplied[NDSInputID_Piano_B].isPressed) ? 0 : 1;
|
||||||
this->_ndsFrameInfo.inputStatesApplied.Right = (ndsInputsApplied.buttons.R) ? 0 : 1;
|
this->_ndsFrameInfo.inputStatesApplied.PianoHighC = (this->_clientInputApplied[NDSInputID_Piano_HighC].isPressed) ? 0 : 1;
|
||||||
this->_ndsFrameInfo.inputStatesApplied.Left = (ndsInputsApplied.buttons.L) ? 0 : 1;
|
this->_ndsFrameInfo.inputStatesApplied.GuitarGripBlue = (this->_clientInputApplied[NDSInputID_GuitarGrip_Blue].isPressed) ? 0 : 1;
|
||||||
this->_ndsFrameInfo.inputStatesApplied.Up = (ndsInputsApplied.buttons.U) ? 0 : 1;
|
this->_ndsFrameInfo.inputStatesApplied.GuitarGripYellow = (this->_clientInputApplied[NDSInputID_GuitarGrip_Yellow].isPressed) ? 0 : 1;
|
||||||
this->_ndsFrameInfo.inputStatesApplied.Down = (ndsInputsApplied.buttons.D) ? 0 : 1;
|
this->_ndsFrameInfo.inputStatesApplied.GuitarGripRed = (this->_clientInputApplied[NDSInputID_GuitarGrip_Red].isPressed) ? 0 : 1;
|
||||||
this->_ndsFrameInfo.inputStatesApplied.R = (ndsInputsApplied.buttons.E) ? 0 : 1;
|
this->_ndsFrameInfo.inputStatesApplied.GuitarGripGreen = (this->_clientInputApplied[NDSInputID_GuitarGrip_Green].isPressed) ? 0 : 1;
|
||||||
this->_ndsFrameInfo.inputStatesApplied.L = (ndsInputsApplied.buttons.W) ? 0 : 1;
|
this->_ndsFrameInfo.inputStatesApplied.Paddle = (this->_clientInputApplied[NDSInputID_Paddle].isPressed) ? 0 : 1;
|
||||||
this->_ndsFrameInfo.inputStatesApplied.X = (ndsInputsApplied.buttons.X) ? 0 : 1;
|
this->_ndsFrameInfo.inputStatesApplied.Microphone = (this->_clientInputApplied[NDSInputID_Microphone].isPressed) ? 0 : 1;
|
||||||
this->_ndsFrameInfo.inputStatesApplied.Y = (ndsInputsApplied.buttons.Y) ? 0 : 1;
|
this->_ndsFrameInfo.inputStatesApplied.Reset = (this->_clientInputApplied[NDSInputID_Reset].isPressed) ? 0 : 1;
|
||||||
this->_ndsFrameInfo.inputStatesApplied.Debug = (ndsInputsApplied.buttons.G) ? 0 : 1;
|
this->_ndsFrameInfo.touchLocXApplied = this->_touchLocXApplied;
|
||||||
this->_ndsFrameInfo.inputStatesApplied.Touch = (ndsInputsApplied.touch.isTouch) ? 0 : 1;
|
this->_ndsFrameInfo.touchLocYApplied = this->_touchLocYApplied;
|
||||||
this->_ndsFrameInfo.inputStatesApplied.Lid = (ndsInputsApplied.buttons.F) ? 0 : 1;
|
this->_ndsFrameInfo.touchPressureApplied = this->_touchPressureApplied;
|
||||||
this->_ndsFrameInfo.inputStatesApplied.Microphone = (ndsInputsApplied.mic.micButtonPressed != 0) ? 0 : 1;
|
this->_ndsFrameInfo.paddleValueApplied = this->_paddleValueApplied;
|
||||||
this->_ndsFrameInfo.touchLocXApplied = ndsInputsApplied.touch.touchX >> 4;
|
this->_ndsFrameInfo.paddleAdjustApplied = this->_paddleAdjustApplied;
|
||||||
this->_ndsFrameInfo.touchLocYApplied = ndsInputsApplied.touch.touchY >> 4;
|
|
||||||
|
|
||||||
pthread_mutex_unlock(&this->_mutexOutputPostNDSExec);
|
pthread_mutex_unlock(&this->_mutexOutputPostNDSExec);
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,28 +19,39 @@
|
||||||
#define _CLIENT_EXECUTION_CONTROL_H_
|
#define _CLIENT_EXECUTION_CONTROL_H_
|
||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "../../slot1.h"
|
#include "../../slot1.h"
|
||||||
#undef BOOL
|
#undef BOOL
|
||||||
|
|
||||||
#define SPEED_SCALAR_QUARTER 0.25 // Speed scalar for quarter execution speed.
|
#define SPEED_SCALAR_QUARTER 0.25 // Speed scalar for quarter execution speed.
|
||||||
#define SPEED_SCALAR_HALF 0.5 // Speed scalar for half execution speed.
|
#define SPEED_SCALAR_HALF 0.5 // Speed scalar for half execution speed.
|
||||||
#define SPEED_SCALAR_THREE_QUARTER 0.75 // Speed scalar for three quarters execution speed.
|
#define SPEED_SCALAR_THREE_QUARTER 0.75 // Speed scalar for three quarters execution speed.
|
||||||
#define SPEED_SCALAR_NORMAL 1.0 // Speed scalar for normal execution speed.
|
#define SPEED_SCALAR_NORMAL 1.0 // Speed scalar for normal execution speed.
|
||||||
#define SPEED_SCALAR_DOUBLE 2.0 // Speed scalar for double execution speed.
|
#define SPEED_SCALAR_DOUBLE 2.0 // Speed scalar for double execution speed.
|
||||||
#define SPEED_SCALAR_MIN 0.005 // Lower limit for the speed multiplier.
|
#define SPEED_SCALAR_MIN 0.005 // Lower limit for the speed multiplier.
|
||||||
|
|
||||||
#define DS_FRAMES_PER_SECOND 59.8261 // Number of DS frames per second.
|
#define DS_FRAMES_PER_SECOND 59.8261 // Number of DS frames per second.
|
||||||
#define DS_SECONDS_PER_FRAME (1.0 / DS_FRAMES_PER_SECOND) // The length of time in seconds that, ideally, a frame should be processed within.
|
#define DS_SECONDS_PER_FRAME (1.0 / DS_FRAMES_PER_SECOND) // The length of time in seconds that, ideally, a frame should be processed within.
|
||||||
|
|
||||||
#define FRAME_SKIP_AGGRESSIVENESS 9.0 // Must be a value between 0.0 (inclusive) and positive infinity.
|
#define FRAME_SKIP_AGGRESSIVENESS 9.0 // Must be a value between 0.0 (inclusive) and positive infinity.
|
||||||
// This value acts as a scalar multiple of the frame skip.
|
// This value acts as a scalar multiple of the frame skip.
|
||||||
#define FRAME_SKIP_BIAS 0.1 // May be any real number. This value acts as a vector addition to the frame skip.
|
#define FRAME_SKIP_BIAS 0.1 // May be any real number. This value acts as a vector addition to the frame skip.
|
||||||
#define MAX_FRAME_SKIP (DS_FRAMES_PER_SECOND / 2.98)
|
#define MAX_FRAME_SKIP (DS_FRAMES_PER_SECOND / 2.98)
|
||||||
|
|
||||||
#define INPUT_STATES_CLEAR_VALUE 0xFFFFFFFF00FF03FFULL
|
#define INPUT_STATES_CLEAR_VALUE 0xFFFFFFFF00FF03FFULL
|
||||||
|
|
||||||
|
#define MIC_SAMPLE_RATE 16000.0
|
||||||
|
#define MIC_SAMPLE_RESOLUTION 8 // Bits per sample; must be a multiple of 8
|
||||||
|
#define MIC_NUMBER_CHANNELS 1 // Number of channels
|
||||||
|
#define MIC_SAMPLE_SIZE ((MIC_SAMPLE_RESOLUTION / 8) * MIC_NUMBER_CHANNELS) // Bytes per sample, multiplied by the number of channels
|
||||||
|
#define MIC_MAX_BUFFER_SAMPLES ((MIC_SAMPLE_RATE / DS_FRAMES_PER_SECOND) * MIC_SAMPLE_SIZE)
|
||||||
|
#define MIC_CAPTURE_FRAMES 192 // The number of audio frames that the NDS microphone should pull. The lower this value, the lower the latency. Ensure that this value is not too low, or else audio frames may be lost.
|
||||||
|
#define MIC_NULL_LEVEL_THRESHOLD 2.5
|
||||||
|
#define MIC_CLIP_LEVEL_THRESHOLD 39.743665431525209 // ((2.0/pi) * MIC_NULL_SAMPLE_VALUE) - 1.0
|
||||||
|
#define MIC_NULL_SAMPLE_VALUE 64
|
||||||
|
|
||||||
enum ExecutionBehavior
|
enum ExecutionBehavior
|
||||||
{
|
{
|
||||||
ExecutionBehavior_Pause = 0,
|
ExecutionBehavior_Pause = 0,
|
||||||
|
@ -81,13 +92,6 @@ enum NDSInputID
|
||||||
NDSInputID_Touch,
|
NDSInputID_Touch,
|
||||||
NDSInputID_Lid,
|
NDSInputID_Lid,
|
||||||
|
|
||||||
NDSInputID_Microphone,
|
|
||||||
|
|
||||||
NDSInputID_GuitarGrip_Green,
|
|
||||||
NDSInputID_GuitarGrip_Red,
|
|
||||||
NDSInputID_GuitarGrip_Yellow,
|
|
||||||
NDSInputID_GuitarGrip_Blue,
|
|
||||||
|
|
||||||
NDSInputID_Piano_C,
|
NDSInputID_Piano_C,
|
||||||
NDSInputID_Piano_CSharp,
|
NDSInputID_Piano_CSharp,
|
||||||
NDSInputID_Piano_D,
|
NDSInputID_Piano_D,
|
||||||
|
@ -102,11 +106,81 @@ enum NDSInputID
|
||||||
NDSInputID_Piano_B,
|
NDSInputID_Piano_B,
|
||||||
NDSInputID_Piano_HighC,
|
NDSInputID_Piano_HighC,
|
||||||
|
|
||||||
|
NDSInputID_GuitarGrip_Green,
|
||||||
|
NDSInputID_GuitarGrip_Red,
|
||||||
|
NDSInputID_GuitarGrip_Yellow,
|
||||||
|
NDSInputID_GuitarGrip_Blue,
|
||||||
|
|
||||||
NDSInputID_Paddle,
|
NDSInputID_Paddle,
|
||||||
|
NDSInputID_Microphone,
|
||||||
|
NDSInputID_Reset,
|
||||||
|
|
||||||
NDSInputID_InputCount
|
NDSInputID_InputCount
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum NDSInputStateBit
|
||||||
|
{
|
||||||
|
NDSInputStateBit_A = 0,
|
||||||
|
NDSInputStateBit_B = 1,
|
||||||
|
NDSInputStateBit_Select = 2,
|
||||||
|
NDSInputStateBit_Start = 3,
|
||||||
|
NDSInputStateBit_Right = 4,
|
||||||
|
NDSInputStateBit_Left = 5,
|
||||||
|
NDSInputStateBit_Up = 6,
|
||||||
|
NDSInputStateBit_Down = 7,
|
||||||
|
NDSInputStateBit_R = 8,
|
||||||
|
NDSInputStateBit_L = 9,
|
||||||
|
|
||||||
|
NDSInputStateBit_X = 16,
|
||||||
|
NDSInputStateBit_Y = 17,
|
||||||
|
NDSInputStateBit_Debug = 19,
|
||||||
|
NDSInputStateBit_Touch = 22,
|
||||||
|
NDSInputStateBit_Lid = 23,
|
||||||
|
|
||||||
|
NDSInputStateBit_Piano_C = 32,
|
||||||
|
NDSInputStateBit_Piano_CSharp = 33,
|
||||||
|
NDSInputStateBit_Piano_D = 34,
|
||||||
|
NDSInputStateBit_Piano_DSharp = 35,
|
||||||
|
NDSInputStateBit_Piano_E = 36,
|
||||||
|
NDSInputStateBit_Piano_F = 37,
|
||||||
|
NDSInputStateBit_Piano_FSharp = 38,
|
||||||
|
NDSInputStateBit_Piano_G = 39,
|
||||||
|
NDSInputStateBit_Piano_GSharp = 40,
|
||||||
|
NDSInputStateBit_Piano_A = 41,
|
||||||
|
NDSInputStateBit_Piano_ASharp = 42,
|
||||||
|
NDSInputStateBit_Piano_B = 45,
|
||||||
|
NDSInputStateBit_Piano_HighC = 46,
|
||||||
|
|
||||||
|
NDSInputStateBit_GuitarGrip_Green = 51,
|
||||||
|
NDSInputStateBit_GuitarGrip_Red = 52,
|
||||||
|
NDSInputStateBit_GuitarGrip_Yellow = 53,
|
||||||
|
NDSInputStateBit_GuitarGrip_Blue = 54,
|
||||||
|
|
||||||
|
NDSInputStateBit_Paddle = 56,
|
||||||
|
NDSInputStateBit_Microphone = 57,
|
||||||
|
NDSInputStateBit_Reset = 58
|
||||||
|
};
|
||||||
|
|
||||||
|
enum MicrophoneMode
|
||||||
|
{
|
||||||
|
MicrophoneMode_None = 0,
|
||||||
|
MicrophoneMode_InternalNoise,
|
||||||
|
MicrophoneMode_AudioFile,
|
||||||
|
MicrophoneMode_WhiteNoise,
|
||||||
|
MicrophoneMode_Physical,
|
||||||
|
MicrophoneMode_SineWave
|
||||||
|
};
|
||||||
|
|
||||||
|
class AudioGenerator;
|
||||||
|
class NullGenerator;
|
||||||
|
class InternalNoiseGenerator;
|
||||||
|
class WhiteNoiseGenerator;
|
||||||
|
class SineWaveGenerator;
|
||||||
|
class AudioSampleBlockGenerator;
|
||||||
|
|
||||||
|
typedef std::map<NDSInputID, size_t> NDSUserInputMap;
|
||||||
|
typedef std::map<NDSInputID, NDSInputStateBit> NDSInputStateBitMap;
|
||||||
|
|
||||||
typedef union
|
typedef union
|
||||||
{
|
{
|
||||||
uint64_t value;
|
uint64_t value;
|
||||||
|
@ -184,7 +258,7 @@ typedef union
|
||||||
uint8_t B:1;
|
uint8_t B:1;
|
||||||
uint8_t A:1;
|
uint8_t A:1;
|
||||||
|
|
||||||
uint8_t :6
|
uint8_t :6;
|
||||||
uint8_t L:1;
|
uint8_t L:1;
|
||||||
uint8_t R:1;
|
uint8_t R:1;
|
||||||
|
|
||||||
|
@ -230,6 +304,17 @@ typedef union
|
||||||
};
|
};
|
||||||
} NDSInputState; // Each bit represents the Pressed/Released state of a single input. Pressed=0, Released=1
|
} NDSInputState; // Each bit represents the Pressed/Released state of a single input. Pressed=0, Released=1
|
||||||
|
|
||||||
|
struct ClientInput
|
||||||
|
{
|
||||||
|
bool isPressed;
|
||||||
|
bool turbo;
|
||||||
|
bool autohold;
|
||||||
|
uint32_t turboPattern;
|
||||||
|
uint8_t turboPatternStep;
|
||||||
|
uint8_t turboPatternLength;
|
||||||
|
};
|
||||||
|
typedef struct ClientInput ClientInput;
|
||||||
|
|
||||||
struct ClientExecutionControlSettings
|
struct ClientExecutionControlSettings
|
||||||
{
|
{
|
||||||
CPUEmulationEngineID cpuEngineID;
|
CPUEmulationEngineID cpuEngineID;
|
||||||
|
@ -281,64 +366,119 @@ struct NDSFrameInfo
|
||||||
NDSInputState inputStatesPending;
|
NDSInputState inputStatesPending;
|
||||||
uint8_t touchLocXPending;
|
uint8_t touchLocXPending;
|
||||||
uint8_t touchLocYPending;
|
uint8_t touchLocYPending;
|
||||||
|
uint8_t touchPressurePending;
|
||||||
|
int16_t paddleValuePending;
|
||||||
|
int16_t paddleAdjustPending;
|
||||||
|
|
||||||
NDSInputState inputStatesApplied;
|
NDSInputState inputStatesApplied;
|
||||||
uint8_t touchLocXApplied;
|
uint8_t touchLocXApplied;
|
||||||
uint8_t touchLocYApplied;
|
uint8_t touchLocYApplied;
|
||||||
|
uint8_t touchPressureApplied;
|
||||||
|
int16_t paddleValueApplied;
|
||||||
|
int16_t paddleAdjustApplied;
|
||||||
|
|
||||||
void clear()
|
void clear()
|
||||||
{
|
{
|
||||||
this->cpuEmulationEngineName = std::string();
|
this->cpuEmulationEngineName = std::string();
|
||||||
this->slot1DeviceName = std::string();
|
this->slot1DeviceName = std::string();
|
||||||
this->rtcString = std::string();
|
this->rtcString = std::string();
|
||||||
this->frameIndex = 0;
|
|
||||||
this->render3DFPS = 0;
|
|
||||||
this->lagFrameCount = 0;
|
|
||||||
this->cpuLoadAvgARM9 = 0;
|
|
||||||
this->cpuLoadAvgARM7 = 0;
|
|
||||||
|
|
||||||
this->inputStatesPending.value = INPUT_STATES_CLEAR_VALUE;
|
this->frameIndex = 0;
|
||||||
this->touchLocXPending = 0;
|
this->render3DFPS = 0;
|
||||||
this->touchLocYPending = 0;
|
this->lagFrameCount = 0;
|
||||||
|
this->cpuLoadAvgARM9 = 0;
|
||||||
|
this->cpuLoadAvgARM7 = 0;
|
||||||
|
|
||||||
this->inputStatesApplied.value = INPUT_STATES_CLEAR_VALUE;
|
this->inputStatesPending.value = INPUT_STATES_CLEAR_VALUE;
|
||||||
this->touchLocXApplied = 0;
|
this->touchLocXPending = 0;
|
||||||
this->touchLocYApplied = 0;
|
this->touchLocYPending = 0;
|
||||||
|
this->touchPressurePending = 50;
|
||||||
|
this->paddleValuePending = 0;
|
||||||
|
this->paddleAdjustPending = 0;
|
||||||
|
|
||||||
|
this->inputStatesApplied.value = INPUT_STATES_CLEAR_VALUE;
|
||||||
|
this->touchLocXApplied = 0;
|
||||||
|
this->touchLocYApplied = 0;
|
||||||
|
this->touchPressureApplied = 50;
|
||||||
|
this->paddleValueApplied = 0;
|
||||||
|
this->paddleAdjustApplied = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void copyFrom(const NDSFrameInfo &fromObject)
|
void copyFrom(const NDSFrameInfo &fromObject)
|
||||||
{
|
{
|
||||||
this->cpuEmulationEngineName = fromObject.cpuEmulationEngineName;
|
this->cpuEmulationEngineName = fromObject.cpuEmulationEngineName;
|
||||||
this->slot1DeviceName = fromObject.slot1DeviceName;
|
this->slot1DeviceName = fromObject.slot1DeviceName;
|
||||||
this->rtcString = fromObject.rtcString;
|
this->rtcString = fromObject.rtcString;
|
||||||
this->frameIndex = fromObject.frameIndex;
|
|
||||||
this->render3DFPS = fromObject.render3DFPS;
|
|
||||||
this->lagFrameCount = fromObject.lagFrameCount;
|
|
||||||
this->cpuLoadAvgARM9 = fromObject.cpuLoadAvgARM9;
|
|
||||||
this->cpuLoadAvgARM7 = fromObject.cpuLoadAvgARM7;
|
|
||||||
|
|
||||||
this->inputStatesPending = fromObject.inputStatesPending;
|
this->frameIndex = fromObject.frameIndex;
|
||||||
this->touchLocXPending = fromObject.touchLocXPending;
|
this->render3DFPS = fromObject.render3DFPS;
|
||||||
this->touchLocYPending = fromObject.touchLocYPending;
|
this->lagFrameCount = fromObject.lagFrameCount;
|
||||||
|
this->cpuLoadAvgARM9 = fromObject.cpuLoadAvgARM9;
|
||||||
|
this->cpuLoadAvgARM7 = fromObject.cpuLoadAvgARM7;
|
||||||
|
|
||||||
this->inputStatesApplied = fromObject.inputStatesApplied;
|
this->inputStatesPending = fromObject.inputStatesPending;
|
||||||
this->touchLocXApplied = fromObject.touchLocXApplied;
|
this->touchLocXPending = fromObject.touchLocXPending;
|
||||||
this->touchLocYApplied = fromObject.touchLocYApplied;
|
this->touchLocYPending = fromObject.touchLocYPending;
|
||||||
|
this->touchPressurePending = fromObject.touchPressurePending;
|
||||||
|
this->paddleValuePending = fromObject.paddleValuePending;
|
||||||
|
this->paddleAdjustPending = fromObject.paddleAdjustPending;
|
||||||
|
|
||||||
|
this->inputStatesApplied = fromObject.inputStatesApplied;
|
||||||
|
this->touchLocXApplied = fromObject.touchLocXApplied;
|
||||||
|
this->touchLocYApplied = fromObject.touchLocYApplied;
|
||||||
|
this->touchPressureApplied = fromObject.touchPressureApplied;
|
||||||
|
this->paddleValueApplied = fromObject.paddleValueApplied;
|
||||||
|
this->paddleAdjustApplied = fromObject.paddleAdjustApplied;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class ClientExecutionControl
|
class ClientExecutionControl
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
NDSUserInputMap _userInputMap;
|
||||||
|
NDSInputStateBitMap _inputStateBitMap;
|
||||||
|
|
||||||
|
AudioGenerator *_softwareMicSampleGeneratorPending;
|
||||||
|
AudioGenerator *_softwareMicSampleGeneratorProcessing;
|
||||||
|
AudioGenerator *_softwareMicSampleGeneratorApplied;
|
||||||
|
NullGenerator *_nullSampleGenerator;
|
||||||
|
InternalNoiseGenerator *_internalNoiseGenerator;
|
||||||
|
WhiteNoiseGenerator *_whiteNoiseGenerator;
|
||||||
|
SineWaveGenerator *_sineWaveGenerator;
|
||||||
|
AudioSampleBlockGenerator *_selectedAudioFileGenerator;
|
||||||
|
|
||||||
ClientExecutionControlSettings _settingsPending;
|
ClientExecutionControlSettings _settingsPending;
|
||||||
ClientExecutionControlSettings _settingsApplied;
|
ClientExecutionControlSettings _settingsApplied;
|
||||||
|
|
||||||
NDSFrameInfo _ndsFrameInfo;
|
NDSFrameInfo _ndsFrameInfo;
|
||||||
|
ClientInput _clientInputPending[NDSInputID_InputCount];
|
||||||
|
ClientInput _clientInputProcessing[NDSInputID_InputCount];
|
||||||
|
ClientInput _clientInputApplied[NDSInputID_InputCount];
|
||||||
|
|
||||||
bool _newSettingsPendingOnReset;
|
bool _newSettingsPendingOnReset;
|
||||||
bool _newSettingsPendingOnExecutionLoopStart;
|
bool _newSettingsPendingOnExecutionLoopStart;
|
||||||
bool _newSettingsPendingOnNDSExec;
|
bool _newSettingsPendingOnNDSExec;
|
||||||
|
|
||||||
|
bool _enableAutohold;
|
||||||
|
|
||||||
|
uint8_t _touchLocXPending;
|
||||||
|
uint8_t _touchLocYPending;
|
||||||
|
uint8_t _touchPressurePending;
|
||||||
|
int16_t _paddleValuePending;
|
||||||
|
int16_t _paddleAdjustPending;
|
||||||
|
|
||||||
|
uint8_t _touchLocXProcessing;
|
||||||
|
uint8_t _touchLocYProcessing;
|
||||||
|
uint8_t _touchPressureProcessing;
|
||||||
|
int16_t _paddleValueProcessing;
|
||||||
|
int16_t _paddleAdjustProcessing;
|
||||||
|
|
||||||
|
uint8_t _touchLocXApplied;
|
||||||
|
uint8_t _touchLocYApplied;
|
||||||
|
uint8_t _touchPressureApplied;
|
||||||
|
int16_t _paddleValueApplied;
|
||||||
|
int16_t _paddleAdjustApplied;
|
||||||
|
|
||||||
bool _needResetFramesToSkip;
|
bool _needResetFramesToSkip;
|
||||||
|
|
||||||
double _frameTime;
|
double _frameTime;
|
||||||
|
@ -352,6 +492,7 @@ private:
|
||||||
pthread_mutex_t _mutexSettingsPendingOnReset;
|
pthread_mutex_t _mutexSettingsPendingOnReset;
|
||||||
pthread_mutex_t _mutexSettingsPendingOnExecutionLoopStart;
|
pthread_mutex_t _mutexSettingsPendingOnExecutionLoopStart;
|
||||||
pthread_mutex_t _mutexSettingsPendingOnNDSExec;
|
pthread_mutex_t _mutexSettingsPendingOnNDSExec;
|
||||||
|
pthread_mutex_t _mutexInputsPending;
|
||||||
pthread_mutex_t _mutexOutputPostNDSExec;
|
pthread_mutex_t _mutexOutputPostNDSExec;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -444,6 +585,32 @@ public:
|
||||||
void ApplySettingsOnExecutionLoopStart();
|
void ApplySettingsOnExecutionLoopStart();
|
||||||
void ApplySettingsOnNDSExec();
|
void ApplySettingsOnNDSExec();
|
||||||
|
|
||||||
|
bool GetEnableAutohold();
|
||||||
|
void SetEnableAutohold(bool enable);
|
||||||
|
void ClearAutohold();
|
||||||
|
|
||||||
|
void SetClientInputStateUsingID(NDSInputID inputID, bool pressedState);
|
||||||
|
void SetClientInputStateUsingID(NDSInputID inputID, bool pressedState, bool isTurboEnabled, uint32_t turboPattern, uint32_t turboPatternLength);
|
||||||
|
void SetClientTouchState(bool pressedState, uint8_t touchLocX, uint8_t touchLocY, uint8_t touchPressure);
|
||||||
|
|
||||||
|
double GetSineWaveFrequency();
|
||||||
|
void SetSineWaveFrequency(double freq);
|
||||||
|
|
||||||
|
AudioGenerator* GetClientSoftwareMicSampleGenerator();
|
||||||
|
AudioGenerator* GetClientSoftwareMicSampleGeneratorApplied();
|
||||||
|
AudioSampleBlockGenerator* GetClientSelectedAudioFileGenerator();
|
||||||
|
void SetClientSelectedAudioFileGenerator(AudioSampleBlockGenerator *selectedAudioFileGenerator);
|
||||||
|
|
||||||
|
bool GetClientSoftwareMicState();
|
||||||
|
bool GetClientSoftwareMicStateApplied();
|
||||||
|
void SetClientSoftwareMicState(bool pressedState, MicrophoneMode micMode);
|
||||||
|
|
||||||
|
int16_t GetClientPaddleAdjust();
|
||||||
|
void SetClientPaddleAdjust(int16_t paddleAdjust);
|
||||||
|
|
||||||
|
void ProcessInputs();
|
||||||
|
void ApplyInputs();
|
||||||
|
|
||||||
void FetchOutputPostNDSExec();
|
void FetchOutputPostNDSExec();
|
||||||
const NDSFrameInfo& GetNDSFrameInfo();
|
const NDSFrameInfo& GetNDSFrameInfo();
|
||||||
|
|
||||||
|
|
|
@ -112,12 +112,12 @@
|
||||||
<false/>
|
<false/>
|
||||||
<key>HUD_ShowLagFrameCount</key>
|
<key>HUD_ShowLagFrameCount</key>
|
||||||
<false/>
|
<false/>
|
||||||
<key>HUD_ShowInput</key>
|
|
||||||
<false/>
|
|
||||||
<key>HUD_ShowCPULoadAverage</key>
|
<key>HUD_ShowCPULoadAverage</key>
|
||||||
<false/>
|
<false/>
|
||||||
<key>HUD_ShowRTC</key>
|
<key>HUD_ShowRTC</key>
|
||||||
<false/>
|
<false/>
|
||||||
|
<key>HUD_ShowInput</key>
|
||||||
|
<false/>
|
||||||
<key>HUD_Color_VideoFPS</key>
|
<key>HUD_Color_VideoFPS</key>
|
||||||
<integer>4294967295</integer>
|
<integer>4294967295</integer>
|
||||||
<key>HUD_Color_Render3DFPS</key>
|
<key>HUD_Color_Render3DFPS</key>
|
||||||
|
@ -130,6 +130,12 @@
|
||||||
<integer>4294967295</integer>
|
<integer>4294967295</integer>
|
||||||
<key>HUD_Color_RTC</key>
|
<key>HUD_Color_RTC</key>
|
||||||
<integer>4294967295</integer>
|
<integer>4294967295</integer>
|
||||||
|
<key>HUD_Color_Input_PendingAndApplied</key>
|
||||||
|
<integer>4294967295</integer>
|
||||||
|
<key>HUD_Color_Input_AppliedOnly</key>
|
||||||
|
<integer>4281348351</integer>
|
||||||
|
<key>HUD_Color_Input_PendingOnly</key>
|
||||||
|
<integer>4278239232</integer>
|
||||||
<key>Input_AudioInputMode</key>
|
<key>Input_AudioInputMode</key>
|
||||||
<integer>1</integer>
|
<integer>1</integer>
|
||||||
<key>Input_ControllerMappings</key>
|
<key>Input_ControllerMappings</key>
|
||||||
|
|
|
@ -32,18 +32,28 @@ static const char *HUDOutputVertShader_100 = {"\
|
||||||
ATTRIBUTE vec2 inTexCoord0; \n\
|
ATTRIBUTE vec2 inTexCoord0; \n\
|
||||||
\n\
|
\n\
|
||||||
uniform vec2 viewSize; \n\
|
uniform vec2 viewSize; \n\
|
||||||
|
uniform float scalar; \n\
|
||||||
|
uniform float angleDegrees; \n\
|
||||||
\n\
|
\n\
|
||||||
VARYING vec4 vtxColor; \n\
|
VARYING vec4 vtxColor; \n\
|
||||||
VARYING vec2 texCoord[1]; \n\
|
VARYING vec2 texCoord[1]; \n\
|
||||||
\n\
|
\n\
|
||||||
void main() \n\
|
void main() \n\
|
||||||
{ \n\
|
{ \n\
|
||||||
|
float angleRadians = radians(angleDegrees); \n\
|
||||||
|
\n\
|
||||||
mat2 projection = mat2( vec2(2.0/viewSize.x, 0.0), \n\
|
mat2 projection = mat2( vec2(2.0/viewSize.x, 0.0), \n\
|
||||||
vec2( 0.0, 2.0/viewSize.y)); \n\
|
vec2( 0.0, 2.0/viewSize.y)); \n\
|
||||||
\n\
|
\n\
|
||||||
|
mat2 rotation = mat2( vec2( cos(angleRadians), sin(angleRadians)), \n\
|
||||||
|
vec2(-sin(angleRadians), cos(angleRadians))); \n\
|
||||||
|
\n\
|
||||||
|
mat2 scale = mat2( vec2(scalar, 0.0), \n\
|
||||||
|
vec2( 0.0, scalar)); \n\
|
||||||
|
\n\
|
||||||
vtxColor = inColor; \n\
|
vtxColor = inColor; \n\
|
||||||
texCoord[0] = inTexCoord0; \n\
|
texCoord[0] = inTexCoord0; \n\
|
||||||
gl_Position = vec4(projection * inPosition, 0.0, 1.0);\n\
|
gl_Position = vec4(projection * rotation * scale * inPosition, 0.0, 1.0);\n\
|
||||||
} \n\
|
} \n\
|
||||||
"};
|
"};
|
||||||
|
|
||||||
|
@ -5016,7 +5026,11 @@ void OGLVideoOutput::_UpdateOrder()
|
||||||
|
|
||||||
void OGLVideoOutput::_UpdateRotation()
|
void OGLVideoOutput::_UpdateRotation()
|
||||||
{
|
{
|
||||||
this->GetDisplayLayer()->SetNeedsUpdateRotationScale();
|
for (size_t i = 0; i < _layerList->size(); i++)
|
||||||
|
{
|
||||||
|
OGLVideoLayer *theLayer = (*_layerList)[i];
|
||||||
|
theLayer->SetNeedsUpdateRotationScale();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OGLVideoOutput::_UpdateClientSize()
|
void OGLVideoOutput::_UpdateClientSize()
|
||||||
|
@ -5032,7 +5046,12 @@ void OGLVideoOutput::_UpdateClientSize()
|
||||||
void OGLVideoOutput::_UpdateViewScale()
|
void OGLVideoOutput::_UpdateViewScale()
|
||||||
{
|
{
|
||||||
this->ClientDisplayView::_UpdateViewScale();
|
this->ClientDisplayView::_UpdateViewScale();
|
||||||
this->GetDisplayLayer()->SetNeedsUpdateRotationScale();
|
|
||||||
|
for (size_t i = 0; i < _layerList->size(); i++)
|
||||||
|
{
|
||||||
|
OGLVideoLayer *theLayer = (*_layerList)[i];
|
||||||
|
theLayer->SetNeedsUpdateRotationScale();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OGLVideoOutput::_UpdateViewport()
|
void OGLVideoOutput::_UpdateViewport()
|
||||||
|
@ -5042,11 +5061,7 @@ void OGLVideoOutput::_UpdateViewport()
|
||||||
for (size_t i = 0; i < _layerList->size(); i++)
|
for (size_t i = 0; i < _layerList->size(); i++)
|
||||||
{
|
{
|
||||||
OGLVideoLayer *theLayer = (*_layerList)[i];
|
OGLVideoLayer *theLayer = (*_layerList)[i];
|
||||||
|
theLayer->SetNeedsUpdateViewport();
|
||||||
if (theLayer->IsVisible())
|
|
||||||
{
|
|
||||||
theLayer->SetNeedsUpdateViewport();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5614,9 +5629,9 @@ OGLImage::OGLImage(OGLContextInfo *contextInfo, GLsizei imageWidth, GLsizei imag
|
||||||
|
|
||||||
const GLuint finalOutputProgramID = _finalOutputProgram->GetProgramID();
|
const GLuint finalOutputProgramID = _finalOutputProgram->GetProgramID();
|
||||||
glUseProgram(finalOutputProgramID);
|
glUseProgram(finalOutputProgramID);
|
||||||
_uniformFinalOutputAngleDegrees = glGetUniformLocation(finalOutputProgramID, "angleDegrees");
|
_uniformAngleDegrees = glGetUniformLocation(finalOutputProgramID, "angleDegrees");
|
||||||
_uniformFinalOutputScalar = glGetUniformLocation(finalOutputProgramID, "scalar");
|
_uniformScalar = glGetUniformLocation(finalOutputProgramID, "scalar");
|
||||||
_uniformFinalOutputViewSize = glGetUniformLocation(finalOutputProgramID, "viewSize");
|
_uniformViewSize = glGetUniformLocation(finalOutputProgramID, "viewSize");
|
||||||
glUseProgram(0);
|
glUseProgram(0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -5753,9 +5768,9 @@ void OGLImage::UploadTransformationOGL()
|
||||||
|
|
||||||
if (this->_canUseShaderOutput)
|
if (this->_canUseShaderOutput)
|
||||||
{
|
{
|
||||||
glUniform2f(this->_uniformFinalOutputViewSize, w, h);
|
glUniform2f(this->_uniformViewSize, w, h);
|
||||||
glUniform1f(this->_uniformFinalOutputAngleDegrees, 0.0f);
|
glUniform1f(this->_uniformAngleDegrees, 0.0f);
|
||||||
glUniform1f(this->_uniformFinalOutputScalar, s);
|
glUniform1f(this->_uniformScalar, s);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -6175,6 +6190,11 @@ void OGLVideoLayer::SetNeedsUpdateViewport()
|
||||||
this->_needUpdateViewport = true;
|
this->_needUpdateViewport = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OGLVideoLayer::SetNeedsUpdateRotationScale()
|
||||||
|
{
|
||||||
|
this->_needUpdateRotationScale = true;
|
||||||
|
}
|
||||||
|
|
||||||
void OGLVideoLayer::SetNeedsUpdateVertices()
|
void OGLVideoLayer::SetNeedsUpdateVertices()
|
||||||
{
|
{
|
||||||
this->_needUpdateVertices = true;
|
this->_needUpdateVertices = true;
|
||||||
|
@ -6205,6 +6225,8 @@ OGLHUDLayer::OGLHUDLayer(OGLVideoOutput *oglVO)
|
||||||
_program->SetVertexAndFragmentShaderOGL(HUDOutputVertShader_100, HUDOutputFragShader_110, true, oglVO->GetContextInfo()->IsUsingShader150());
|
_program->SetVertexAndFragmentShaderOGL(HUDOutputVertShader_100, HUDOutputFragShader_110, true, oglVO->GetContextInfo()->IsUsingShader150());
|
||||||
|
|
||||||
glUseProgram(_program->GetProgramID());
|
glUseProgram(_program->GetProgramID());
|
||||||
|
_uniformAngleDegrees = glGetUniformLocation(_program->GetProgramID(), "angleDegrees");
|
||||||
|
_uniformScalar = glGetUniformLocation(_program->GetProgramID(), "scalar");
|
||||||
_uniformViewSize = glGetUniformLocation(_program->GetProgramID(), "viewSize");
|
_uniformViewSize = glGetUniformLocation(_program->GetProgramID(), "viewSize");
|
||||||
glUseProgram(0);
|
glUseProgram(0);
|
||||||
}
|
}
|
||||||
|
@ -6230,10 +6252,10 @@ OGLHUDLayer::OGLHUDLayer(OGLVideoOutput *oglVO)
|
||||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
|
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
|
||||||
|
|
||||||
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, _vboElementID);
|
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, _vboElementID);
|
||||||
glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, sizeof(GLshort) * HUD_MAX_CHARACTERS * 6, NULL, GL_STATIC_DRAW_ARB);
|
glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, sizeof(GLshort) * HUD_TOTAL_ELEMENTS * 6, NULL, GL_STATIC_DRAW_ARB);
|
||||||
GLshort *idxBufferPtr = (GLshort *)glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
|
GLshort *idxBufferPtr = (GLshort *)glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
|
||||||
|
|
||||||
for (size_t i = 0, j = 0, k = 0; i < HUD_MAX_CHARACTERS; i++, j+=6, k+=4)
|
for (size_t i = 0, j = 0, k = 0; i < HUD_TOTAL_ELEMENTS; i++, j+=6, k+=4)
|
||||||
{
|
{
|
||||||
idxBufferPtr[j+0] = k+0;
|
idxBufferPtr[j+0] = k+0;
|
||||||
idxBufferPtr[j+1] = k+1;
|
idxBufferPtr[j+1] = k+1;
|
||||||
|
@ -6418,8 +6440,44 @@ void OGLHUDLayer::_UpdateVerticesOGL()
|
||||||
|
|
||||||
void OGLHUDLayer::RenderOGL()
|
void OGLHUDLayer::RenderOGL()
|
||||||
{
|
{
|
||||||
const size_t length = this->_output->GetHUDString().length();
|
size_t hudLength = this->_output->GetHUDString().length();
|
||||||
if (length <= 1)
|
size_t hudTouchLineLength = 0;
|
||||||
|
|
||||||
|
if (this->_output->GetHUDShowInput())
|
||||||
|
{
|
||||||
|
hudLength += HUD_INPUT_ELEMENT_LENGTH;
|
||||||
|
|
||||||
|
switch (this->_output->GetMode())
|
||||||
|
{
|
||||||
|
case ClientDisplayMode_Main:
|
||||||
|
case ClientDisplayMode_Touch:
|
||||||
|
hudTouchLineLength = HUD_INPUT_TOUCH_LINE_ELEMENTS / 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ClientDisplayMode_Dual:
|
||||||
|
{
|
||||||
|
switch (this->_output->GetLayout())
|
||||||
|
{
|
||||||
|
case ClientDisplayLayout_Vertical:
|
||||||
|
case ClientDisplayLayout_Horizontal:
|
||||||
|
hudTouchLineLength = HUD_INPUT_TOUCH_LINE_ELEMENTS / 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ClientDisplayLayout_Hybrid_2_1:
|
||||||
|
case ClientDisplayLayout_Hybrid_16_9:
|
||||||
|
case ClientDisplayLayout_Hybrid_16_10:
|
||||||
|
hudTouchLineLength = HUD_INPUT_TOUCH_LINE_ELEMENTS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hudLength += hudTouchLineLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hudLength <= 1)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -6443,12 +6501,65 @@ void OGLHUDLayer::RenderOGL()
|
||||||
glBindVertexArrayDESMUME(this->_vaoMainStatesID);
|
glBindVertexArrayDESMUME(this->_vaoMainStatesID);
|
||||||
glBindTexture(GL_TEXTURE_2D, this->_texCharMap);
|
glBindTexture(GL_TEXTURE_2D, this->_texCharMap);
|
||||||
|
|
||||||
// First, draw the backing text box.
|
// First, draw the inputs.
|
||||||
|
if (this->_output->GetHUDShowInput())
|
||||||
|
{
|
||||||
|
const ClientDisplayViewProperties &cdv = this->_output->GetViewProperties();
|
||||||
|
|
||||||
|
if (this->_output->GetContextInfo()->IsShaderSupported())
|
||||||
|
{
|
||||||
|
glUniform1f(this->_uniformAngleDegrees, cdv.rotation);
|
||||||
|
glUniform1f(this->_uniformScalar, cdv.viewScale);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
glLoadIdentity();
|
||||||
|
glRotatef(cdv.rotation, 0.0f, 0.0f, 1.0f);
|
||||||
|
glScalef(cdv.viewScale, cdv.viewScale, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
glDrawElements(GL_TRIANGLES, hudTouchLineLength * 6, GL_UNSIGNED_SHORT, (GLvoid *)((this->_output->GetHUDString().length() + HUD_INPUT_ELEMENT_LENGTH) * 6 * sizeof(uint16_t)));
|
||||||
|
|
||||||
|
if (this->_output->GetContextInfo()->IsShaderSupported())
|
||||||
|
{
|
||||||
|
glUniform1f(this->_uniformAngleDegrees, 0.0f);
|
||||||
|
glUniform1f(this->_uniformScalar, 1.0f);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
glLoadIdentity();
|
||||||
|
glRotatef(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
glScalef(1.0f, 1.0f, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
glDrawElements(GL_TRIANGLES, HUD_INPUT_ELEMENT_LENGTH * 6, GL_UNSIGNED_SHORT, (GLvoid *)(this->_output->GetHUDString().length() * 6 * sizeof(uint16_t)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Next, draw the backing text box.
|
||||||
|
if (this->_output->GetContextInfo()->IsShaderSupported())
|
||||||
|
{
|
||||||
|
glUniform1f(this->_uniformAngleDegrees, 0.0f);
|
||||||
|
glUniform1f(this->_uniformScalar, 1.0f);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
glLoadIdentity();
|
||||||
|
glRotatef(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
glScalef(1.0f, 1.0f, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
|
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
|
||||||
|
|
||||||
// Next, draw each character inside the box.
|
// Finally, draw each character inside the box.
|
||||||
const GLfloat textBoxScale = (GLfloat)HUD_TEXTBOX_BASE_SCALE * this->_output->GetHUDObjectScale() / this->_output->GetScaleFactor();
|
const GLfloat textBoxScale = (GLfloat)HUD_TEXTBOX_BASE_SCALE * this->_output->GetHUDObjectScale() / this->_output->GetScaleFactor();
|
||||||
if (textBoxScale >= (2.0/3.0))
|
if (textBoxScale >= (2.0/3.0))
|
||||||
{
|
{
|
||||||
|
@ -6462,7 +6573,7 @@ void OGLHUDLayer::RenderOGL()
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, -0.50f);
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, -0.50f);
|
||||||
}
|
}
|
||||||
glDrawElements(GL_TRIANGLES, (length - 1) * 6, GL_UNSIGNED_SHORT, (GLvoid *)(6 * sizeof(GLshort)));
|
glDrawElements(GL_TRIANGLES, (this->_output->GetHUDString().length() - 1) * 6, GL_UNSIGNED_SHORT, (GLvoid *)(6 * sizeof(GLshort)));
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
glBindVertexArrayDESMUME(0);
|
glBindVertexArrayDESMUME(0);
|
||||||
|
@ -6531,9 +6642,9 @@ OGLDisplayLayer::OGLDisplayLayer(OGLVideoOutput *oglVO)
|
||||||
|
|
||||||
const GLuint finalOutputProgramID = _finalOutputProgram->GetProgramID();
|
const GLuint finalOutputProgramID = _finalOutputProgram->GetProgramID();
|
||||||
glUseProgram(finalOutputProgramID);
|
glUseProgram(finalOutputProgramID);
|
||||||
_uniformFinalOutputAngleDegrees = glGetUniformLocation(finalOutputProgramID, "angleDegrees");
|
_uniformAngleDegrees = glGetUniformLocation(finalOutputProgramID, "angleDegrees");
|
||||||
_uniformFinalOutputScalar = glGetUniformLocation(finalOutputProgramID, "scalar");
|
_uniformScalar = glGetUniformLocation(finalOutputProgramID, "scalar");
|
||||||
_uniformFinalOutputViewSize = glGetUniformLocation(finalOutputProgramID, "viewSize");
|
_uniformViewSize = glGetUniformLocation(finalOutputProgramID, "viewSize");
|
||||||
glUseProgram(0);
|
glUseProgram(0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -6589,23 +6700,16 @@ OGLDisplayLayer::~OGLDisplayLayer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OGLDisplayLayer::SetNeedsUpdateRotationScale()
|
|
||||||
{
|
|
||||||
this->_needUpdateRotationScale = true;
|
|
||||||
this->_needUpdateVertices = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OGLDisplayLayer::_UpdateRotationScaleOGL()
|
void OGLDisplayLayer::_UpdateRotationScaleOGL()
|
||||||
{
|
{
|
||||||
const ClientDisplayViewProperties &cdv = this->_output->GetViewProperties();
|
const ClientDisplayViewProperties &cdv = this->_output->GetViewProperties();
|
||||||
|
|
||||||
const double r = cdv.rotation;
|
const double r = cdv.rotation;
|
||||||
const double s = cdv.viewScale;
|
const double s = cdv.viewScale;
|
||||||
|
|
||||||
if (this->_output->GetContextInfo()->IsShaderSupported())
|
if (this->_output->GetContextInfo()->IsShaderSupported())
|
||||||
{
|
{
|
||||||
glUniform1f(this->_uniformFinalOutputAngleDegrees, r);
|
glUniform1f(this->_uniformAngleDegrees, r);
|
||||||
glUniform1f(this->_uniformFinalOutputScalar, s);
|
glUniform1f(this->_uniformScalar, s);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -7040,7 +7144,7 @@ void OGLDisplayLayer::RenderOGL()
|
||||||
|
|
||||||
if (this->_needUpdateViewport)
|
if (this->_needUpdateViewport)
|
||||||
{
|
{
|
||||||
glUniform2f(this->_uniformFinalOutputViewSize, this->_output->GetViewportWidth(), this->_output->GetViewportHeight());
|
glUniform2f(this->_uniformViewSize, this->_output->GetViewportWidth(), this->_output->GetViewportHeight());
|
||||||
this->_needUpdateViewport = false;
|
this->_needUpdateViewport = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -209,9 +209,9 @@ protected:
|
||||||
GLuint _vboVertexID;
|
GLuint _vboVertexID;
|
||||||
GLuint _vboTexCoordID;
|
GLuint _vboTexCoordID;
|
||||||
|
|
||||||
GLint _uniformFinalOutputAngleDegrees;
|
GLint _uniformAngleDegrees;
|
||||||
GLint _uniformFinalOutputScalar;
|
GLint _uniformScalar;
|
||||||
GLint _uniformFinalOutputViewSize;
|
GLint _uniformViewSize;
|
||||||
|
|
||||||
void UploadVerticesOGL();
|
void UploadVerticesOGL();
|
||||||
void UploadTexCoordsOGL();
|
void UploadTexCoordsOGL();
|
||||||
|
@ -254,10 +254,15 @@ protected:
|
||||||
bool _needUpdateRotationScale;
|
bool _needUpdateRotationScale;
|
||||||
bool _needUpdateVertices;
|
bool _needUpdateVertices;
|
||||||
|
|
||||||
|
GLint _uniformAngleDegrees;
|
||||||
|
GLint _uniformScalar;
|
||||||
|
GLint _uniformViewSize;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~OGLVideoLayer() {};
|
virtual ~OGLVideoLayer() {};
|
||||||
|
|
||||||
void SetNeedsUpdateViewport();
|
void SetNeedsUpdateViewport();
|
||||||
|
void SetNeedsUpdateRotationScale();
|
||||||
void SetNeedsUpdateVertices();
|
void SetNeedsUpdateVertices();
|
||||||
|
|
||||||
virtual bool IsVisible();
|
virtual bool IsVisible();
|
||||||
|
@ -271,7 +276,6 @@ class OGLHUDLayer : public OGLVideoLayer
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
OGLShaderProgram *_program;
|
OGLShaderProgram *_program;
|
||||||
GLint _uniformViewSize;
|
|
||||||
|
|
||||||
GLuint _vaoMainStatesID;
|
GLuint _vaoMainStatesID;
|
||||||
GLuint _vboPositionVertexID;
|
GLuint _vboPositionVertexID;
|
||||||
|
@ -305,10 +309,6 @@ protected:
|
||||||
GLuint _vboVertexID;
|
GLuint _vboVertexID;
|
||||||
GLuint _vboTexCoordID;
|
GLuint _vboTexCoordID;
|
||||||
|
|
||||||
GLint _uniformFinalOutputAngleDegrees;
|
|
||||||
GLint _uniformFinalOutputScalar;
|
|
||||||
GLint _uniformFinalOutputViewSize;
|
|
||||||
|
|
||||||
void _UpdateRotationScaleOGL();
|
void _UpdateRotationScaleOGL();
|
||||||
void _UpdateVerticesOGL();
|
void _UpdateVerticesOGL();
|
||||||
|
|
||||||
|
@ -319,8 +319,6 @@ public:
|
||||||
OGLDisplayLayer(OGLVideoOutput *oglVO);
|
OGLDisplayLayer(OGLVideoOutput *oglVO);
|
||||||
virtual ~OGLDisplayLayer();
|
virtual ~OGLDisplayLayer();
|
||||||
|
|
||||||
void SetNeedsUpdateRotationScale();
|
|
||||||
|
|
||||||
OutputFilterTypeID SetOutputFilterOGL(const OutputFilterTypeID filterID);
|
OutputFilterTypeID SetOutputFilterOGL(const OutputFilterTypeID filterID);
|
||||||
bool SetGPUPixelScalerOGL(const VideoFilterTypeID filterID);
|
bool SetGPUPixelScalerOGL(const VideoFilterTypeID filterID);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright (C) 2013-2015 DeSmuME team
|
Copyright (C) 2013-2017 DeSmuME team
|
||||||
|
|
||||||
This file is free software: you can redistribute it and/or modify
|
This file is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -23,7 +23,7 @@
|
||||||
#include "audiosamplegenerator.h"
|
#include "audiosamplegenerator.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "cocoa_globals.h"
|
#include "ClientExecutionControl.h"
|
||||||
|
|
||||||
#define NUM_INTERNAL_NOISE_SAMPLES 32
|
#define NUM_INTERNAL_NOISE_SAMPLES 32
|
||||||
|
|
||||||
|
|
|
@ -972,21 +972,8 @@ static void* RunCoreThread(void *arg)
|
||||||
frameTime = execControl->GetFrameTime();
|
frameTime = execControl->GetFrameTime();
|
||||||
frameJumpTarget = execControl->GetFrameJumpTargetApplied();
|
frameJumpTarget = execControl->GetFrameJumpTargetApplied();
|
||||||
|
|
||||||
CocoaDSController *cdsController = [cdsCore cdsController];
|
execControl->ProcessInputs();
|
||||||
if (behavior != ExecutionBehavior_FrameJump)
|
execControl->ApplyInputs();
|
||||||
{
|
|
||||||
[cdsController flush];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
[cdsController flushEmpty];
|
|
||||||
}
|
|
||||||
|
|
||||||
NDS_beginProcessingInput();
|
|
||||||
FCEUMOV_HandlePlayback();
|
|
||||||
NDS_endProcessingInput();
|
|
||||||
FCEUMOV_HandleRecording();
|
|
||||||
|
|
||||||
execControl->ApplySettingsOnNDSExec();
|
execControl->ApplySettingsOnNDSExec();
|
||||||
|
|
||||||
// Execute the frame and increment the frame counter.
|
// Execute the frame and increment the frame counter.
|
||||||
|
@ -1008,6 +995,7 @@ static void* RunCoreThread(void *arg)
|
||||||
// of whether the NDS actually reads the mic or not.
|
// of whether the NDS actually reads the mic or not.
|
||||||
if ((ndsFrameInfo.frameIndex & 0x07) == 0x07)
|
if ((ndsFrameInfo.frameIndex & 0x07) == 0x07)
|
||||||
{
|
{
|
||||||
|
CocoaDSController *cdsController = [cdsCore cdsController];
|
||||||
[cdsController updateMicLevel];
|
[cdsController updateMicLevel];
|
||||||
[cdsController clearMicLevelMeasure];
|
[cdsController clearMicLevelMeasure];
|
||||||
}
|
}
|
||||||
|
|
|
@ -204,16 +204,6 @@
|
||||||
#define ROMINFO_GAME_CODE_LENGTH 4
|
#define ROMINFO_GAME_CODE_LENGTH 4
|
||||||
#define ROMINFO_GAME_BANNER_LENGTH 128
|
#define ROMINFO_GAME_BANNER_LENGTH 128
|
||||||
|
|
||||||
#define MIC_SAMPLE_RATE 16000.0
|
|
||||||
#define MIC_SAMPLE_RESOLUTION 8 // Bits per sample; must be a multiple of 8
|
|
||||||
#define MIC_NUMBER_CHANNELS 1 // Number of channels
|
|
||||||
#define MIC_SAMPLE_SIZE ((MIC_SAMPLE_RESOLUTION / 8) * MIC_NUMBER_CHANNELS) // Bytes per sample, multiplied by the number of channels
|
|
||||||
#define MIC_MAX_BUFFER_SAMPLES ((MIC_SAMPLE_RATE / DS_FRAMES_PER_SECOND) * MIC_SAMPLE_SIZE)
|
|
||||||
#define MIC_CAPTURE_FRAMES 192 // The number of audio frames that the NDS microphone should pull. The lower this value, the lower the latency. Ensure that this value is not too low, or else audio frames may be lost.
|
|
||||||
#define MIC_NULL_LEVEL_THRESHOLD 2.5
|
|
||||||
#define MIC_CLIP_LEVEL_THRESHOLD 39.743665431525209 // ((2.0/pi) * MIC_NULL_SAMPLE_VALUE) - 1.0
|
|
||||||
#define MIC_NULL_SAMPLE_VALUE 64
|
|
||||||
|
|
||||||
#define COCOA_DIALOG_CANCEL 0
|
#define COCOA_DIALOG_CANCEL 0
|
||||||
#define COCOA_DIALOG_DEFAULT 1
|
#define COCOA_DIALOG_DEFAULT 1
|
||||||
#define COCOA_DIALOG_OK 1
|
#define COCOA_DIALOG_OK 1
|
||||||
|
@ -397,19 +387,6 @@ enum
|
||||||
CORE3DLIST_OPENGL
|
CORE3DLIST_OPENGL
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
MICROPHONE MODE
|
|
||||||
*/
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
MICMODE_NONE = 0,
|
|
||||||
MICMODE_INTERNAL_NOISE,
|
|
||||||
MICMODE_AUDIO_FILE,
|
|
||||||
MICMODE_WHITE_NOISE,
|
|
||||||
MICMODE_PHYSICAL,
|
|
||||||
MICMODE_SINE_WAVE
|
|
||||||
};
|
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
PADDLE_CONTROL_RELATIVE = 0,
|
PADDLE_CONTROL_RELATIVE = 0,
|
||||||
|
|
|
@ -28,16 +28,6 @@ struct CoreAudioInputDeviceInfo;
|
||||||
class AudioGenerator;
|
class AudioGenerator;
|
||||||
class AudioSampleBlockGenerator;
|
class AudioSampleBlockGenerator;
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
bool isPressed;
|
|
||||||
bool turbo;
|
|
||||||
bool autohold;
|
|
||||||
uint32_t turboPattern;
|
|
||||||
uint8_t turboPatternStep;
|
|
||||||
uint8_t turboPatternLength;
|
|
||||||
} ClientInput;
|
|
||||||
|
|
||||||
@protocol CocoaDSControllerDelegate <NSObject>
|
@protocol CocoaDSControllerDelegate <NSObject>
|
||||||
|
|
||||||
@optional
|
@optional
|
||||||
|
@ -53,13 +43,8 @@ typedef struct
|
||||||
@interface CocoaDSController : NSObject
|
@interface CocoaDSController : NSObject
|
||||||
{
|
{
|
||||||
id <CocoaDSControllerDelegate> delegate;
|
id <CocoaDSControllerDelegate> delegate;
|
||||||
|
ClientExecutionControl *execControl;
|
||||||
|
|
||||||
ClientInput clientInput[NDSInputID_InputCount];
|
|
||||||
BOOL autohold;
|
|
||||||
BOOL _isAutoholdCleared;
|
|
||||||
|
|
||||||
NSPoint touchLocation;
|
|
||||||
NSInteger paddleAdjust;
|
|
||||||
NSInteger stylusPressure;
|
NSInteger stylusPressure;
|
||||||
|
|
||||||
float micLevel;
|
float micLevel;
|
||||||
|
@ -67,23 +52,18 @@ typedef struct
|
||||||
float _micLevelsRead;
|
float _micLevelsRead;
|
||||||
|
|
||||||
BOOL hardwareMicMute;
|
BOOL hardwareMicMute;
|
||||||
BOOL _useHardwareMic;
|
|
||||||
size_t _availableMicSamples;
|
size_t _availableMicSamples;
|
||||||
NSInteger micMode;
|
|
||||||
|
|
||||||
AudioSampleBlockGenerator *selectedAudioFileGenerator;
|
|
||||||
CoreAudioInput *CAInputDevice;
|
CoreAudioInput *CAInputDevice;
|
||||||
AudioGenerator *softwareMicSampleGenerator;
|
|
||||||
|
|
||||||
NSString *hardwareMicInfoString;
|
NSString *hardwareMicInfoString;
|
||||||
NSString *hardwareMicNameString;
|
NSString *hardwareMicNameString;
|
||||||
NSString *hardwareMicManufacturerString;
|
NSString *hardwareMicManufacturerString;
|
||||||
NSString *hardwareMicSampleRateString;
|
NSString *hardwareMicSampleRateString;
|
||||||
|
|
||||||
OSSpinLock spinlockControllerState;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@property (retain) id <CocoaDSControllerDelegate> delegate;
|
@property (retain) id <CocoaDSControllerDelegate> delegate;
|
||||||
|
@property (assign) ClientExecutionControl *execControl;
|
||||||
@property (assign) BOOL autohold;
|
@property (assign) BOOL autohold;
|
||||||
@property (assign) NSInteger paddleAdjust;
|
@property (assign) NSInteger paddleAdjust;
|
||||||
@property (assign) NSInteger stylusPressure;
|
@property (assign) NSInteger stylusPressure;
|
||||||
|
@ -96,9 +76,6 @@ typedef struct
|
||||||
@property (assign) float hardwareMicGain;
|
@property (assign) float hardwareMicGain;
|
||||||
@property (assign) BOOL hardwareMicMute;
|
@property (assign) BOOL hardwareMicMute;
|
||||||
@property (assign) BOOL hardwareMicPause;
|
@property (assign) BOOL hardwareMicPause;
|
||||||
@property (assign) BOOL softwareMicState;
|
|
||||||
@property (assign) NSInteger softwareMicMode;
|
|
||||||
@property (assign) NSInteger micMode;
|
|
||||||
@property (readonly) CoreAudioInput *CAInputDevice;
|
@property (readonly) CoreAudioInput *CAInputDevice;
|
||||||
@property (readonly) AudioGenerator *softwareMicSampleGenerator;
|
@property (readonly) AudioGenerator *softwareMicSampleGenerator;
|
||||||
@property (assign) AudioSampleBlockGenerator *selectedAudioFileGenerator;
|
@property (assign) AudioSampleBlockGenerator *selectedAudioFileGenerator;
|
||||||
|
@ -107,13 +84,13 @@ typedef struct
|
||||||
@property (retain) NSString *hardwareMicManufacturerString;
|
@property (retain) NSString *hardwareMicManufacturerString;
|
||||||
@property (retain) NSString *hardwareMicSampleRateString;
|
@property (retain) NSString *hardwareMicSampleRateString;
|
||||||
|
|
||||||
|
- (void) setSoftwareMicState:(BOOL)theState mode:(NSInteger)micMode;
|
||||||
|
- (BOOL) softwareMicState;
|
||||||
- (void) setControllerState:(BOOL)theState controlID:(const NSUInteger)controlID;
|
- (void) setControllerState:(BOOL)theState controlID:(const NSUInteger)controlID;
|
||||||
- (void) setControllerState:(BOOL)theState controlID:(const NSUInteger)controlID turbo:(const BOOL)isTurboEnabled turboPattern:(uint32_t)turboPattern turboPatternLength:(uint32_t)turboPatternLength;
|
- (void) setControllerState:(BOOL)theState controlID:(const NSUInteger)controlID turbo:(const BOOL)isTurboEnabled turboPattern:(uint32_t)turboPattern turboPatternLength:(uint32_t)turboPatternLength;
|
||||||
- (void) setTouchState:(BOOL)theState location:(const NSPoint)theLocation;
|
- (void) setTouchState:(BOOL)theState location:(const NSPoint)theLocation;
|
||||||
- (void) setSineWaveGeneratorFrequency:(const double)freq;
|
- (void) setSineWaveGeneratorFrequency:(const double)freq;
|
||||||
- (void) clearAutohold;
|
- (void) clearAutohold;
|
||||||
- (void) flush;
|
|
||||||
- (void) flushEmpty;
|
|
||||||
- (void) reset;
|
- (void) reset;
|
||||||
|
|
||||||
- (void) clearMicLevelMeasure;
|
- (void) clearMicLevelMeasure;
|
||||||
|
|
|
@ -26,17 +26,13 @@
|
||||||
#include "../../slot2.h"
|
#include "../../slot2.h"
|
||||||
#undef BOOL
|
#undef BOOL
|
||||||
|
|
||||||
NullGenerator nullSampleGenerator;
|
|
||||||
InternalNoiseGenerator internalNoiseGenerator;
|
|
||||||
WhiteNoiseGenerator whiteNoiseGenerator;
|
|
||||||
SineWaveGenerator sineWaveGenerator(250.0, MIC_SAMPLE_RATE);
|
|
||||||
|
|
||||||
|
|
||||||
@implementation CocoaDSController
|
@implementation CocoaDSController
|
||||||
|
|
||||||
@synthesize delegate;
|
@synthesize delegate;
|
||||||
|
@synthesize execControl;
|
||||||
@dynamic autohold;
|
@dynamic autohold;
|
||||||
@synthesize paddleAdjust;
|
@dynamic paddleAdjust;
|
||||||
@synthesize stylusPressure;
|
@synthesize stylusPressure;
|
||||||
@dynamic isHardwareMicAvailable;
|
@dynamic isHardwareMicAvailable;
|
||||||
@dynamic isHardwareMicIdle;
|
@dynamic isHardwareMicIdle;
|
||||||
|
@ -47,12 +43,9 @@ SineWaveGenerator sineWaveGenerator(250.0, MIC_SAMPLE_RATE);
|
||||||
@dynamic hardwareMicGain;
|
@dynamic hardwareMicGain;
|
||||||
@synthesize hardwareMicMute;
|
@synthesize hardwareMicMute;
|
||||||
@dynamic hardwareMicPause;
|
@dynamic hardwareMicPause;
|
||||||
@dynamic softwareMicState;
|
|
||||||
@dynamic softwareMicMode;
|
|
||||||
@synthesize micMode;
|
|
||||||
@synthesize CAInputDevice;
|
@synthesize CAInputDevice;
|
||||||
@synthesize softwareMicSampleGenerator;
|
@dynamic softwareMicSampleGenerator;
|
||||||
@synthesize selectedAudioFileGenerator;
|
@dynamic selectedAudioFileGenerator;
|
||||||
@synthesize hardwareMicInfoString;
|
@synthesize hardwareMicInfoString;
|
||||||
@synthesize hardwareMicNameString;
|
@synthesize hardwareMicNameString;
|
||||||
@synthesize hardwareMicManufacturerString;
|
@synthesize hardwareMicManufacturerString;
|
||||||
|
@ -65,36 +58,18 @@ SineWaveGenerator sineWaveGenerator(250.0, MIC_SAMPLE_RATE);
|
||||||
{
|
{
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < NDSInputID_InputCount; i++)
|
|
||||||
{
|
|
||||||
clientInput[i].isPressed = false;
|
|
||||||
clientInput[i].turbo = false;
|
|
||||||
clientInput[i].turboPattern = 0;
|
|
||||||
clientInput[i].turboPatternStep = 0;
|
|
||||||
clientInput[i].turboPatternLength = 0;
|
|
||||||
clientInput[i].autohold = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
delegate = nil;
|
delegate = nil;
|
||||||
spinlockControllerState = OS_SPINLOCK_INIT;
|
execControl = NULL;
|
||||||
autohold = NO;
|
|
||||||
_isAutoholdCleared = YES;
|
|
||||||
_useHardwareMic = NO;
|
|
||||||
_availableMicSamples = 0;
|
_availableMicSamples = 0;
|
||||||
|
|
||||||
micLevel = 0.0f;
|
micLevel = 0.0f;
|
||||||
_micLevelTotal = 0.0f;
|
_micLevelTotal = 0.0f;
|
||||||
_micLevelsRead = 0.0f;
|
_micLevelsRead = 0.0f;
|
||||||
|
|
||||||
micMode = MICMODE_NONE;
|
|
||||||
selectedAudioFileGenerator = NULL;
|
|
||||||
CAInputDevice = new CoreAudioInput;
|
CAInputDevice = new CoreAudioInput;
|
||||||
CAInputDevice->SetCallbackHardwareStateChanged(&CAHardwareStateChangedCallback, self, NULL);
|
CAInputDevice->SetCallbackHardwareStateChanged(&CAHardwareStateChangedCallback, self, NULL);
|
||||||
CAInputDevice->SetCallbackHardwareGainChanged(&CAHardwareGainChangedCallback, self, NULL);
|
CAInputDevice->SetCallbackHardwareGainChanged(&CAHardwareGainChangedCallback, self, NULL);
|
||||||
softwareMicSampleGenerator = &nullSampleGenerator;
|
|
||||||
touchLocation = NSMakePoint(0.0f, 0.0f);
|
|
||||||
paddleAdjust = 0;
|
|
||||||
|
|
||||||
hardwareMicInfoString = @"No hardware input detected.";
|
hardwareMicInfoString = @"No hardware input detected.";
|
||||||
hardwareMicNameString = @"No hardware input detected.";
|
hardwareMicNameString = @"No hardware input detected.";
|
||||||
|
@ -180,365 +155,94 @@ SineWaveGenerator sineWaveGenerator(250.0, MIC_SAMPLE_RATE);
|
||||||
return (CAInputDevice->GetPauseState()) ? YES : NO;
|
return (CAInputDevice->GetPauseState()) ? YES : NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) setSoftwareMicState:(BOOL)theState
|
- (void) setSoftwareMicState:(BOOL)theState mode:(NSInteger)micMode
|
||||||
{
|
{
|
||||||
OSSpinLockLock(&spinlockControllerState);
|
execControl->SetClientSoftwareMicState((theState) ? true : false, (MicrophoneMode)micMode);
|
||||||
clientInput[NDSInputID_Microphone].isPressed = (theState) ? true : false;
|
|
||||||
OSSpinLockUnlock(&spinlockControllerState);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL) softwareMicState
|
- (BOOL) softwareMicState
|
||||||
{
|
{
|
||||||
OSSpinLockLock(&spinlockControllerState);
|
return (execControl->GetClientSoftwareMicState()) ? YES : NO;
|
||||||
BOOL theState = (clientInput[NDSInputID_Microphone].isPressed) ? YES : NO;
|
|
||||||
OSSpinLockUnlock(&spinlockControllerState);
|
|
||||||
return theState;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) setSoftwareMicMode:(NSInteger)theMode
|
- (AudioGenerator *) softwareMicSampleGenerator
|
||||||
{
|
{
|
||||||
OSSpinLockLock(&spinlockControllerState);
|
return execControl->GetClientSoftwareMicSampleGenerator();
|
||||||
micMode = theMode;
|
|
||||||
OSSpinLockUnlock(&spinlockControllerState);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSInteger) softwareMicMode
|
- (void) setSelectedAudioFileGenerator:(AudioSampleBlockGenerator *)audioGenerator
|
||||||
{
|
{
|
||||||
OSSpinLockLock(&spinlockControllerState);
|
execControl->SetClientSelectedAudioFileGenerator(audioGenerator);
|
||||||
NSInteger theMode = micMode;
|
}
|
||||||
OSSpinLockUnlock(&spinlockControllerState);
|
|
||||||
return theMode;
|
- (AudioSampleBlockGenerator *) selectedAudioFileGenerator
|
||||||
|
{
|
||||||
|
return execControl->GetClientSelectedAudioFileGenerator();
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) setAutohold:(BOOL)theState
|
- (void) setAutohold:(BOOL)theState
|
||||||
{
|
{
|
||||||
OSSpinLockLock(&spinlockControllerState);
|
execControl->SetEnableAutohold((theState) ? true: false);
|
||||||
|
|
||||||
autohold = theState;
|
|
||||||
|
|
||||||
if (autohold && _isAutoholdCleared)
|
|
||||||
{
|
|
||||||
memset(clientInput, 0, sizeof(clientInput));
|
|
||||||
_isAutoholdCleared = NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!autohold)
|
|
||||||
{
|
|
||||||
for (size_t i = 0; i < NDSInputID_InputCount; i++)
|
|
||||||
{
|
|
||||||
clientInput[i].isPressed = clientInput[i].autohold;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
OSSpinLockUnlock(&spinlockControllerState);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL) autohold
|
- (BOOL) autohold
|
||||||
{
|
{
|
||||||
OSSpinLockLock(&spinlockControllerState);
|
return (execControl->GetEnableAutohold()) ? YES : NO;
|
||||||
const BOOL theState = autohold;
|
}
|
||||||
OSSpinLockUnlock(&spinlockControllerState);
|
|
||||||
return theState;
|
- (void) setPaddleAdjust:(NSInteger)paddleAdjust
|
||||||
|
{
|
||||||
|
execControl->SetClientPaddleAdjust((int16_t)paddleAdjust);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSInteger) paddleAdjust
|
||||||
|
{
|
||||||
|
return (NSInteger)execControl->GetClientPaddleAdjust();
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) setControllerState:(BOOL)theState controlID:(const NSUInteger)controlID
|
- (void) setControllerState:(BOOL)theState controlID:(const NSUInteger)controlID
|
||||||
{
|
{
|
||||||
[self setControllerState:theState controlID:controlID turbo:NO turboPattern:0 turboPatternLength:0];
|
execControl->SetClientInputStateUsingID((NDSInputID)controlID,
|
||||||
|
(theState) ? true : false,
|
||||||
|
false,
|
||||||
|
0,
|
||||||
|
0);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) setControllerState:(BOOL)theState controlID:(const NSUInteger)controlID turbo:(const BOOL)isTurboEnabled turboPattern:(uint32_t)turboPattern turboPatternLength:(uint32_t)turboPatternLength
|
- (void) setControllerState:(BOOL)theState controlID:(const NSUInteger)controlID turbo:(const BOOL)isTurboEnabled turboPattern:(uint32_t)turboPattern turboPatternLength:(uint32_t)turboPatternLength
|
||||||
{
|
{
|
||||||
if (controlID >= NDSInputID_InputCount)
|
execControl->SetClientInputStateUsingID((NDSInputID)controlID,
|
||||||
{
|
(theState) ? true : false,
|
||||||
return;
|
(isTurboEnabled) ? true : false,
|
||||||
}
|
turboPattern,
|
||||||
|
turboPatternLength);
|
||||||
OSSpinLockLock(&spinlockControllerState);
|
|
||||||
|
|
||||||
if (autohold)
|
|
||||||
{
|
|
||||||
if (theState)
|
|
||||||
{
|
|
||||||
clientInput[controlID].turbo = (isTurboEnabled) ? true : false;
|
|
||||||
clientInput[controlID].autohold = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
clientInput[controlID].isPressed = (theState || clientInput[controlID].autohold);
|
|
||||||
clientInput[controlID].turbo = (isTurboEnabled && clientInput[controlID].isPressed);
|
|
||||||
}
|
|
||||||
|
|
||||||
clientInput[controlID].turboPattern = (clientInput[controlID].turbo) ? turboPattern : 0;
|
|
||||||
|
|
||||||
if (turboPatternLength > 32)
|
|
||||||
{
|
|
||||||
turboPatternLength = 32;
|
|
||||||
}
|
|
||||||
|
|
||||||
clientInput[controlID].turboPatternLength = (clientInput[controlID].turbo) ? turboPatternLength : 0;
|
|
||||||
|
|
||||||
if (!clientInput[controlID].turbo)
|
|
||||||
{
|
|
||||||
clientInput[controlID].turboPatternStep = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
OSSpinLockUnlock(&spinlockControllerState);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) setTouchState:(BOOL)theState location:(const NSPoint)theLocation
|
- (void) setTouchState:(BOOL)theState location:(const NSPoint)theLocation
|
||||||
{
|
{
|
||||||
OSSpinLockLock(&spinlockControllerState);
|
execControl->SetClientTouchState((theState) ? true : false,
|
||||||
clientInput[NDSInputID_Touch].isPressed = (theState) ? true : false;
|
(uint8_t)(theLocation.x + 0.3f),
|
||||||
touchLocation = theLocation;
|
(uint8_t)(theLocation.y + 0.3f),
|
||||||
OSSpinLockUnlock(&spinlockControllerState);
|
(uint8_t)[self stylusPressure]);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) setSineWaveGeneratorFrequency:(const double)freq
|
- (void) setSineWaveGeneratorFrequency:(const double)freq
|
||||||
{
|
{
|
||||||
sineWaveGenerator.setFrequency(freq);
|
execControl->SetSineWaveFrequency(freq);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) clearAutohold
|
- (void) clearAutohold
|
||||||
{
|
{
|
||||||
[self setAutohold:NO];
|
execControl->ClearAutohold();
|
||||||
OSSpinLockLock(&spinlockControllerState);
|
|
||||||
|
|
||||||
if (!_isAutoholdCleared)
|
|
||||||
{
|
|
||||||
memset(clientInput, 0, sizeof(clientInput));
|
|
||||||
_isAutoholdCleared = YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
OSSpinLockUnlock(&spinlockControllerState);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void) flush
|
|
||||||
{
|
|
||||||
OSSpinLockLock(&spinlockControllerState);
|
|
||||||
|
|
||||||
const NSPoint theLocation = touchLocation;
|
|
||||||
const NSInteger theMicMode = micMode;
|
|
||||||
bool flushedStates[NDSInputID_InputCount] = {0};
|
|
||||||
|
|
||||||
if (!autohold)
|
|
||||||
{
|
|
||||||
for (size_t i = 0; i < NDSInputID_InputCount; i++)
|
|
||||||
{
|
|
||||||
flushedStates[i] = (clientInput[i].isPressed || clientInput[i].autohold);
|
|
||||||
|
|
||||||
if (clientInput[i].turbo)
|
|
||||||
{
|
|
||||||
const bool pressedState = (clientInput[i].turboPattern >> clientInput[i].turboPatternStep) & 0x00000001;
|
|
||||||
flushedStates[i] = (flushedStates[i] && pressedState);
|
|
||||||
|
|
||||||
clientInput[i].turboPatternStep++;
|
|
||||||
if (clientInput[i].turboPatternStep >= clientInput[i].turboPatternLength)
|
|
||||||
{
|
|
||||||
clientInput[i].turboPatternStep = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
flushedStates[i] = clientInput[i].isPressed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
OSSpinLockUnlock(&spinlockControllerState);
|
|
||||||
|
|
||||||
const bool isTouchDown = flushedStates[NDSInputID_Touch];
|
|
||||||
const bool isMicPressed = flushedStates[NDSInputID_Microphone];
|
|
||||||
|
|
||||||
// Setup the DS pad.
|
|
||||||
NDS_setPad(flushedStates[NDSInputID_Right],
|
|
||||||
flushedStates[NDSInputID_Left],
|
|
||||||
flushedStates[NDSInputID_Down],
|
|
||||||
flushedStates[NDSInputID_Up],
|
|
||||||
flushedStates[NDSInputID_Select],
|
|
||||||
flushedStates[NDSInputID_Start],
|
|
||||||
flushedStates[NDSInputID_B],
|
|
||||||
flushedStates[NDSInputID_A],
|
|
||||||
flushedStates[NDSInputID_Y],
|
|
||||||
flushedStates[NDSInputID_X],
|
|
||||||
flushedStates[NDSInputID_L],
|
|
||||||
flushedStates[NDSInputID_R],
|
|
||||||
flushedStates[NDSInputID_Debug],
|
|
||||||
flushedStates[NDSInputID_Lid]);
|
|
||||||
|
|
||||||
// Setup the DS touch pad.
|
|
||||||
CommonSettings.StylusPressure = (int)[self stylusPressure];
|
|
||||||
|
|
||||||
if (isTouchDown)
|
|
||||||
{
|
|
||||||
NDS_setTouchPos((u16)theLocation.x, (u16)theLocation.y);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
NDS_releaseTouch();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup the inputs from SLOT-2 devices.
|
|
||||||
const NDS_SLOT2_TYPE slot2DeviceType = slot2_GetSelectedType();
|
|
||||||
switch (slot2DeviceType)
|
|
||||||
{
|
|
||||||
case NDS_SLOT2_GUITARGRIP:
|
|
||||||
guitarGrip_setKey(flushedStates[NDSInputID_GuitarGrip_Green],
|
|
||||||
flushedStates[NDSInputID_GuitarGrip_Red],
|
|
||||||
flushedStates[NDSInputID_GuitarGrip_Yellow],
|
|
||||||
flushedStates[NDSInputID_GuitarGrip_Blue]);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NDS_SLOT2_EASYPIANO:
|
|
||||||
piano_setKey(flushedStates[NDSInputID_Piano_C],
|
|
||||||
flushedStates[NDSInputID_Piano_CSharp],
|
|
||||||
flushedStates[NDSInputID_Piano_D],
|
|
||||||
flushedStates[NDSInputID_Piano_DSharp],
|
|
||||||
flushedStates[NDSInputID_Piano_E],
|
|
||||||
flushedStates[NDSInputID_Piano_F],
|
|
||||||
flushedStates[NDSInputID_Piano_FSharp],
|
|
||||||
flushedStates[NDSInputID_Piano_G],
|
|
||||||
flushedStates[NDSInputID_Piano_GSharp],
|
|
||||||
flushedStates[NDSInputID_Piano_A],
|
|
||||||
flushedStates[NDSInputID_Piano_ASharp],
|
|
||||||
flushedStates[NDSInputID_Piano_B],
|
|
||||||
flushedStates[NDSInputID_Piano_HighC]);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NDS_SLOT2_PADDLE:
|
|
||||||
{
|
|
||||||
const u16 newPaddleValue = Paddle_GetValue() + (u16)[self paddleAdjust];
|
|
||||||
Paddle_SetValue(newPaddleValue);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup the DS mic.
|
|
||||||
AudioGenerator *selectedGenerator = &nullSampleGenerator;
|
|
||||||
|
|
||||||
if (isMicPressed)
|
|
||||||
{
|
|
||||||
switch (theMicMode)
|
|
||||||
{
|
|
||||||
case MICMODE_INTERNAL_NOISE:
|
|
||||||
selectedGenerator = &internalNoiseGenerator;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MICMODE_WHITE_NOISE:
|
|
||||||
selectedGenerator = &whiteNoiseGenerator;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MICMODE_SINE_WAVE:
|
|
||||||
selectedGenerator = &sineWaveGenerator;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MICMODE_AUDIO_FILE:
|
|
||||||
if (selectedAudioFileGenerator != NULL)
|
|
||||||
{
|
|
||||||
selectedGenerator = selectedAudioFileGenerator;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
selectedGenerator = &nullSampleGenerator;
|
|
||||||
internalNoiseGenerator.setSamplePosition(0);
|
|
||||||
sineWaveGenerator.setCyclePosition(0.0);
|
|
||||||
|
|
||||||
if (selectedAudioFileGenerator != NULL)
|
|
||||||
{
|
|
||||||
selectedAudioFileGenerator->setSamplePosition(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_useHardwareMic = (isMicPressed) ? NO : YES;
|
|
||||||
softwareMicSampleGenerator = selectedGenerator;
|
|
||||||
NDS_setMic(isMicPressed);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void) flushEmpty
|
|
||||||
{
|
|
||||||
// Setup the DS pad.
|
|
||||||
NDS_setPad(false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false);
|
|
||||||
|
|
||||||
// Setup the DS touch pad.
|
|
||||||
NDS_releaseTouch();
|
|
||||||
|
|
||||||
// Setup the inputs from SLOT-2 devices.
|
|
||||||
const NDS_SLOT2_TYPE slot2DeviceType = slot2_GetSelectedType();
|
|
||||||
switch (slot2DeviceType)
|
|
||||||
{
|
|
||||||
case NDS_SLOT2_GUITARGRIP:
|
|
||||||
guitarGrip_setKey(false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NDS_SLOT2_EASYPIANO:
|
|
||||||
piano_setKey(false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NDS_SLOT2_PADDLE:
|
|
||||||
// Do nothing.
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup the DS mic.
|
|
||||||
_useHardwareMic = NO;
|
|
||||||
softwareMicSampleGenerator = &nullSampleGenerator;
|
|
||||||
NDS_setMic(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) reset
|
- (void) reset
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < NDSInputID_InputCount; i++)
|
|
||||||
{
|
|
||||||
memset(clientInput, 0, sizeof(clientInput));
|
|
||||||
}
|
|
||||||
|
|
||||||
[self setAutohold:NO];
|
[self setAutohold:NO];
|
||||||
[self setMicLevel:0.0f];
|
[self setMicLevel:0.0f];
|
||||||
|
[self clearMicLevelMeasure];
|
||||||
|
|
||||||
_isAutoholdCleared = YES;
|
|
||||||
_availableMicSamples = 0;
|
_availableMicSamples = 0;
|
||||||
_micLevelTotal = 0.0f;
|
|
||||||
_micLevelsRead = 0.0f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) clearMicLevelMeasure
|
- (void) clearMicLevelMeasure
|
||||||
|
@ -549,7 +253,7 @@ SineWaveGenerator sineWaveGenerator(250.0, MIC_SAMPLE_RATE);
|
||||||
|
|
||||||
- (void) updateMicLevel
|
- (void) updateMicLevel
|
||||||
{
|
{
|
||||||
float avgMicLevel = _micLevelTotal / _micLevelsRead;
|
float avgMicLevel = (_micLevelsRead != 0) ? _micLevelTotal / _micLevelsRead : 0.0f;
|
||||||
|
|
||||||
NSAutoreleasePool *tempPool = [[NSAutoreleasePool alloc] init];
|
NSAutoreleasePool *tempPool = [[NSAutoreleasePool alloc] init];
|
||||||
[self setMicLevel:avgMicLevel];
|
[self setMicLevel:avgMicLevel];
|
||||||
|
@ -566,7 +270,7 @@ SineWaveGenerator sineWaveGenerator(250.0, MIC_SAMPLE_RATE);
|
||||||
{
|
{
|
||||||
uint8_t theSample = MIC_NULL_SAMPLE_VALUE;
|
uint8_t theSample = MIC_NULL_SAMPLE_VALUE;
|
||||||
|
|
||||||
if (_useHardwareMic && (caInput != NULL))
|
if (!execControl->GetClientSoftwareMicStateApplied() && (caInput != NULL))
|
||||||
{
|
{
|
||||||
if (caInput->GetPauseState())
|
if (caInput->GetPauseState())
|
||||||
{
|
{
|
||||||
|
|
|
@ -148,12 +148,16 @@
|
||||||
@property (assign) BOOL isHUDLagFrameCountVisible;
|
@property (assign) BOOL isHUDLagFrameCountVisible;
|
||||||
@property (assign) BOOL isHUDCPULoadAverageVisible;
|
@property (assign) BOOL isHUDCPULoadAverageVisible;
|
||||||
@property (assign) BOOL isHUDRealTimeClockVisible;
|
@property (assign) BOOL isHUDRealTimeClockVisible;
|
||||||
|
@property (assign) BOOL isHUDInputVisible;
|
||||||
@property (assign) uint32_t hudColorVideoFPS;
|
@property (assign) uint32_t hudColorVideoFPS;
|
||||||
@property (assign) uint32_t hudColorRender3DFPS;
|
@property (assign) uint32_t hudColorRender3DFPS;
|
||||||
@property (assign) uint32_t hudColorFrameIndex;
|
@property (assign) uint32_t hudColorFrameIndex;
|
||||||
@property (assign) uint32_t hudColorLagFrameCount;
|
@property (assign) uint32_t hudColorLagFrameCount;
|
||||||
@property (assign) uint32_t hudColorCPULoadAverage;
|
@property (assign) uint32_t hudColorCPULoadAverage;
|
||||||
@property (assign) uint32_t hudColorRTC;
|
@property (assign) uint32_t hudColorRTC;
|
||||||
|
@property (assign) uint32_t hudColorInputPendingAndApplied;
|
||||||
|
@property (assign) uint32_t hudColorInputAppliedOnly;
|
||||||
|
@property (assign) uint32_t hudColorInputPendingOnly;
|
||||||
@property (assign) NSInteger displayMainVideoSource;
|
@property (assign) NSInteger displayMainVideoSource;
|
||||||
@property (assign) NSInteger displayTouchVideoSource;
|
@property (assign) NSInteger displayTouchVideoSource;
|
||||||
@property (assign) BOOL useVerticalSync;
|
@property (assign) BOOL useVerticalSync;
|
||||||
|
@ -168,5 +172,6 @@
|
||||||
- (void) handleRedraw;
|
- (void) handleRedraw;
|
||||||
|
|
||||||
- (void) setScaleFactor:(float)theScaleFactor;
|
- (void) setScaleFactor:(float)theScaleFactor;
|
||||||
|
- (void) hudUpdate;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -741,12 +741,16 @@
|
||||||
@dynamic isHUDLagFrameCountVisible;
|
@dynamic isHUDLagFrameCountVisible;
|
||||||
@dynamic isHUDCPULoadAverageVisible;
|
@dynamic isHUDCPULoadAverageVisible;
|
||||||
@dynamic isHUDRealTimeClockVisible;
|
@dynamic isHUDRealTimeClockVisible;
|
||||||
|
@dynamic isHUDInputVisible;
|
||||||
@dynamic hudColorVideoFPS;
|
@dynamic hudColorVideoFPS;
|
||||||
@dynamic hudColorRender3DFPS;
|
@dynamic hudColorRender3DFPS;
|
||||||
@dynamic hudColorFrameIndex;
|
@dynamic hudColorFrameIndex;
|
||||||
@dynamic hudColorLagFrameCount;
|
@dynamic hudColorLagFrameCount;
|
||||||
@dynamic hudColorCPULoadAverage;
|
@dynamic hudColorCPULoadAverage;
|
||||||
@dynamic hudColorRTC;
|
@dynamic hudColorRTC;
|
||||||
|
@dynamic hudColorInputPendingAndApplied;
|
||||||
|
@dynamic hudColorInputAppliedOnly;
|
||||||
|
@dynamic hudColorInputPendingOnly;
|
||||||
@dynamic useVerticalSync;
|
@dynamic useVerticalSync;
|
||||||
@dynamic videoFiltersPreferGPU;
|
@dynamic videoFiltersPreferGPU;
|
||||||
@dynamic sourceDeposterize;
|
@dynamic sourceDeposterize;
|
||||||
|
@ -901,6 +905,22 @@
|
||||||
return theState;
|
return theState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) setIsHUDInputVisible:(BOOL)theState
|
||||||
|
{
|
||||||
|
OSSpinLockLock(&spinlockIsHUDVisible);
|
||||||
|
_cdv->SetHUDShowInput((theState) ? true : false);
|
||||||
|
OSSpinLockUnlock(&spinlockIsHUDVisible);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL) isHUDInputVisible
|
||||||
|
{
|
||||||
|
OSSpinLockLock(&spinlockIsHUDVisible);
|
||||||
|
const BOOL theState = (_cdv->GetHUDShowInput()) ? YES : NO;
|
||||||
|
OSSpinLockUnlock(&spinlockIsHUDVisible);
|
||||||
|
|
||||||
|
return theState;
|
||||||
|
}
|
||||||
|
|
||||||
- (void) setHudColorVideoFPS:(uint32_t)theColor
|
- (void) setHudColorVideoFPS:(uint32_t)theColor
|
||||||
{
|
{
|
||||||
OSSpinLockLock(&spinlockIsHUDVisible);
|
OSSpinLockLock(&spinlockIsHUDVisible);
|
||||||
|
@ -997,6 +1017,54 @@
|
||||||
return color32;
|
return color32;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) setHudColorInputPendingAndApplied:(uint32_t)theColor
|
||||||
|
{
|
||||||
|
OSSpinLockLock(&spinlockIsHUDVisible);
|
||||||
|
_cdv->SetHUDColorInputPendingAndApplied(theColor);
|
||||||
|
OSSpinLockUnlock(&spinlockIsHUDVisible);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (uint32_t) hudColorInputPendingAndApplied
|
||||||
|
{
|
||||||
|
OSSpinLockLock(&spinlockIsHUDVisible);
|
||||||
|
const uint32_t color32 = _cdv->GetHUDColorInputPendingAndApplied();
|
||||||
|
OSSpinLockUnlock(&spinlockIsHUDVisible);
|
||||||
|
|
||||||
|
return color32;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) setHudColorInputAppliedOnly:(uint32_t)theColor
|
||||||
|
{
|
||||||
|
OSSpinLockLock(&spinlockIsHUDVisible);
|
||||||
|
_cdv->SetHUDColorInputAppliedOnly(theColor);
|
||||||
|
OSSpinLockUnlock(&spinlockIsHUDVisible);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (uint32_t) hudColorInputAppliedOnly
|
||||||
|
{
|
||||||
|
OSSpinLockLock(&spinlockIsHUDVisible);
|
||||||
|
const uint32_t color32 = _cdv->GetHUDColorInputAppliedOnly();
|
||||||
|
OSSpinLockUnlock(&spinlockIsHUDVisible);
|
||||||
|
|
||||||
|
return color32;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) setHudColorInputPendingOnly:(uint32_t)theColor
|
||||||
|
{
|
||||||
|
OSSpinLockLock(&spinlockIsHUDVisible);
|
||||||
|
_cdv->SetHUDColorInputPendingOnly(theColor);
|
||||||
|
OSSpinLockUnlock(&spinlockIsHUDVisible);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (uint32_t) hudColorInputPendingOnly
|
||||||
|
{
|
||||||
|
OSSpinLockLock(&spinlockIsHUDVisible);
|
||||||
|
const uint32_t color32 = _cdv->GetHUDColorInputPendingOnly();
|
||||||
|
OSSpinLockUnlock(&spinlockIsHUDVisible);
|
||||||
|
|
||||||
|
return color32;
|
||||||
|
}
|
||||||
|
|
||||||
- (void) setDisplayMainVideoSource:(NSInteger)displaySourceID
|
- (void) setDisplayMainVideoSource:(NSInteger)displaySourceID
|
||||||
{
|
{
|
||||||
OSSpinLockLock(&spinlockDisplayVideoSource);
|
OSSpinLockLock(&spinlockDisplayVideoSource);
|
||||||
|
@ -1136,16 +1204,7 @@
|
||||||
- (void) handleEmuFrameProcessed
|
- (void) handleEmuFrameProcessed
|
||||||
{
|
{
|
||||||
[super handleEmuFrameProcessed];
|
[super handleEmuFrameProcessed];
|
||||||
|
[self hudUpdate];
|
||||||
OSSpinLockLock(&spinlockReceivedFrameIndex);
|
|
||||||
ClientFrameInfo clientFrameInfo;
|
|
||||||
clientFrameInfo.videoFPS = _receivedFrameCount;
|
|
||||||
OSSpinLockUnlock(&spinlockReceivedFrameIndex);
|
|
||||||
|
|
||||||
OSSpinLockLock(&spinlockNDSFrameInfo);
|
|
||||||
_cdv->SetHUDInfo(clientFrameInfo, _ndsFrameInfo);
|
|
||||||
OSSpinLockUnlock(&spinlockNDSFrameInfo);
|
|
||||||
|
|
||||||
_cdv->HandleEmulatorFrameEndEvent();
|
_cdv->HandleEmulatorFrameEndEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1187,4 +1246,16 @@
|
||||||
OSSpinLockUnlock(&spinlockIsHUDVisible);
|
OSSpinLockUnlock(&spinlockIsHUDVisible);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) hudUpdate
|
||||||
|
{
|
||||||
|
OSSpinLockLock(&spinlockReceivedFrameIndex);
|
||||||
|
ClientFrameInfo clientFrameInfo;
|
||||||
|
clientFrameInfo.videoFPS = _receivedFrameCount;
|
||||||
|
OSSpinLockUnlock(&spinlockReceivedFrameIndex);
|
||||||
|
|
||||||
|
OSSpinLockLock(&spinlockNDSFrameInfo);
|
||||||
|
_cdv->SetHUDInfo(clientFrameInfo, _ndsFrameInfo);
|
||||||
|
OSSpinLockUnlock(&spinlockNDSFrameInfo);
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -18,9 +18,11 @@
|
||||||
#include "coreaudiosound.h"
|
#include "coreaudiosound.h"
|
||||||
|
|
||||||
#include <CoreAudio/CoreAudio.h>
|
#include <CoreAudio/CoreAudio.h>
|
||||||
#include "cocoa_globals.h"
|
#include "ClientExecutionControl.h"
|
||||||
#include "utilities.h"
|
#include "utilities.h"
|
||||||
|
|
||||||
|
#import "cocoa_globals.h"
|
||||||
|
|
||||||
//#define FORCE_AUDIOCOMPONENT_10_5
|
//#define FORCE_AUDIOCOMPONENT_10_5
|
||||||
|
|
||||||
CoreAudioInput::CoreAudioInput()
|
CoreAudioInput::CoreAudioInput()
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#import "cocoa_globals.h"
|
#include "ClientExecutionControl.h"
|
||||||
#include "mic_ext.h"
|
#include "mic_ext.h"
|
||||||
#include "../../emufile.h"
|
#include "../../emufile.h"
|
||||||
#include "../../readwrite.h"
|
#include "../../readwrite.h"
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright (C) 2012-2015 DeSmuME team
|
Copyright (C) 2012-2017 DeSmuME team
|
||||||
|
|
||||||
This file is free software: you can redistribute it and/or modify
|
This file is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -86,7 +86,7 @@ volatile bool execute = true;
|
||||||
|
|
||||||
// Set up the DS controller
|
// Set up the DS controller
|
||||||
cdsController = [[[[CocoaDSController alloc] init] retain] autorelease];
|
cdsController = [[[[CocoaDSController alloc] init] retain] autorelease];
|
||||||
[cdsController setMicMode:MICMODE_INTERNAL_NOISE];
|
[cdsController setMicMode:MicrophoneMode_InternalNoise];
|
||||||
|
|
||||||
// Set up the cheat system
|
// Set up the cheat system
|
||||||
cdsCheats = [[[[CocoaDSCheatManager alloc] init] retain] autorelease];
|
cdsCheats = [[[[CocoaDSCheatManager alloc] init] retain] autorelease];
|
||||||
|
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
|
@ -58,12 +58,16 @@ class OGLVideoOutput;
|
||||||
@property (assign) BOOL isHUDLagFrameCountVisible;
|
@property (assign) BOOL isHUDLagFrameCountVisible;
|
||||||
@property (assign) BOOL isHUDCPULoadAverageVisible;
|
@property (assign) BOOL isHUDCPULoadAverageVisible;
|
||||||
@property (assign) BOOL isHUDRealTimeClockVisible;
|
@property (assign) BOOL isHUDRealTimeClockVisible;
|
||||||
|
@property (assign) BOOL isHUDInputVisible;
|
||||||
@property (assign) NSColor *hudColorVideoFPS;
|
@property (assign) NSColor *hudColorVideoFPS;
|
||||||
@property (assign) NSColor *hudColorRender3DFPS;
|
@property (assign) NSColor *hudColorRender3DFPS;
|
||||||
@property (assign) NSColor *hudColorFrameIndex;
|
@property (assign) NSColor *hudColorFrameIndex;
|
||||||
@property (assign) NSColor *hudColorLagFrameCount;
|
@property (assign) NSColor *hudColorLagFrameCount;
|
||||||
@property (assign) NSColor *hudColorCPULoadAverage;
|
@property (assign) NSColor *hudColorCPULoadAverage;
|
||||||
@property (assign) NSColor *hudColorRTC;
|
@property (assign) NSColor *hudColorRTC;
|
||||||
|
@property (assign) NSColor *hudColorInputPendingAndApplied;
|
||||||
|
@property (assign) NSColor *hudColorInputAppliedOnly;
|
||||||
|
@property (assign) NSColor *hudColorInputPendingOnly;
|
||||||
@property (assign) NSInteger displayMainVideoSource;
|
@property (assign) NSInteger displayMainVideoSource;
|
||||||
@property (assign) NSInteger displayTouchVideoSource;
|
@property (assign) NSInteger displayTouchVideoSource;
|
||||||
@property (assign) BOOL useVerticalSync;
|
@property (assign) BOOL useVerticalSync;
|
||||||
|
@ -206,9 +210,9 @@ class OGLVideoOutput;
|
||||||
- (IBAction) toggleShowHUDRender3DFPS:(id)sender;
|
- (IBAction) toggleShowHUDRender3DFPS:(id)sender;
|
||||||
- (IBAction) toggleShowHUDFrameIndex:(id)sender;
|
- (IBAction) toggleShowHUDFrameIndex:(id)sender;
|
||||||
- (IBAction) toggleShowHUDLagFrameCount:(id)sender;
|
- (IBAction) toggleShowHUDLagFrameCount:(id)sender;
|
||||||
- (IBAction) toggleShowHUDInput:(id)sender;
|
|
||||||
- (IBAction) toggleShowHUDCPULoadAverage:(id)sender;
|
- (IBAction) toggleShowHUDCPULoadAverage:(id)sender;
|
||||||
- (IBAction) toggleShowHUDRealTimeClock:(id)sender;
|
- (IBAction) toggleShowHUDRealTimeClock:(id)sender;
|
||||||
|
- (IBAction) toggleShowHUDInput:(id)sender;
|
||||||
- (IBAction) toggleNDSDisplays:(id)sender;
|
- (IBAction) toggleNDSDisplays:(id)sender;
|
||||||
- (IBAction) toggleKeepMinDisplaySizeAtNormal:(id)sender;
|
- (IBAction) toggleKeepMinDisplaySizeAtNormal:(id)sender;
|
||||||
- (IBAction) toggleStatusBar:(id)sender;
|
- (IBAction) toggleStatusBar:(id)sender;
|
||||||
|
|
|
@ -571,8 +571,7 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
|
||||||
[[self view] setIsHUDLagFrameCountVisible:[[NSUserDefaults standardUserDefaults] boolForKey:@"HUD_ShowLagFrameCount"]];
|
[[self view] setIsHUDLagFrameCountVisible:[[NSUserDefaults standardUserDefaults] boolForKey:@"HUD_ShowLagFrameCount"]];
|
||||||
[[self view] setIsHUDCPULoadAverageVisible:[[NSUserDefaults standardUserDefaults] boolForKey:@"HUD_ShowCPULoadAverage"]];
|
[[self view] setIsHUDCPULoadAverageVisible:[[NSUserDefaults standardUserDefaults] boolForKey:@"HUD_ShowCPULoadAverage"]];
|
||||||
[[self view] setIsHUDRealTimeClockVisible:[[NSUserDefaults standardUserDefaults] boolForKey:@"HUD_ShowRTC"]];
|
[[self view] setIsHUDRealTimeClockVisible:[[NSUserDefaults standardUserDefaults] boolForKey:@"HUD_ShowRTC"]];
|
||||||
// TODO: Show HUD Input.
|
[[self view] setIsHUDInputVisible:[[NSUserDefaults standardUserDefaults] boolForKey:@"HUD_ShowInput"]];
|
||||||
//[[self view] setIsHUDInputVisible:[[NSUserDefaults standardUserDefaults] boolForKey:@"HUD_ShowInput"]];
|
|
||||||
|
|
||||||
[[self view] setHudColorVideoFPS:[CocoaDSUtil NSColorFromRGBA8888:[[NSUserDefaults standardUserDefaults] integerForKey:@"HUD_Color_VideoFPS"]]];
|
[[self view] setHudColorVideoFPS:[CocoaDSUtil NSColorFromRGBA8888:[[NSUserDefaults standardUserDefaults] integerForKey:@"HUD_Color_VideoFPS"]]];
|
||||||
[[self view] setHudColorRender3DFPS:[CocoaDSUtil NSColorFromRGBA8888:[[NSUserDefaults standardUserDefaults] integerForKey:@"HUD_Color_Render3DFPS"]]];
|
[[self view] setHudColorRender3DFPS:[CocoaDSUtil NSColorFromRGBA8888:[[NSUserDefaults standardUserDefaults] integerForKey:@"HUD_Color_Render3DFPS"]]];
|
||||||
|
@ -831,11 +830,6 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
|
||||||
[[self view] setIsHUDLagFrameCountVisible:![[self view] isHUDLagFrameCountVisible]];
|
[[self view] setIsHUDLagFrameCountVisible:![[self view] isHUDLagFrameCountVisible]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction) toggleShowHUDInput:(id)sender
|
|
||||||
{
|
|
||||||
//[[self view] setIsHUDInputVisible:![[self view] isHUDInputVisible]];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction) toggleShowHUDCPULoadAverage:(id)sender
|
- (IBAction) toggleShowHUDCPULoadAverage:(id)sender
|
||||||
{
|
{
|
||||||
[[self view] setIsHUDCPULoadAverageVisible:![[self view] isHUDCPULoadAverageVisible]];
|
[[self view] setIsHUDCPULoadAverageVisible:![[self view] isHUDCPULoadAverageVisible]];
|
||||||
|
@ -846,6 +840,11 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
|
||||||
[[self view] setIsHUDRealTimeClockVisible:![[self view] isHUDRealTimeClockVisible]];
|
[[self view] setIsHUDRealTimeClockVisible:![[self view] isHUDRealTimeClockVisible]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (IBAction) toggleShowHUDInput:(id)sender
|
||||||
|
{
|
||||||
|
[[self view] setIsHUDInputVisible:![[self view] isHUDInputVisible]];
|
||||||
|
}
|
||||||
|
|
||||||
- (IBAction) toggleKeepMinDisplaySizeAtNormal:(id)sender
|
- (IBAction) toggleKeepMinDisplaySizeAtNormal:(id)sender
|
||||||
{
|
{
|
||||||
if ([self isMinSizeNormal])
|
if ([self isMinSizeNormal])
|
||||||
|
@ -1080,8 +1079,7 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
|
||||||
[[NSUserDefaults standardUserDefaults] setBool:[[self view] isHUDLagFrameCountVisible] forKey:@"HUD_ShowLagFrameCount"];
|
[[NSUserDefaults standardUserDefaults] setBool:[[self view] isHUDLagFrameCountVisible] forKey:@"HUD_ShowLagFrameCount"];
|
||||||
[[NSUserDefaults standardUserDefaults] setBool:[[self view] isHUDCPULoadAverageVisible] forKey:@"HUD_ShowCPULoadAverage"];
|
[[NSUserDefaults standardUserDefaults] setBool:[[self view] isHUDCPULoadAverageVisible] forKey:@"HUD_ShowCPULoadAverage"];
|
||||||
[[NSUserDefaults standardUserDefaults] setBool:[[self view] isHUDRealTimeClockVisible] forKey:@"HUD_ShowRTC"];
|
[[NSUserDefaults standardUserDefaults] setBool:[[self view] isHUDRealTimeClockVisible] forKey:@"HUD_ShowRTC"];
|
||||||
// TODO: Show HUD Input.
|
[[NSUserDefaults standardUserDefaults] setBool:[[self view] isHUDInputVisible] forKey:@"HUD_ShowInput"];
|
||||||
//[[NSUserDefaults standardUserDefaults] setBool:[[self view] isHUDInputVisible] forKey:@"HUD_ShowInput"];
|
|
||||||
|
|
||||||
[[NSUserDefaults standardUserDefaults] setInteger:[CocoaDSUtil RGBA8888FromNSColor:[[self view] hudColorVideoFPS]] forKey:@"HUD_Color_VideoFPS"];
|
[[NSUserDefaults standardUserDefaults] setInteger:[CocoaDSUtil RGBA8888FromNSColor:[[self view] hudColorVideoFPS]] forKey:@"HUD_Color_VideoFPS"];
|
||||||
[[NSUserDefaults standardUserDefaults] setInteger:[CocoaDSUtil RGBA8888FromNSColor:[[self view] hudColorRender3DFPS]] forKey:@"HUD_Color_Render3DFPS"];
|
[[NSUserDefaults standardUserDefaults] setInteger:[CocoaDSUtil RGBA8888FromNSColor:[[self view] hudColorRender3DFPS]] forKey:@"HUD_Color_Render3DFPS"];
|
||||||
|
@ -1089,6 +1087,9 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
|
||||||
[[NSUserDefaults standardUserDefaults] setInteger:[CocoaDSUtil RGBA8888FromNSColor:[[self view] hudColorLagFrameCount]] forKey:@"HUD_Color_LagFrameCount"];
|
[[NSUserDefaults standardUserDefaults] setInteger:[CocoaDSUtil RGBA8888FromNSColor:[[self view] hudColorLagFrameCount]] forKey:@"HUD_Color_LagFrameCount"];
|
||||||
[[NSUserDefaults standardUserDefaults] setInteger:[CocoaDSUtil RGBA8888FromNSColor:[[self view] hudColorCPULoadAverage]] forKey:@"HUD_Color_CPULoadAverage"];
|
[[NSUserDefaults standardUserDefaults] setInteger:[CocoaDSUtil RGBA8888FromNSColor:[[self view] hudColorCPULoadAverage]] forKey:@"HUD_Color_CPULoadAverage"];
|
||||||
[[NSUserDefaults standardUserDefaults] setInteger:[CocoaDSUtil RGBA8888FromNSColor:[[self view] hudColorRTC]] forKey:@"HUD_Color_RTC"];
|
[[NSUserDefaults standardUserDefaults] setInteger:[CocoaDSUtil RGBA8888FromNSColor:[[self view] hudColorRTC]] forKey:@"HUD_Color_RTC"];
|
||||||
|
[[NSUserDefaults standardUserDefaults] setInteger:[CocoaDSUtil RGBA8888FromNSColor:[[self view] hudColorInputPendingAndApplied]] forKey:@"HUD_Color_Input_PendingAndApplied"];
|
||||||
|
[[NSUserDefaults standardUserDefaults] setInteger:[CocoaDSUtil RGBA8888FromNSColor:[[self view] hudColorInputAppliedOnly]] forKey:@"HUD_Color_Input_AppliedOnly"];
|
||||||
|
[[NSUserDefaults standardUserDefaults] setInteger:[CocoaDSUtil RGBA8888FromNSColor:[[self view] hudColorInputPendingOnly]] forKey:@"HUD_Color_Input_PendingOnly"];
|
||||||
|
|
||||||
[[NSUserDefaults standardUserDefaults] synchronize];
|
[[NSUserDefaults standardUserDefaults] synchronize];
|
||||||
}
|
}
|
||||||
|
@ -1296,6 +1297,13 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
|
||||||
[(NSMenuItem *)theItem setState:([[self view] isHUDRealTimeClockVisible]) ? NSOnState : NSOffState];
|
[(NSMenuItem *)theItem setState:([[self view] isHUDRealTimeClockVisible]) ? NSOnState : NSOffState];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (theAction == @selector(toggleShowHUDInput:))
|
||||||
|
{
|
||||||
|
if ([(id)theItem isMemberOfClass:[NSMenuItem class]])
|
||||||
|
{
|
||||||
|
[(NSMenuItem *)theItem setState:([[self view] isHUDInputVisible]) ? NSOnState : NSOffState];
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (theAction == @selector(toggleStatusBar:))
|
else if (theAction == @selector(toggleStatusBar:))
|
||||||
{
|
{
|
||||||
if ([(id)theItem isMemberOfClass:[NSMenuItem class]])
|
if ([(id)theItem isMemberOfClass:[NSMenuItem class]])
|
||||||
|
@ -1682,12 +1690,16 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
|
||||||
@dynamic isHUDLagFrameCountVisible;
|
@dynamic isHUDLagFrameCountVisible;
|
||||||
@dynamic isHUDCPULoadAverageVisible;
|
@dynamic isHUDCPULoadAverageVisible;
|
||||||
@dynamic isHUDRealTimeClockVisible;
|
@dynamic isHUDRealTimeClockVisible;
|
||||||
|
@dynamic isHUDInputVisible;
|
||||||
@dynamic hudColorVideoFPS;
|
@dynamic hudColorVideoFPS;
|
||||||
@dynamic hudColorRender3DFPS;
|
@dynamic hudColorRender3DFPS;
|
||||||
@dynamic hudColorFrameIndex;
|
@dynamic hudColorFrameIndex;
|
||||||
@dynamic hudColorLagFrameCount;
|
@dynamic hudColorLagFrameCount;
|
||||||
@dynamic hudColorCPULoadAverage;
|
@dynamic hudColorCPULoadAverage;
|
||||||
@dynamic hudColorRTC;
|
@dynamic hudColorRTC;
|
||||||
|
@dynamic hudColorInputPendingAndApplied;
|
||||||
|
@dynamic hudColorInputAppliedOnly;
|
||||||
|
@dynamic hudColorInputPendingOnly;
|
||||||
@dynamic displayMainVideoSource;
|
@dynamic displayMainVideoSource;
|
||||||
@dynamic displayTouchVideoSource;
|
@dynamic displayTouchVideoSource;
|
||||||
@dynamic useVerticalSync;
|
@dynamic useVerticalSync;
|
||||||
|
@ -1821,6 +1833,16 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
|
||||||
return [[self cdsVideoOutput] isHUDRealTimeClockVisible];
|
return [[self cdsVideoOutput] isHUDRealTimeClockVisible];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) setIsHUDInputVisible:(BOOL)theState
|
||||||
|
{
|
||||||
|
[[self cdsVideoOutput] setIsHUDInputVisible:theState];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL) isHUDInputVisible
|
||||||
|
{
|
||||||
|
return [[self cdsVideoOutput] isHUDInputVisible];
|
||||||
|
}
|
||||||
|
|
||||||
- (void) setHudColorVideoFPS:(NSColor *)theColor
|
- (void) setHudColorVideoFPS:(NSColor *)theColor
|
||||||
{
|
{
|
||||||
[[self cdsVideoOutput] setHudColorVideoFPS:[CocoaDSUtil RGBA8888FromNSColor:theColor]];
|
[[self cdsVideoOutput] setHudColorVideoFPS:[CocoaDSUtil RGBA8888FromNSColor:theColor]];
|
||||||
|
@ -1881,6 +1903,36 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
|
||||||
return [CocoaDSUtil NSColorFromRGBA8888:[[self cdsVideoOutput] hudColorRTC]];
|
return [CocoaDSUtil NSColorFromRGBA8888:[[self cdsVideoOutput] hudColorRTC]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) setHudColorInputPendingAndApplied:(NSColor *)theColor
|
||||||
|
{
|
||||||
|
[[self cdsVideoOutput] setHudColorInputPendingAndApplied:[CocoaDSUtil RGBA8888FromNSColor:theColor]];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSColor *) hudColorInputPendingAndApplied
|
||||||
|
{
|
||||||
|
return [CocoaDSUtil NSColorFromRGBA8888:[[self cdsVideoOutput] hudColorInputPendingAndApplied]];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) setHudColorInputAppliedOnly:(NSColor *)theColor
|
||||||
|
{
|
||||||
|
[[self cdsVideoOutput] setHudColorInputAppliedOnly:[CocoaDSUtil RGBA8888FromNSColor:theColor]];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSColor *) hudColorInputAppliedOnly
|
||||||
|
{
|
||||||
|
return [CocoaDSUtil NSColorFromRGBA8888:[[self cdsVideoOutput] hudColorInputAppliedOnly]];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) setHudColorInputPendingOnly:(NSColor *)theColor
|
||||||
|
{
|
||||||
|
[[self cdsVideoOutput] setHudColorInputPendingOnly:[CocoaDSUtil RGBA8888FromNSColor:theColor]];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSColor *) hudColorInputPendingOnly
|
||||||
|
{
|
||||||
|
return [CocoaDSUtil NSColorFromRGBA8888:[[self cdsVideoOutput] hudColorInputPendingOnly]];
|
||||||
|
}
|
||||||
|
|
||||||
- (void) setDisplayMainVideoSource:(NSInteger)displaySourceID
|
- (void) setDisplayMainVideoSource:(NSInteger)displaySourceID
|
||||||
{
|
{
|
||||||
[[self cdsVideoOutput] setDisplayMainVideoSource:displaySourceID];
|
[[self cdsVideoOutput] setDisplayMainVideoSource:displaySourceID];
|
||||||
|
|
|
@ -1041,6 +1041,17 @@
|
||||||
|
|
||||||
CocoaDSCore *cdsCore = (CocoaDSCore *)[cdsCoreController content];
|
CocoaDSCore *cdsCore = (CocoaDSCore *)[cdsCoreController content];
|
||||||
[[cdsCore cdsController] setControllerState:theState controlID:controlID];
|
[[cdsCore cdsController] setControllerState:theState controlID:controlID];
|
||||||
|
|
||||||
|
for (DisplayWindowController *windowController in windowList)
|
||||||
|
{
|
||||||
|
[[[windowController view] cdsVideoOutput] setNDSFrameInfo:[cdsCore execControl]->GetNDSFrameInfo()];
|
||||||
|
[[[windowController view] cdsVideoOutput] hudUpdate];
|
||||||
|
|
||||||
|
if ([[windowController view] isHUDInputVisible])
|
||||||
|
{
|
||||||
|
[[windowController view] clientDisplay3DView]->UpdateView();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) cmdUpdateDSControllerWithTurbo:(NSValue *)cmdAttrValue
|
- (void) cmdUpdateDSControllerWithTurbo:(NSValue *)cmdAttrValue
|
||||||
|
@ -1055,6 +1066,17 @@
|
||||||
|
|
||||||
CocoaDSCore *cdsCore = (CocoaDSCore *)[cdsCoreController content];
|
CocoaDSCore *cdsCore = (CocoaDSCore *)[cdsCoreController content];
|
||||||
[[cdsCore cdsController] setControllerState:theState controlID:controlID turbo:isTurboEnabled turboPattern:turboPattern turboPatternLength:turboPatternLength];
|
[[cdsCore cdsController] setControllerState:theState controlID:controlID turbo:isTurboEnabled turboPattern:turboPattern turboPatternLength:turboPatternLength];
|
||||||
|
|
||||||
|
for (DisplayWindowController *windowController in windowList)
|
||||||
|
{
|
||||||
|
[[[windowController view] cdsVideoOutput] setNDSFrameInfo:[cdsCore execControl]->GetNDSFrameInfo()];
|
||||||
|
[[[windowController view] cdsVideoOutput] hudUpdate];
|
||||||
|
|
||||||
|
if ([[windowController view] isHUDInputVisible])
|
||||||
|
{
|
||||||
|
[[windowController view] clientDisplay3DView]->UpdateView();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) cmdUpdateDSTouch:(NSValue *)cmdAttrValue
|
- (void) cmdUpdateDSTouch:(NSValue *)cmdAttrValue
|
||||||
|
@ -1068,6 +1090,17 @@
|
||||||
{
|
{
|
||||||
CocoaDSCore *cdsCore = (CocoaDSCore *)[cdsCoreController content];
|
CocoaDSCore *cdsCore = (CocoaDSCore *)[cdsCoreController content];
|
||||||
[[cdsCore cdsController] setTouchState:theState location:touchLoc];
|
[[cdsCore cdsController] setTouchState:theState location:touchLoc];
|
||||||
|
|
||||||
|
for (DisplayWindowController *windowController in windowList)
|
||||||
|
{
|
||||||
|
[[[windowController view] cdsVideoOutput] setNDSFrameInfo:[cdsCore execControl]->GetNDSFrameInfo()];
|
||||||
|
[[[windowController view] cdsVideoOutput] hudUpdate];
|
||||||
|
|
||||||
|
if ([[windowController view] isHUDInputVisible])
|
||||||
|
{
|
||||||
|
[[windowController view] clientDisplay3DView]->UpdateView();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1081,8 +1114,7 @@
|
||||||
CocoaDSController *cdsController = [cdsCore cdsController];
|
CocoaDSController *cdsController = [cdsCore cdsController];
|
||||||
|
|
||||||
const NSInteger micMode = cmdAttr.intValue[1];
|
const NSInteger micMode = cmdAttr.intValue[1];
|
||||||
[cdsController setSoftwareMicState:theState];
|
[cdsController setSoftwareMicState:theState mode:micMode];
|
||||||
[cdsController setSoftwareMicMode:micMode];
|
|
||||||
|
|
||||||
const float sineWaveFrequency = cmdAttr.floatValue[0];
|
const float sineWaveFrequency = cmdAttr.floatValue[0];
|
||||||
[cdsController setSineWaveGeneratorFrequency:sineWaveFrequency];
|
[cdsController setSineWaveGeneratorFrequency:sineWaveFrequency];
|
||||||
|
|
|
@ -1141,7 +1141,7 @@ static std::unordered_map<unsigned short, std::string> keyboardNameTable; // Key
|
||||||
cmdDSControlTouch.useInputForIntCoord = true;
|
cmdDSControlTouch.useInputForIntCoord = true;
|
||||||
|
|
||||||
CommandAttributes cmdDSControlMic = NewCommandAttributesForDSControl("Microphone", NDSInputID_Microphone);
|
CommandAttributes cmdDSControlMic = NewCommandAttributesForDSControl("Microphone", NDSInputID_Microphone);
|
||||||
cmdDSControlMic.intValue[1] = MICMODE_INTERNAL_NOISE;
|
cmdDSControlMic.intValue[1] = MicrophoneMode_InternalNoise;
|
||||||
cmdDSControlMic.floatValue[0] = 250.0f;
|
cmdDSControlMic.floatValue[0] = 250.0f;
|
||||||
|
|
||||||
CommandAttributes cmdGuitarGripGreen = NewCommandAttributesForDSControl("Guitar Grip: Green", NDSInputID_GuitarGrip_Green);
|
CommandAttributes cmdGuitarGripGreen = NewCommandAttributesForDSControl("Guitar Grip: Green", NDSInputID_GuitarGrip_Green);
|
||||||
|
@ -1685,18 +1685,18 @@ static std::unordered_map<unsigned short, std::string> keyboardNameTable; // Key
|
||||||
}
|
}
|
||||||
else if (strncmp(commandTag, "Microphone", INPUT_HANDLER_STRING_LENGTH) == 0)
|
else if (strncmp(commandTag, "Microphone", INPUT_HANDLER_STRING_LENGTH) == 0)
|
||||||
{
|
{
|
||||||
const NSInteger micMode = [(NSNumber *)[deviceInfo valueForKey:@"intValue1"] integerValue];
|
const MicrophoneMode micMode = (MicrophoneMode)[(NSNumber *)[deviceInfo valueForKey:@"intValue1"] integerValue];
|
||||||
switch (micMode)
|
switch (micMode)
|
||||||
{
|
{
|
||||||
case MICMODE_NONE:
|
case MicrophoneMode_None:
|
||||||
inputSummary = NSSTRING_INPUTPREF_MIC_NONE;
|
inputSummary = NSSTRING_INPUTPREF_MIC_NONE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MICMODE_INTERNAL_NOISE:
|
case MicrophoneMode_InternalNoise:
|
||||||
inputSummary = NSSTRING_INPUTPREF_MIC_INTERNAL_NOISE;
|
inputSummary = NSSTRING_INPUTPREF_MIC_INTERNAL_NOISE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MICMODE_AUDIO_FILE:
|
case MicrophoneMode_AudioFile:
|
||||||
inputSummary = (NSString *)[deviceInfo valueForKey:@"object1"];
|
inputSummary = (NSString *)[deviceInfo valueForKey:@"object1"];
|
||||||
if (inputSummary == nil)
|
if (inputSummary == nil)
|
||||||
{
|
{
|
||||||
|
@ -1704,15 +1704,15 @@ static std::unordered_map<unsigned short, std::string> keyboardNameTable; // Key
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MICMODE_WHITE_NOISE:
|
case MicrophoneMode_WhiteNoise:
|
||||||
inputSummary = NSSTRING_INPUTPREF_MIC_WHITE_NOISE;
|
inputSummary = NSSTRING_INPUTPREF_MIC_WHITE_NOISE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MICMODE_SINE_WAVE:
|
case MicrophoneMode_SineWave:
|
||||||
inputSummary = [NSString stringWithFormat:NSSTRING_INPUTPREF_MIC_SINE_WAVE, [(NSNumber *)[deviceInfo valueForKey:@"floatValue0"] floatValue]];
|
inputSummary = [NSString stringWithFormat:NSSTRING_INPUTPREF_MIC_SINE_WAVE, [(NSNumber *)[deviceInfo valueForKey:@"floatValue0"] floatValue]];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MICMODE_PHYSICAL:
|
case MicrophoneMode_Physical:
|
||||||
inputSummary = @"Physical:";
|
inputSummary = @"Physical:";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -117,16 +117,18 @@
|
||||||
[[[hudPipelineDesc colorAttachments] objectAtIndexedSubscript:0] setSourceAlphaBlendFactor:MTLBlendFactorSourceAlpha];
|
[[[hudPipelineDesc colorAttachments] objectAtIndexedSubscript:0] setSourceAlphaBlendFactor:MTLBlendFactorSourceAlpha];
|
||||||
[[[hudPipelineDesc colorAttachments] objectAtIndexedSubscript:0] setDestinationRGBBlendFactor:MTLBlendFactorOneMinusSourceAlpha];
|
[[[hudPipelineDesc colorAttachments] objectAtIndexedSubscript:0] setDestinationRGBBlendFactor:MTLBlendFactorOneMinusSourceAlpha];
|
||||||
[[[hudPipelineDesc colorAttachments] objectAtIndexedSubscript:0] setDestinationAlphaBlendFactor:MTLBlendFactorOneMinusSourceAlpha];
|
[[[hudPipelineDesc colorAttachments] objectAtIndexedSubscript:0] setDestinationAlphaBlendFactor:MTLBlendFactorOneMinusSourceAlpha];
|
||||||
[hudPipelineDesc setVertexFunction:[defaultLibrary newFunctionWithName:@"hud_vertex"]];
|
|
||||||
[hudPipelineDesc setFragmentFunction:[defaultLibrary newFunctionWithName:@"hud_fragment"]];
|
|
||||||
|
|
||||||
|
id<MTLFunction> hudFragmentFunction = [defaultLibrary newFunctionWithName:@"hud_fragment"];
|
||||||
|
[hudPipelineDesc setVertexFunction:[defaultLibrary newFunctionWithName:@"hud_vertex"]];
|
||||||
|
[hudPipelineDesc setFragmentFunction:hudFragmentFunction];
|
||||||
hudPipeline = [[device newRenderPipelineStateWithDescriptor:hudPipelineDesc error:nil] retain];
|
hudPipeline = [[device newRenderPipelineStateWithDescriptor:hudPipelineDesc error:nil] retain];
|
||||||
|
|
||||||
[hudPipelineDesc release];
|
[hudPipelineDesc release];
|
||||||
|
|
||||||
hudIndexBuffer = [[device newBufferWithLength:(sizeof(uint16_t) * HUD_MAX_CHARACTERS * 6) options:MTLResourceStorageModeManaged] retain];
|
hudIndexBuffer = [[device newBufferWithLength:(sizeof(uint16_t) * HUD_TOTAL_ELEMENTS * 6) options:MTLResourceStorageModeManaged] retain];
|
||||||
|
|
||||||
uint16_t *idxBufferPtr = (uint16_t *)[hudIndexBuffer contents];
|
uint16_t *idxBufferPtr = (uint16_t *)[hudIndexBuffer contents];
|
||||||
for (size_t i = 0, j = 0, k = 0; i < HUD_MAX_CHARACTERS; i++, j+=6, k+=4)
|
for (size_t i = 0, j = 0, k = 0; i < HUD_TOTAL_ELEMENTS; i++, j+=6, k+=4)
|
||||||
{
|
{
|
||||||
idxBufferPtr[j+0] = k+0;
|
idxBufferPtr[j+0] = k+0;
|
||||||
idxBufferPtr[j+1] = k+1;
|
idxBufferPtr[j+1] = k+1;
|
||||||
|
@ -136,7 +138,7 @@
|
||||||
idxBufferPtr[j+5] = k+0;
|
idxBufferPtr[j+5] = k+0;
|
||||||
}
|
}
|
||||||
|
|
||||||
[hudIndexBuffer didModifyRange:NSMakeRange(0, sizeof(uint16_t) * HUD_MAX_CHARACTERS * 6)];
|
[hudIndexBuffer didModifyRange:NSMakeRange(0, sizeof(uint16_t) * HUD_TOTAL_ELEMENTS * 6)];
|
||||||
|
|
||||||
_bufDisplayFetchNative[NDSDisplayID_Main][0] = nil;
|
_bufDisplayFetchNative[NDSDisplayID_Main][0] = nil;
|
||||||
_bufDisplayFetchNative[NDSDisplayID_Main][1] = nil;
|
_bufDisplayFetchNative[NDSDisplayID_Main][1] = nil;
|
||||||
|
@ -1451,18 +1453,27 @@
|
||||||
{
|
{
|
||||||
NSAutoreleasePool *renderAutoreleasePool = [[NSAutoreleasePool alloc] init];
|
NSAutoreleasePool *renderAutoreleasePool = [[NSAutoreleasePool alloc] init];
|
||||||
|
|
||||||
|
dispatch_semaphore_wait(availableResources, DISPATCH_TIME_FOREVER);
|
||||||
|
|
||||||
id<CAMetalDrawable> drawable = [self nextDrawable];
|
id<CAMetalDrawable> drawable = [self nextDrawable];
|
||||||
|
if (drawable == nil)
|
||||||
|
{
|
||||||
|
puts("MacMetalDisplayView: No drawable object was available!\n");
|
||||||
|
dispatch_semaphore_signal(availableResources);
|
||||||
|
[renderAutoreleasePool release];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
id<MTLTexture> texture = [drawable texture];
|
id<MTLTexture> texture = [drawable texture];
|
||||||
if (texture == nil)
|
if (texture == nil)
|
||||||
{
|
{
|
||||||
|
dispatch_semaphore_signal(availableResources);
|
||||||
[renderAutoreleasePool release];
|
[renderAutoreleasePool release];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const NDSDisplayInfo &displayInfo = _cdv->GetEmuDisplayInfo();
|
const NDSDisplayInfo &displayInfo = _cdv->GetEmuDisplayInfo();
|
||||||
|
|
||||||
dispatch_semaphore_wait(availableResources, DISPATCH_TIME_FOREVER);
|
|
||||||
|
|
||||||
[[self colorAttachment0Desc] setTexture:texture];
|
[[self colorAttachment0Desc] setTexture:texture];
|
||||||
|
|
||||||
id<MTLCommandBuffer> cb = [[sharedData commandQueue] commandBufferWithUnretainedReferences];
|
id<MTLCommandBuffer> cb = [[sharedData commandQueue] commandBufferWithUnretainedReferences];
|
||||||
|
@ -1586,7 +1597,43 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw the HUD.
|
// Draw the HUD.
|
||||||
const size_t hudLength = _cdv->GetHUDString().length();
|
size_t hudLength = _cdv->GetHUDString().length();
|
||||||
|
size_t hudTouchLineLength = 0;
|
||||||
|
|
||||||
|
if (_cdv->GetHUDShowInput())
|
||||||
|
{
|
||||||
|
hudLength += HUD_INPUT_ELEMENT_LENGTH;
|
||||||
|
|
||||||
|
switch (_cdv->GetMode())
|
||||||
|
{
|
||||||
|
case ClientDisplayMode_Main:
|
||||||
|
case ClientDisplayMode_Touch:
|
||||||
|
hudTouchLineLength = HUD_INPUT_TOUCH_LINE_ELEMENTS / 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ClientDisplayMode_Dual:
|
||||||
|
{
|
||||||
|
switch (_cdv->GetLayout())
|
||||||
|
{
|
||||||
|
case ClientDisplayLayout_Vertical:
|
||||||
|
case ClientDisplayLayout_Horizontal:
|
||||||
|
hudTouchLineLength = HUD_INPUT_TOUCH_LINE_ELEMENTS / 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ClientDisplayLayout_Hybrid_2_1:
|
||||||
|
case ClientDisplayLayout_Hybrid_16_9:
|
||||||
|
case ClientDisplayLayout_Hybrid_16_10:
|
||||||
|
hudTouchLineLength = HUD_INPUT_TOUCH_LINE_ELEMENTS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hudLength += hudTouchLineLength;
|
||||||
|
}
|
||||||
|
|
||||||
if ( _cdv->GetHUDVisibility() && (hudLength > 1) && ([self texHUDCharMap] != nil) )
|
if ( _cdv->GetHUDVisibility() && (hudLength > 1) && ([self texHUDCharMap] != nil) )
|
||||||
{
|
{
|
||||||
if (_cdv->HUDNeedsUpdate())
|
if (_cdv->HUDNeedsUpdate())
|
||||||
|
@ -1603,6 +1650,8 @@
|
||||||
_cdv->ClearHUDNeedsUpdate();
|
_cdv->ClearHUDNeedsUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t isScreenOverlay = 0;
|
||||||
|
|
||||||
[ce setRenderPipelineState:[sharedData hudPipeline]];
|
[ce setRenderPipelineState:[sharedData hudPipeline]];
|
||||||
[ce setVertexBuffer:_hudVtxPositionBuffer offset:0 atIndex:0];
|
[ce setVertexBuffer:_hudVtxPositionBuffer offset:0 atIndex:0];
|
||||||
[ce setVertexBuffer:_hudVtxColorBuffer offset:0 atIndex:1];
|
[ce setVertexBuffer:_hudVtxColorBuffer offset:0 atIndex:1];
|
||||||
|
@ -1610,7 +1659,30 @@
|
||||||
[ce setVertexBuffer:_cdvPropertiesBuffer offset:0 atIndex:3];
|
[ce setVertexBuffer:_cdvPropertiesBuffer offset:0 atIndex:3];
|
||||||
[ce setFragmentTexture:[self texHUDCharMap] atIndex:0];
|
[ce setFragmentTexture:[self texHUDCharMap] atIndex:0];
|
||||||
|
|
||||||
// First, draw the backing text box.
|
// First, draw the inputs.
|
||||||
|
if (_cdv->GetHUDShowInput())
|
||||||
|
{
|
||||||
|
isScreenOverlay = 1;
|
||||||
|
[ce setVertexBytes:&isScreenOverlay length:sizeof(uint8_t) atIndex:4];
|
||||||
|
[ce setFragmentSamplerState:[sharedData samplerHUDBox] atIndex:0];
|
||||||
|
[ce drawIndexedPrimitives:MTLPrimitiveTypeTriangle
|
||||||
|
indexCount:hudTouchLineLength * 6
|
||||||
|
indexType:MTLIndexTypeUInt16
|
||||||
|
indexBuffer:[sharedData hudIndexBuffer]
|
||||||
|
indexBufferOffset:(_cdv->GetHUDString().length() + HUD_INPUT_ELEMENT_LENGTH) * 6 * sizeof(uint16_t)];
|
||||||
|
|
||||||
|
isScreenOverlay = 0;
|
||||||
|
[ce setVertexBytes:&isScreenOverlay length:sizeof(uint8_t) atIndex:4];
|
||||||
|
[ce setFragmentSamplerState:[sharedData samplerHUDText] atIndex:0];
|
||||||
|
[ce drawIndexedPrimitives:MTLPrimitiveTypeTriangle
|
||||||
|
indexCount:HUD_INPUT_ELEMENT_LENGTH * 6
|
||||||
|
indexType:MTLIndexTypeUInt16
|
||||||
|
indexBuffer:[sharedData hudIndexBuffer]
|
||||||
|
indexBufferOffset:_cdv->GetHUDString().length() * 6 * sizeof(uint16_t)];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Next, draw the backing text box.
|
||||||
|
[ce setVertexBytes:&isScreenOverlay length:sizeof(uint8_t) atIndex:4];
|
||||||
[ce setFragmentSamplerState:[sharedData samplerHUDBox] atIndex:0];
|
[ce setFragmentSamplerState:[sharedData samplerHUDBox] atIndex:0];
|
||||||
[ce drawIndexedPrimitives:MTLPrimitiveTypeTriangle
|
[ce drawIndexedPrimitives:MTLPrimitiveTypeTriangle
|
||||||
indexCount:6
|
indexCount:6
|
||||||
|
@ -1618,10 +1690,10 @@
|
||||||
indexBuffer:[sharedData hudIndexBuffer]
|
indexBuffer:[sharedData hudIndexBuffer]
|
||||||
indexBufferOffset:0];
|
indexBufferOffset:0];
|
||||||
|
|
||||||
// Next, draw each character inside the box.
|
// Finally, draw each character inside the box.
|
||||||
[ce setFragmentSamplerState:[sharedData samplerHUDText] atIndex:0];
|
[ce setFragmentSamplerState:[sharedData samplerHUDText] atIndex:0];
|
||||||
[ce drawIndexedPrimitives:MTLPrimitiveTypeTriangle
|
[ce drawIndexedPrimitives:MTLPrimitiveTypeTriangle
|
||||||
indexCount:(hudLength - 1) * 6
|
indexCount:(_cdv->GetHUDString().length() - 1) * 6
|
||||||
indexType:MTLIndexTypeUInt16
|
indexType:MTLIndexTypeUInt16
|
||||||
indexBuffer:[sharedData hudIndexBuffer]
|
indexBuffer:[sharedData hudIndexBuffer]
|
||||||
indexBufferOffset:6 * sizeof(uint16_t)];
|
indexBufferOffset:6 * sizeof(uint16_t)];
|
||||||
|
|
|
@ -25,7 +25,6 @@ struct HUDVtx
|
||||||
float4 position [[position]];
|
float4 position [[position]];
|
||||||
float4 color;
|
float4 color;
|
||||||
float2 texCoord;
|
float2 texCoord;
|
||||||
bool isBox;
|
|
||||||
bool lowerHUDMipMapLevel;
|
bool lowerHUDMipMapLevel;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -147,16 +146,24 @@ vertex HUDVtx hud_vertex(const device float2 *inPosition [[buffer(0)]],
|
||||||
const device uint32_t *inColor [[buffer(1)]],
|
const device uint32_t *inColor [[buffer(1)]],
|
||||||
const device float2 *inTexCoord [[buffer(2)]],
|
const device float2 *inTexCoord [[buffer(2)]],
|
||||||
const constant DisplayViewShaderProperties &viewProps [[buffer(3)]],
|
const constant DisplayViewShaderProperties &viewProps [[buffer(3)]],
|
||||||
|
const constant uint8_t &isScreenOverlay [[buffer(4)]],
|
||||||
const uint vid [[vertex_id]])
|
const uint vid [[vertex_id]])
|
||||||
{
|
{
|
||||||
|
const float angleRadians = viewProps.rotation * (M_PI_F/180.0f);
|
||||||
|
|
||||||
const float2x2 projection = float2x2( float2(2.0f/viewProps.width, 0.0f),
|
const float2x2 projection = float2x2( float2(2.0f/viewProps.width, 0.0f),
|
||||||
float2( 0.0f, 2.0f/viewProps.height));
|
float2( 0.0f, 2.0f/viewProps.height));
|
||||||
|
|
||||||
|
const float2x2 rotation = float2x2( float2( cos(angleRadians), sin(angleRadians)),
|
||||||
|
float2(-sin(angleRadians), cos(angleRadians)));
|
||||||
|
|
||||||
|
const float2x2 scale = float2x2( float2(viewProps.viewScale, 0.0f),
|
||||||
|
float2( 0.0f, viewProps.viewScale));
|
||||||
|
|
||||||
HUDVtx outVtx;
|
HUDVtx outVtx;
|
||||||
outVtx.position = float4(projection * inPosition[vid], 0.0f, 1.0f);
|
outVtx.position = (isScreenOverlay != 0) ? float4(projection * rotation * scale * inPosition[vid], 0.0f, 1.0f) : float4(projection * inPosition[vid], 0.0f, 1.0f);
|
||||||
outVtx.color = float4( (float)((inColor[vid] >> 0) & 0xFF) / 255.0f, (float)((inColor[vid] >> 8) & 0xFF) / 255.0f, (float)((inColor[vid] >> 16) & 0xFF) / 255.0f, (float)((inColor[vid] >> 24) & 0xFF) / 255.0f );
|
outVtx.color = float4( (float)((inColor[vid] >> 0) & 0xFF) / 255.0f, (float)((inColor[vid] >> 8) & 0xFF) / 255.0f, (float)((inColor[vid] >> 16) & 0xFF) / 255.0f, (float)((inColor[vid] >> 24) & 0xFF) / 255.0f );
|
||||||
outVtx.texCoord = inTexCoord[vid];
|
outVtx.texCoord = inTexCoord[vid];
|
||||||
outVtx.isBox = (vid < 4);
|
|
||||||
outVtx.lowerHUDMipMapLevel = (viewProps.lowerHUDMipMapLevel == 1);
|
outVtx.lowerHUDMipMapLevel = (viewProps.lowerHUDMipMapLevel == 1);
|
||||||
|
|
||||||
return outVtx;
|
return outVtx;
|
||||||
|
|
|
@ -194,6 +194,7 @@
|
||||||
CocoaDSController *newController = [[[CocoaDSController alloc] init] autorelease];
|
CocoaDSController *newController = [[[CocoaDSController alloc] init] autorelease];
|
||||||
[newCore setCdsController:newController];
|
[newCore setCdsController:newController];
|
||||||
[newController setDelegate:emuControl];
|
[newController setDelegate:emuControl];
|
||||||
|
[newController setExecControl:[newCore execControl]];
|
||||||
[newController setHardwareMicEnabled:YES];
|
[newController setHardwareMicEnabled:YES];
|
||||||
|
|
||||||
// Init the DS speakers.
|
// Init the DS speakers.
|
||||||
|
@ -607,8 +608,7 @@
|
||||||
const BOOL hudShowLagFrameCount = ([windowProperties objectForKey:@"hudShowLagFrameCount"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudShowLagFrameCount"] boolValue] : [[NSUserDefaults standardUserDefaults] boolForKey:@"HUD_ShowLagFrameCount"];
|
const BOOL hudShowLagFrameCount = ([windowProperties objectForKey:@"hudShowLagFrameCount"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudShowLagFrameCount"] boolValue] : [[NSUserDefaults standardUserDefaults] boolForKey:@"HUD_ShowLagFrameCount"];
|
||||||
const BOOL hudShowCPULoadAverage = ([windowProperties objectForKey:@"hudShowCPULoadAverage"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudShowCPULoadAverage"] boolValue] : [[NSUserDefaults standardUserDefaults] boolForKey:@"HUD_ShowCPULoadAverage"];
|
const BOOL hudShowCPULoadAverage = ([windowProperties objectForKey:@"hudShowCPULoadAverage"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudShowCPULoadAverage"] boolValue] : [[NSUserDefaults standardUserDefaults] boolForKey:@"HUD_ShowCPULoadAverage"];
|
||||||
const BOOL hudShowRTC = ([windowProperties objectForKey:@"hudShowRTC"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudShowRTC"] boolValue] : [[NSUserDefaults standardUserDefaults] boolForKey:@"HUD_ShowRTC"];
|
const BOOL hudShowRTC = ([windowProperties objectForKey:@"hudShowRTC"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudShowRTC"] boolValue] : [[NSUserDefaults standardUserDefaults] boolForKey:@"HUD_ShowRTC"];
|
||||||
// TODO: Show HUD Input.
|
const BOOL hudShowInput = ([windowProperties objectForKey:@"hudShowInput"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudShowInput"] boolValue] : [[NSUserDefaults standardUserDefaults] boolForKey:@"HUD_ShowInput"];
|
||||||
//const BOOL hudShowInput = [(NSNumber *)[windowProperties valueForKey:@"hudShowInput"] boolValue];
|
|
||||||
|
|
||||||
const NSUInteger hudColorVideoFPS = ([windowProperties objectForKey:@"hudColorVideoFPS"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudColorVideoFPS"] unsignedIntegerValue] : [[NSUserDefaults standardUserDefaults] integerForKey:@"HUD_Color_VideoFPS"];
|
const NSUInteger hudColorVideoFPS = ([windowProperties objectForKey:@"hudColorVideoFPS"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudColorVideoFPS"] unsignedIntegerValue] : [[NSUserDefaults standardUserDefaults] integerForKey:@"HUD_Color_VideoFPS"];
|
||||||
const NSUInteger hudColorRender3DFPS = ([windowProperties objectForKey:@"hudColorRender3DFPS"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudColorRender3DFPS"] unsignedIntegerValue] : [[NSUserDefaults standardUserDefaults] integerForKey:@"HUD_Color_Render3DFPS"];
|
const NSUInteger hudColorRender3DFPS = ([windowProperties objectForKey:@"hudColorRender3DFPS"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudColorRender3DFPS"] unsignedIntegerValue] : [[NSUserDefaults standardUserDefaults] integerForKey:@"HUD_Color_Render3DFPS"];
|
||||||
|
@ -616,6 +616,9 @@
|
||||||
const NSUInteger hudColorLagFrameCount = ([windowProperties objectForKey:@"hudColorLagFrameCount"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudColorLagFrameCount"] unsignedIntegerValue] : [[NSUserDefaults standardUserDefaults] integerForKey:@"HUD_Color_LagFrameCount"];
|
const NSUInteger hudColorLagFrameCount = ([windowProperties objectForKey:@"hudColorLagFrameCount"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudColorLagFrameCount"] unsignedIntegerValue] : [[NSUserDefaults standardUserDefaults] integerForKey:@"HUD_Color_LagFrameCount"];
|
||||||
const NSUInteger hudColorCPULoadAverage = ([windowProperties objectForKey:@"hudColorCPULoadAverage"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudColorCPULoadAverage"] unsignedIntegerValue] : [[NSUserDefaults standardUserDefaults] integerForKey:@"HUD_Color_CPULoadAverage"];
|
const NSUInteger hudColorCPULoadAverage = ([windowProperties objectForKey:@"hudColorCPULoadAverage"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudColorCPULoadAverage"] unsignedIntegerValue] : [[NSUserDefaults standardUserDefaults] integerForKey:@"HUD_Color_CPULoadAverage"];
|
||||||
const NSUInteger hudColorRTC = ([windowProperties objectForKey:@"hudColorRTC"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudColorRTC"] unsignedIntegerValue] : [[NSUserDefaults standardUserDefaults] integerForKey:@"HUD_Color_RTC"];
|
const NSUInteger hudColorRTC = ([windowProperties objectForKey:@"hudColorRTC"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudColorRTC"] unsignedIntegerValue] : [[NSUserDefaults standardUserDefaults] integerForKey:@"HUD_Color_RTC"];
|
||||||
|
const NSUInteger hudColorInputPendingAndApplied = ([windowProperties objectForKey:@"hudColorInputPendingAndApplied"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudColorInputPendingAndApplied"] unsignedIntegerValue] : [[NSUserDefaults standardUserDefaults] integerForKey:@"HUD_Color_Input_PendingAndApplied"];
|
||||||
|
const NSUInteger hudColorInputAppliedOnly = ([windowProperties objectForKey:@"hudColorInputAppliedOnly"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudColorInputAppliedOnly"] unsignedIntegerValue] : [[NSUserDefaults standardUserDefaults] integerForKey:@"HUD_Color_Input_AppliedOnly"];
|
||||||
|
const NSUInteger hudColorInputPendingOnly = ([windowProperties objectForKey:@"hudColorInputPendingOnly"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudColorInputPendingOnly"] unsignedIntegerValue] : [[NSUserDefaults standardUserDefaults] integerForKey:@"HUD_Color_Input_PendingOnly"];
|
||||||
|
|
||||||
const NSInteger screenshotFileFormat = ([windowProperties objectForKey:@"screenshotFileFormat"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"screenshotFileFormat"] integerValue] : NSTIFFFileType;
|
const NSInteger screenshotFileFormat = ([windowProperties objectForKey:@"screenshotFileFormat"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"screenshotFileFormat"] integerValue] : NSTIFFFileType;
|
||||||
const BOOL useVerticalSync = ([windowProperties objectForKey:@"useVerticalSync"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"useVerticalSync"] boolValue] : YES;
|
const BOOL useVerticalSync = ([windowProperties objectForKey:@"useVerticalSync"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"useVerticalSync"] boolValue] : YES;
|
||||||
|
@ -661,6 +664,7 @@
|
||||||
[[windowController view] setIsHUDLagFrameCountVisible:hudShowLagFrameCount];
|
[[windowController view] setIsHUDLagFrameCountVisible:hudShowLagFrameCount];
|
||||||
[[windowController view] setIsHUDCPULoadAverageVisible:hudShowCPULoadAverage];
|
[[windowController view] setIsHUDCPULoadAverageVisible:hudShowCPULoadAverage];
|
||||||
[[windowController view] setIsHUDRealTimeClockVisible:hudShowRTC];
|
[[windowController view] setIsHUDRealTimeClockVisible:hudShowRTC];
|
||||||
|
[[windowController view] setIsHUDInputVisible:hudShowInput];
|
||||||
|
|
||||||
[[windowController view] setHudColorVideoFPS:[CocoaDSUtil NSColorFromRGBA8888:(uint32_t)hudColorVideoFPS]];
|
[[windowController view] setHudColorVideoFPS:[CocoaDSUtil NSColorFromRGBA8888:(uint32_t)hudColorVideoFPS]];
|
||||||
[[windowController view] setHudColorRender3DFPS:[CocoaDSUtil NSColorFromRGBA8888:(uint32_t)hudColorRender3DFPS]];
|
[[windowController view] setHudColorRender3DFPS:[CocoaDSUtil NSColorFromRGBA8888:(uint32_t)hudColorRender3DFPS]];
|
||||||
|
@ -668,6 +672,9 @@
|
||||||
[[windowController view] setHudColorLagFrameCount:[CocoaDSUtil NSColorFromRGBA8888:(uint32_t)hudColorLagFrameCount]];
|
[[windowController view] setHudColorLagFrameCount:[CocoaDSUtil NSColorFromRGBA8888:(uint32_t)hudColorLagFrameCount]];
|
||||||
[[windowController view] setHudColorCPULoadAverage:[CocoaDSUtil NSColorFromRGBA8888:(uint32_t)hudColorCPULoadAverage]];
|
[[windowController view] setHudColorCPULoadAverage:[CocoaDSUtil NSColorFromRGBA8888:(uint32_t)hudColorCPULoadAverage]];
|
||||||
[[windowController view] setHudColorRTC:[CocoaDSUtil NSColorFromRGBA8888:(uint32_t)hudColorRTC]];
|
[[windowController view] setHudColorRTC:[CocoaDSUtil NSColorFromRGBA8888:(uint32_t)hudColorRTC]];
|
||||||
|
[[windowController view] setHudColorInputPendingAndApplied:[CocoaDSUtil NSColorFromRGBA8888:(uint32_t)hudColorInputPendingAndApplied]];
|
||||||
|
[[windowController view] setHudColorInputAppliedOnly:[CocoaDSUtil NSColorFromRGBA8888:(uint32_t)hudColorInputAppliedOnly]];
|
||||||
|
[[windowController view] setHudColorInputPendingOnly:[CocoaDSUtil NSColorFromRGBA8888:(uint32_t)hudColorInputPendingOnly]];
|
||||||
|
|
||||||
[[windowController masterWindow] setFrameOrigin:NSMakePoint(frameX, frameY)];
|
[[windowController masterWindow] setFrameOrigin:NSMakePoint(frameX, frameY)];
|
||||||
|
|
||||||
|
@ -740,12 +747,16 @@
|
||||||
[NSNumber numberWithBool:[[windowController view] isHUDLagFrameCountVisible]], @"hudShowLagFrameCount",
|
[NSNumber numberWithBool:[[windowController view] isHUDLagFrameCountVisible]], @"hudShowLagFrameCount",
|
||||||
[NSNumber numberWithBool:[[windowController view] isHUDCPULoadAverageVisible]], @"hudShowCPULoadAverage",
|
[NSNumber numberWithBool:[[windowController view] isHUDCPULoadAverageVisible]], @"hudShowCPULoadAverage",
|
||||||
[NSNumber numberWithBool:[[windowController view] isHUDRealTimeClockVisible]], @"hudShowRTC",
|
[NSNumber numberWithBool:[[windowController view] isHUDRealTimeClockVisible]], @"hudShowRTC",
|
||||||
|
[NSNumber numberWithBool:[[windowController view] isHUDInputVisible]], @"hudShowInput",
|
||||||
[NSNumber numberWithUnsignedInteger:[CocoaDSUtil RGBA8888FromNSColor:[[windowController view] hudColorVideoFPS]]], @"hudColorVideoFPS",
|
[NSNumber numberWithUnsignedInteger:[CocoaDSUtil RGBA8888FromNSColor:[[windowController view] hudColorVideoFPS]]], @"hudColorVideoFPS",
|
||||||
[NSNumber numberWithUnsignedInteger:[CocoaDSUtil RGBA8888FromNSColor:[[windowController view] hudColorRender3DFPS]]], @"hudColorRender3DFPS",
|
[NSNumber numberWithUnsignedInteger:[CocoaDSUtil RGBA8888FromNSColor:[[windowController view] hudColorRender3DFPS]]], @"hudColorRender3DFPS",
|
||||||
[NSNumber numberWithUnsignedInteger:[CocoaDSUtil RGBA8888FromNSColor:[[windowController view] hudColorFrameIndex]]], @"hudColorFrameIndex",
|
[NSNumber numberWithUnsignedInteger:[CocoaDSUtil RGBA8888FromNSColor:[[windowController view] hudColorFrameIndex]]], @"hudColorFrameIndex",
|
||||||
[NSNumber numberWithUnsignedInteger:[CocoaDSUtil RGBA8888FromNSColor:[[windowController view] hudColorLagFrameCount]]], @"hudColorLagFrameCount",
|
[NSNumber numberWithUnsignedInteger:[CocoaDSUtil RGBA8888FromNSColor:[[windowController view] hudColorLagFrameCount]]], @"hudColorLagFrameCount",
|
||||||
[NSNumber numberWithUnsignedInteger:[CocoaDSUtil RGBA8888FromNSColor:[[windowController view] hudColorCPULoadAverage]]], @"hudColorCPULoadAverage",
|
[NSNumber numberWithUnsignedInteger:[CocoaDSUtil RGBA8888FromNSColor:[[windowController view] hudColorCPULoadAverage]]], @"hudColorCPULoadAverage",
|
||||||
[NSNumber numberWithUnsignedInteger:[CocoaDSUtil RGBA8888FromNSColor:[[windowController view] hudColorRTC]]], @"hudColorRTC",
|
[NSNumber numberWithUnsignedInteger:[CocoaDSUtil RGBA8888FromNSColor:[[windowController view] hudColorRTC]]], @"hudColorRTC",
|
||||||
|
[NSNumber numberWithUnsignedInteger:[CocoaDSUtil RGBA8888FromNSColor:[[windowController view] hudColorInputPendingAndApplied]]], @"hudColorInputPendingAndApplied",
|
||||||
|
[NSNumber numberWithUnsignedInteger:[CocoaDSUtil RGBA8888FromNSColor:[[windowController view] hudColorInputAppliedOnly]]], @"hudColorInputAppliedOnly",
|
||||||
|
[NSNumber numberWithUnsignedInteger:[CocoaDSUtil RGBA8888FromNSColor:[[windowController view] hudColorInputPendingOnly]]], @"hudColorInputPendingOnly",
|
||||||
[NSNumber numberWithBool:[windowController isMinSizeNormal]], @"isMinSizeNormal",
|
[NSNumber numberWithBool:[windowController isMinSizeNormal]], @"isMinSizeNormal",
|
||||||
[NSNumber numberWithBool:[windowController masterStatusBarState]], @"isShowingStatusBar",
|
[NSNumber numberWithBool:[windowController masterStatusBarState]], @"isShowingStatusBar",
|
||||||
[NSNumber numberWithBool:[windowController isFullScreen]], @"isInFullScreenMode",
|
[NSNumber numberWithBool:[windowController isFullScreen]], @"isInFullScreenMode",
|
||||||
|
|
Loading…
Reference in New Issue