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;
|
||||
_showCPULoadAverage = false;
|
||||
_showRTC = false;
|
||||
_showInputs = false;
|
||||
|
||||
_hudColorVideoFPS = 0xFFFFFFFF;
|
||||
_hudColorRender3DFPS = 0xFFFFFFFF;
|
||||
|
@ -99,6 +100,9 @@ void ClientDisplayView::__InstanceInit(const ClientDisplayViewProperties &props)
|
|||
_hudColorLagFrameCount = 0xFFFFFFFF;
|
||||
_hudColorCPULoadAverage = 0xFFFFFFFF;
|
||||
_hudColorRTC = 0xFFFFFFFF;
|
||||
_hudColorInputAppliedAndPending = 0xFFFFFFFF;
|
||||
_hudColorInputAppliedOnly = 0xFF3030FF;
|
||||
_hudColorInputPendingOnly = 0xFF00C000;
|
||||
|
||||
_clientFrameInfo.videoFPS = 0;
|
||||
_ndsFrameInfo.clear();
|
||||
|
@ -106,6 +110,7 @@ void ClientDisplayView::__InstanceInit(const ClientDisplayViewProperties &props)
|
|||
memset(&_emuDisplayInfo, 0, sizeof(_emuDisplayInfo));
|
||||
_hudString = "\x01"; // Char value 0x01 will represent the "text box" character, which will always be first in the string.
|
||||
_outHudString = _hudString;
|
||||
_hudInputString = "<^>vABXYLRSsgf x:000 y:000";
|
||||
_hudNeedsUpdate = true;
|
||||
_allowViewUpdates = true;
|
||||
|
||||
|
@ -167,7 +172,7 @@ void ClientDisplayView::_UpdateHUDString()
|
|||
|
||||
if (this->_showCPULoadAverage)
|
||||
{
|
||||
static char buffer[32];
|
||||
char buffer[32];
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
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";
|
||||
}
|
||||
|
||||
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);
|
||||
this->_hudString = ss.str();
|
||||
this->_hudNeedsUpdate = true;
|
||||
|
@ -292,6 +316,13 @@ void ClientDisplayView::SetupViewProperties()
|
|||
if (didOrderChange)
|
||||
{
|
||||
this->_UpdateOrder();
|
||||
|
||||
if (this->_showInputs)
|
||||
{
|
||||
pthread_mutex_lock(&this->_mutexHUDString);
|
||||
this->_hudNeedsUpdate = true;
|
||||
pthread_mutex_unlock(&this->_mutexHUDString);
|
||||
}
|
||||
}
|
||||
|
||||
if (didRotationChange)
|
||||
|
@ -567,6 +598,17 @@ void ClientDisplayView::SetHUDShowRTC(const bool visibleState)
|
|||
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
|
||||
{
|
||||
return this->_hudColorVideoFPS;
|
||||
|
@ -663,6 +705,78 @@ void ClientDisplayView::SetHUDColorRTC(uint32_t color32)
|
|||
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()
|
||||
{
|
||||
pthread_mutex_lock(&this->_mutexHUDString);
|
||||
|
@ -1296,7 +1410,7 @@ void ClientDisplay3DView::SetHUDPositionVertices(float viewportWidth, float view
|
|||
pthread_mutex_unlock(&this->_mutexHUDString);
|
||||
|
||||
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 lineHeight = charSize * 0.8f;
|
||||
const float textBoxTextOffset = charSize * 0.25f;
|
||||
|
@ -1312,7 +1426,10 @@ void ClientDisplay3DView::SetHUDPositionVertices(float viewportWidth, float view
|
|||
vtxPositionBufferPtr[6] = 0.0f; vtxPositionBufferPtr[7] = -textBoxTextOffset;
|
||||
|
||||
// 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];
|
||||
|
||||
|
@ -1365,15 +1482,239 @@ void ClientDisplay3DView::SetHUDPositionVertices(float viewportWidth, float view
|
|||
vtxPositionBufferPtr[4] += textBoxWidth;
|
||||
|
||||
// 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
|
||||
vtxPositionBufferPtr[i+0] *= textBoxScale;
|
||||
vtxPositionBufferPtr[i+1] *= textBoxScale;
|
||||
vtxPositionBufferPtr[k+0] *= textBoxScale;
|
||||
vtxPositionBufferPtr[k+1] *= textBoxScale;
|
||||
|
||||
// Translate
|
||||
vtxPositionBufferPtr[i+0] += boxOffset - (viewportWidth / 2.0f);
|
||||
vtxPositionBufferPtr[i+1] += (viewportHeight / 2.0f) - boxOffset;
|
||||
vtxPositionBufferPtr[k+0] += boxOffset - (viewportWidth / 2.0f);
|
||||
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);
|
||||
|
||||
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;
|
||||
|
||||
// First, calculate the color of the text box.
|
||||
|
@ -1433,7 +1774,10 @@ void ClientDisplay3DView::SetHUDColorVertices(uint32_t *vtxColorBufferPtr)
|
|||
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];
|
||||
|
||||
|
@ -1478,6 +1822,51 @@ void ClientDisplay3DView::SetHUDColorVertices(uint32_t *vtxColorBufferPtr)
|
|||
vtxColorBufferPtr[j+2] = currentColor; // Bottom Right
|
||||
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)
|
||||
|
@ -1487,9 +1876,10 @@ void ClientDisplay3DView::SetHUDTextureCoordinates(float *texCoordBufferPtr)
|
|||
pthread_mutex_unlock(&this->_mutexHUDString);
|
||||
|
||||
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 float *glyphTexCoord = this->_glyphInfo[c].texCoord;
|
||||
|
@ -1504,6 +1894,40 @@ void ClientDisplay3DView::SetHUDTextureCoordinates(float *texCoordBufferPtr)
|
|||
hudTexCoord[6] = glyphTexCoord[6];
|
||||
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)
|
||||
|
|
|
@ -29,9 +29,12 @@
|
|||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
|
||||
#define HUD_MAX_CHARACTERS 2048
|
||||
#define HUD_VERTEX_ATTRIBUTE_BUFFER_SIZE (sizeof(float) * HUD_MAX_CHARACTERS * (2 * 4))
|
||||
#define HUD_VERTEX_COLOR_ATTRIBUTE_BUFFER_SIZE (sizeof(uint32_t) * HUD_MAX_CHARACTERS * 4)
|
||||
#define HUD_TOTAL_ELEMENTS 1024
|
||||
#define HUD_INPUT_ELEMENT_LENGTH 26
|
||||
#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_BASE_SCALE (1.0/3.0)
|
||||
#define HUD_TEXTBOX_MIN_SCALE 0.70
|
||||
|
@ -160,6 +163,7 @@ protected:
|
|||
bool _showLagFrameCount;
|
||||
bool _showCPULoadAverage;
|
||||
bool _showRTC;
|
||||
bool _showInputs;
|
||||
|
||||
uint32_t _hudColorVideoFPS;
|
||||
uint32_t _hudColorRender3DFPS;
|
||||
|
@ -167,12 +171,16 @@ protected:
|
|||
uint32_t _hudColorLagFrameCount;
|
||||
uint32_t _hudColorCPULoadAverage;
|
||||
uint32_t _hudColorRTC;
|
||||
uint32_t _hudColorInputAppliedAndPending;
|
||||
uint32_t _hudColorInputAppliedOnly;
|
||||
uint32_t _hudColorInputPendingOnly;
|
||||
|
||||
ClientFrameInfo _clientFrameInfo;
|
||||
NDSFrameInfo _ndsFrameInfo;
|
||||
|
||||
NDSDisplayInfo _emuDisplayInfo;
|
||||
std::string _hudString;
|
||||
std::string _hudInputString;
|
||||
std::string _outHudString;
|
||||
bool _hudNeedsUpdate;
|
||||
bool _allowViewUpdates;
|
||||
|
@ -267,6 +275,8 @@ public:
|
|||
virtual void SetHUDShowCPULoadAverage(const bool visibleState);
|
||||
bool GetHUDShowRTC() const;
|
||||
virtual void SetHUDShowRTC(const bool visibleState);
|
||||
bool GetHUDShowInput() const;
|
||||
virtual void SetHUDShowInput(const bool visibleState);
|
||||
uint32_t GetHUDColorVideoFPS() const;
|
||||
virtual void SetHUDColorVideoFPS(uint32_t color32);
|
||||
uint32_t GetHUDColorRender3DFPS() const;
|
||||
|
@ -279,6 +289,13 @@ public:
|
|||
virtual void SetHUDColorCPULoadAverage(uint32_t color32);
|
||||
uint32_t GetHUDColorRTC() const;
|
||||
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();
|
||||
void ClearHUDNeedsUpdate();
|
||||
|
||||
|
@ -340,6 +357,7 @@ public:
|
|||
virtual void SetSourceDeposterize(const bool useDeposterize);
|
||||
|
||||
void SetHUDPositionVertices(float viewportWidth, float viewportHeight, float *vtxPositionBufferPtr);
|
||||
void SetHUDTouchLinePositionVertices(float *vtxBufferPtr);
|
||||
void SetHUDColorVertices(uint32_t *vtxColorBufferPtr);
|
||||
void SetHUDTextureCoordinates(float *texCoordBufferPtr);
|
||||
void SetScreenVertices(float *vtxBufferPtr);
|
||||
|
|
|
@ -22,16 +22,34 @@
|
|||
#include "GPU.h"
|
||||
#include "movie.h"
|
||||
#include "rtc.h"
|
||||
#include "slot2.h"
|
||||
|
||||
#include "audiosamplegenerator.h"
|
||||
#include "ClientExecutionControl.h"
|
||||
|
||||
|
||||
ClientExecutionControl::ClientExecutionControl()
|
||||
{
|
||||
_nullSampleGenerator = new NullGenerator;
|
||||
_internalNoiseGenerator = new InternalNoiseGenerator;
|
||||
_whiteNoiseGenerator = new WhiteNoiseGenerator;
|
||||
_sineWaveGenerator = new SineWaveGenerator(250.0, MIC_SAMPLE_RATE);
|
||||
_selectedAudioFileGenerator = NULL;
|
||||
|
||||
_newSettingsPendingOnReset = true;
|
||||
_newSettingsPendingOnExecutionLoopStart = 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;
|
||||
|
||||
_frameTime = 0.0;
|
||||
|
@ -83,9 +101,65 @@ ClientExecutionControl::ClientExecutionControl()
|
|||
_cpuEmulationEngineNameOut = _ndsFrameInfo.cpuEmulationEngineName;
|
||||
_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(&_mutexSettingsPendingOnExecutionLoopStart, NULL);
|
||||
pthread_mutex_init(&_mutexSettingsPendingOnNDSExec, NULL);
|
||||
pthread_mutex_init(&_mutexInputsPending, NULL);
|
||||
pthread_mutex_init(&_mutexOutputPostNDSExec, NULL);
|
||||
}
|
||||
|
||||
|
@ -94,7 +168,13 @@ ClientExecutionControl::~ClientExecutionControl()
|
|||
pthread_mutex_destroy(&this->_mutexSettingsPendingOnReset);
|
||||
pthread_mutex_destroy(&this->_mutexSettingsPendingOnExecutionLoopStart);
|
||||
pthread_mutex_destroy(&this->_mutexSettingsPendingOnNDSExec);
|
||||
pthread_mutex_destroy(&this->_mutexInputsPending);
|
||||
pthread_mutex_destroy(&this->_mutexOutputPostNDSExec);
|
||||
|
||||
delete this->_nullSampleGenerator;
|
||||
delete this->_internalNoiseGenerator;
|
||||
delete this->_whiteNoiseGenerator;
|
||||
delete this->_sineWaveGenerator;
|
||||
}
|
||||
|
||||
CPUEmulationEngineID ClientExecutionControl::GetCPUEmulationEngineID()
|
||||
|
@ -118,7 +198,7 @@ const char* ClientExecutionControl::GetCPUEmulationEngineName()
|
|||
void ClientExecutionControl::SetCPUEmulationEngineByID(CPUEmulationEngineID engineID)
|
||||
{
|
||||
#if !defined(__i386__) && !defined(__x86_64__)
|
||||
engineID = CPUEmulationEngine_Interpreter;
|
||||
engineID = CPUEmulationEngineID_Interpreter;
|
||||
#endif
|
||||
|
||||
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()
|
||||
{
|
||||
pthread_mutex_lock(&this->_mutexOutputPostNDSExec);
|
||||
|
@ -850,48 +1330,47 @@ void ClientExecutionControl::FetchOutputPostNDSExec()
|
|||
this->_ndsFrameInfo.rtcString = tempBuffer;
|
||||
free(tempBuffer);
|
||||
|
||||
const UserInput &ndsInputsPending = NDS_getRawUserInput();
|
||||
const UserInput &ndsInputsApplied = NDS_getFinalUserInput();
|
||||
|
||||
this->_ndsFrameInfo.inputStatesPending.value = INPUT_STATES_CLEAR_VALUE;
|
||||
this->_ndsFrameInfo.inputStatesPending.A = (ndsInputsPending.buttons.A) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesPending.B = (ndsInputsPending.buttons.B) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesPending.Select = (ndsInputsPending.buttons.T) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesPending.Start = (ndsInputsPending.buttons.S) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesPending.Right = (ndsInputsPending.buttons.R) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesPending.Left = (ndsInputsPending.buttons.L) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesPending.Up = (ndsInputsPending.buttons.U) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesPending.Down = (ndsInputsPending.buttons.D) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesPending.R = (ndsInputsPending.buttons.E) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesPending.L = (ndsInputsPending.buttons.W) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesPending.X = (ndsInputsPending.buttons.X) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesPending.Y = (ndsInputsPending.buttons.Y) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesPending.Debug = (ndsInputsPending.buttons.G) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesPending.Touch = (ndsInputsPending.touch.isTouch) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesPending.Lid = (ndsInputsPending.buttons.F) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesPending.Microphone = (ndsInputsPending.mic.micButtonPressed != 0) ? 0 : 1;
|
||||
this->_ndsFrameInfo.touchLocXPending = ndsInputsPending.touch.touchX >> 4;
|
||||
this->_ndsFrameInfo.touchLocYPending = ndsInputsPending.touch.touchY >> 4;
|
||||
|
||||
this->_ndsFrameInfo.inputStatesApplied.value = INPUT_STATES_CLEAR_VALUE;
|
||||
this->_ndsFrameInfo.inputStatesApplied.A = (ndsInputsApplied.buttons.A) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesApplied.B = (ndsInputsApplied.buttons.B) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesApplied.Select = (ndsInputsApplied.buttons.T) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesApplied.Start = (ndsInputsApplied.buttons.S) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesApplied.Right = (ndsInputsApplied.buttons.R) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesApplied.Left = (ndsInputsApplied.buttons.L) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesApplied.Up = (ndsInputsApplied.buttons.U) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesApplied.Down = (ndsInputsApplied.buttons.D) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesApplied.R = (ndsInputsApplied.buttons.E) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesApplied.L = (ndsInputsApplied.buttons.W) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesApplied.X = (ndsInputsApplied.buttons.X) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesApplied.Y = (ndsInputsApplied.buttons.Y) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesApplied.Debug = (ndsInputsApplied.buttons.G) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesApplied.Touch = (ndsInputsApplied.touch.isTouch) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesApplied.Lid = (ndsInputsApplied.buttons.F) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesApplied.Microphone = (ndsInputsApplied.mic.micButtonPressed != 0) ? 0 : 1;
|
||||
this->_ndsFrameInfo.touchLocXApplied = ndsInputsApplied.touch.touchX >> 4;
|
||||
this->_ndsFrameInfo.touchLocYApplied = ndsInputsApplied.touch.touchY >> 4;
|
||||
this->_ndsFrameInfo.inputStatesApplied.value = INPUT_STATES_CLEAR_VALUE;
|
||||
this->_ndsFrameInfo.inputStatesApplied.A = (this->_clientInputApplied[NDSInputID_A].isPressed) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesApplied.B = (this->_clientInputApplied[NDSInputID_B].isPressed) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesApplied.Select = (this->_clientInputApplied[NDSInputID_Select].isPressed) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesApplied.Start = (this->_clientInputApplied[NDSInputID_Start].isPressed) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesApplied.Right = (this->_clientInputApplied[NDSInputID_Right].isPressed) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesApplied.Left = (this->_clientInputApplied[NDSInputID_Left].isPressed) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesApplied.Up = (this->_clientInputApplied[NDSInputID_Up].isPressed) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesApplied.Down = (this->_clientInputApplied[NDSInputID_Down].isPressed) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesApplied.R = (this->_clientInputApplied[NDSInputID_R].isPressed) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesApplied.L = (this->_clientInputApplied[NDSInputID_L].isPressed) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesApplied.X = (this->_clientInputApplied[NDSInputID_X].isPressed) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesApplied.Y = (this->_clientInputApplied[NDSInputID_Y].isPressed) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesApplied.Debug = (this->_clientInputApplied[NDSInputID_Debug].isPressed) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesApplied.Touch = (this->_clientInputApplied[NDSInputID_Touch].isPressed) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesApplied.Lid = (this->_clientInputApplied[NDSInputID_Lid].isPressed) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesApplied.PianoC = (this->_clientInputApplied[NDSInputID_Piano_C].isPressed) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesApplied.PianoCSharp = (this->_clientInputApplied[NDSInputID_Piano_CSharp].isPressed) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesApplied.PianoD = (this->_clientInputApplied[NDSInputID_Piano_D].isPressed) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesApplied.PianoDSharp = (this->_clientInputApplied[NDSInputID_Piano_DSharp].isPressed) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesApplied.PianoE = (this->_clientInputApplied[NDSInputID_Piano_E].isPressed) ? 0 : 1;
|
||||
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.PianoG = (this->_clientInputApplied[NDSInputID_Piano_G].isPressed) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesApplied.PianoGSharp = (this->_clientInputApplied[NDSInputID_Piano_GSharp].isPressed) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesApplied.PianoA = (this->_clientInputApplied[NDSInputID_Piano_A].isPressed) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesApplied.PianoASharp = (this->_clientInputApplied[NDSInputID_Piano_ASharp].isPressed) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesApplied.PianoB = (this->_clientInputApplied[NDSInputID_Piano_B].isPressed) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesApplied.PianoHighC = (this->_clientInputApplied[NDSInputID_Piano_HighC].isPressed) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesApplied.GuitarGripBlue = (this->_clientInputApplied[NDSInputID_GuitarGrip_Blue].isPressed) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesApplied.GuitarGripYellow = (this->_clientInputApplied[NDSInputID_GuitarGrip_Yellow].isPressed) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesApplied.GuitarGripRed = (this->_clientInputApplied[NDSInputID_GuitarGrip_Red].isPressed) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesApplied.GuitarGripGreen = (this->_clientInputApplied[NDSInputID_GuitarGrip_Green].isPressed) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesApplied.Paddle = (this->_clientInputApplied[NDSInputID_Paddle].isPressed) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesApplied.Microphone = (this->_clientInputApplied[NDSInputID_Microphone].isPressed) ? 0 : 1;
|
||||
this->_ndsFrameInfo.inputStatesApplied.Reset = (this->_clientInputApplied[NDSInputID_Reset].isPressed) ? 0 : 1;
|
||||
this->_ndsFrameInfo.touchLocXApplied = this->_touchLocXApplied;
|
||||
this->_ndsFrameInfo.touchLocYApplied = this->_touchLocYApplied;
|
||||
this->_ndsFrameInfo.touchPressureApplied = this->_touchPressureApplied;
|
||||
this->_ndsFrameInfo.paddleValueApplied = this->_paddleValueApplied;
|
||||
this->_ndsFrameInfo.paddleAdjustApplied = this->_paddleAdjustApplied;
|
||||
|
||||
pthread_mutex_unlock(&this->_mutexOutputPostNDSExec);
|
||||
}
|
||||
|
|
|
@ -19,28 +19,39 @@
|
|||
#define _CLIENT_EXECUTION_CONTROL_H_
|
||||
|
||||
#include <pthread.h>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "../../slot1.h"
|
||||
#undef BOOL
|
||||
|
||||
#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_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_DOUBLE 2.0 // Speed scalar for double execution speed.
|
||||
#define SPEED_SCALAR_MIN 0.005 // Lower limit for the speed multiplier.
|
||||
#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_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_DOUBLE 2.0 // Speed scalar for double execution speed.
|
||||
#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 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.
|
||||
#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_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.
|
||||
#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 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
|
||||
{
|
||||
ExecutionBehavior_Pause = 0,
|
||||
|
@ -81,13 +92,6 @@ enum NDSInputID
|
|||
NDSInputID_Touch,
|
||||
NDSInputID_Lid,
|
||||
|
||||
NDSInputID_Microphone,
|
||||
|
||||
NDSInputID_GuitarGrip_Green,
|
||||
NDSInputID_GuitarGrip_Red,
|
||||
NDSInputID_GuitarGrip_Yellow,
|
||||
NDSInputID_GuitarGrip_Blue,
|
||||
|
||||
NDSInputID_Piano_C,
|
||||
NDSInputID_Piano_CSharp,
|
||||
NDSInputID_Piano_D,
|
||||
|
@ -102,11 +106,81 @@ enum NDSInputID
|
|||
NDSInputID_Piano_B,
|
||||
NDSInputID_Piano_HighC,
|
||||
|
||||
NDSInputID_GuitarGrip_Green,
|
||||
NDSInputID_GuitarGrip_Red,
|
||||
NDSInputID_GuitarGrip_Yellow,
|
||||
NDSInputID_GuitarGrip_Blue,
|
||||
|
||||
NDSInputID_Paddle,
|
||||
NDSInputID_Microphone,
|
||||
NDSInputID_Reset,
|
||||
|
||||
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
|
||||
{
|
||||
uint64_t value;
|
||||
|
@ -184,7 +258,7 @@ typedef union
|
|||
uint8_t B:1;
|
||||
uint8_t A:1;
|
||||
|
||||
uint8_t :6
|
||||
uint8_t :6;
|
||||
uint8_t L: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
|
||||
|
||||
struct ClientInput
|
||||
{
|
||||
bool isPressed;
|
||||
bool turbo;
|
||||
bool autohold;
|
||||
uint32_t turboPattern;
|
||||
uint8_t turboPatternStep;
|
||||
uint8_t turboPatternLength;
|
||||
};
|
||||
typedef struct ClientInput ClientInput;
|
||||
|
||||
struct ClientExecutionControlSettings
|
||||
{
|
||||
CPUEmulationEngineID cpuEngineID;
|
||||
|
@ -281,64 +366,119 @@ struct NDSFrameInfo
|
|||
NDSInputState inputStatesPending;
|
||||
uint8_t touchLocXPending;
|
||||
uint8_t touchLocYPending;
|
||||
uint8_t touchPressurePending;
|
||||
int16_t paddleValuePending;
|
||||
int16_t paddleAdjustPending;
|
||||
|
||||
NDSInputState inputStatesApplied;
|
||||
uint8_t touchLocXApplied;
|
||||
uint8_t touchLocYApplied;
|
||||
uint8_t touchPressureApplied;
|
||||
int16_t paddleValueApplied;
|
||||
int16_t paddleAdjustApplied;
|
||||
|
||||
void clear()
|
||||
{
|
||||
this->cpuEmulationEngineName = std::string();
|
||||
this->slot1DeviceName = std::string();
|
||||
this->rtcString = std::string();
|
||||
this->frameIndex = 0;
|
||||
this->render3DFPS = 0;
|
||||
this->lagFrameCount = 0;
|
||||
this->cpuLoadAvgARM9 = 0;
|
||||
this->cpuLoadAvgARM7 = 0;
|
||||
this->cpuEmulationEngineName = std::string();
|
||||
this->slot1DeviceName = std::string();
|
||||
this->rtcString = std::string();
|
||||
|
||||
this->inputStatesPending.value = INPUT_STATES_CLEAR_VALUE;
|
||||
this->touchLocXPending = 0;
|
||||
this->touchLocYPending = 0;
|
||||
this->frameIndex = 0;
|
||||
this->render3DFPS = 0;
|
||||
this->lagFrameCount = 0;
|
||||
this->cpuLoadAvgARM9 = 0;
|
||||
this->cpuLoadAvgARM7 = 0;
|
||||
|
||||
this->inputStatesApplied.value = INPUT_STATES_CLEAR_VALUE;
|
||||
this->touchLocXApplied = 0;
|
||||
this->touchLocYApplied = 0;
|
||||
this->inputStatesPending.value = INPUT_STATES_CLEAR_VALUE;
|
||||
this->touchLocXPending = 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)
|
||||
{
|
||||
this->cpuEmulationEngineName = fromObject.cpuEmulationEngineName;
|
||||
this->slot1DeviceName = fromObject.slot1DeviceName;
|
||||
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->cpuEmulationEngineName = fromObject.cpuEmulationEngineName;
|
||||
this->slot1DeviceName = fromObject.slot1DeviceName;
|
||||
this->rtcString = fromObject.rtcString;
|
||||
|
||||
this->inputStatesPending = fromObject.inputStatesPending;
|
||||
this->touchLocXPending = fromObject.touchLocXPending;
|
||||
this->touchLocYPending = fromObject.touchLocYPending;
|
||||
this->frameIndex = fromObject.frameIndex;
|
||||
this->render3DFPS = fromObject.render3DFPS;
|
||||
this->lagFrameCount = fromObject.lagFrameCount;
|
||||
this->cpuLoadAvgARM9 = fromObject.cpuLoadAvgARM9;
|
||||
this->cpuLoadAvgARM7 = fromObject.cpuLoadAvgARM7;
|
||||
|
||||
this->inputStatesApplied = fromObject.inputStatesApplied;
|
||||
this->touchLocXApplied = fromObject.touchLocXApplied;
|
||||
this->touchLocYApplied = fromObject.touchLocYApplied;
|
||||
this->inputStatesPending = fromObject.inputStatesPending;
|
||||
this->touchLocXPending = fromObject.touchLocXPending;
|
||||
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
|
||||
{
|
||||
private:
|
||||
NDSUserInputMap _userInputMap;
|
||||
NDSInputStateBitMap _inputStateBitMap;
|
||||
|
||||
AudioGenerator *_softwareMicSampleGeneratorPending;
|
||||
AudioGenerator *_softwareMicSampleGeneratorProcessing;
|
||||
AudioGenerator *_softwareMicSampleGeneratorApplied;
|
||||
NullGenerator *_nullSampleGenerator;
|
||||
InternalNoiseGenerator *_internalNoiseGenerator;
|
||||
WhiteNoiseGenerator *_whiteNoiseGenerator;
|
||||
SineWaveGenerator *_sineWaveGenerator;
|
||||
AudioSampleBlockGenerator *_selectedAudioFileGenerator;
|
||||
|
||||
ClientExecutionControlSettings _settingsPending;
|
||||
ClientExecutionControlSettings _settingsApplied;
|
||||
|
||||
NDSFrameInfo _ndsFrameInfo;
|
||||
ClientInput _clientInputPending[NDSInputID_InputCount];
|
||||
ClientInput _clientInputProcessing[NDSInputID_InputCount];
|
||||
ClientInput _clientInputApplied[NDSInputID_InputCount];
|
||||
|
||||
bool _newSettingsPendingOnReset;
|
||||
bool _newSettingsPendingOnExecutionLoopStart;
|
||||
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;
|
||||
|
||||
double _frameTime;
|
||||
|
@ -352,6 +492,7 @@ private:
|
|||
pthread_mutex_t _mutexSettingsPendingOnReset;
|
||||
pthread_mutex_t _mutexSettingsPendingOnExecutionLoopStart;
|
||||
pthread_mutex_t _mutexSettingsPendingOnNDSExec;
|
||||
pthread_mutex_t _mutexInputsPending;
|
||||
pthread_mutex_t _mutexOutputPostNDSExec;
|
||||
|
||||
public:
|
||||
|
@ -444,6 +585,32 @@ public:
|
|||
void ApplySettingsOnExecutionLoopStart();
|
||||
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();
|
||||
const NDSFrameInfo& GetNDSFrameInfo();
|
||||
|
||||
|
|
|
@ -112,12 +112,12 @@
|
|||
<false/>
|
||||
<key>HUD_ShowLagFrameCount</key>
|
||||
<false/>
|
||||
<key>HUD_ShowInput</key>
|
||||
<false/>
|
||||
<key>HUD_ShowCPULoadAverage</key>
|
||||
<false/>
|
||||
<key>HUD_ShowRTC</key>
|
||||
<false/>
|
||||
<key>HUD_ShowInput</key>
|
||||
<false/>
|
||||
<key>HUD_Color_VideoFPS</key>
|
||||
<integer>4294967295</integer>
|
||||
<key>HUD_Color_Render3DFPS</key>
|
||||
|
@ -130,6 +130,12 @@
|
|||
<integer>4294967295</integer>
|
||||
<key>HUD_Color_RTC</key>
|
||||
<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>
|
||||
<integer>1</integer>
|
||||
<key>Input_ControllerMappings</key>
|
||||
|
|
|
@ -32,18 +32,28 @@ static const char *HUDOutputVertShader_100 = {"\
|
|||
ATTRIBUTE vec2 inTexCoord0; \n\
|
||||
\n\
|
||||
uniform vec2 viewSize; \n\
|
||||
uniform float scalar; \n\
|
||||
uniform float angleDegrees; \n\
|
||||
\n\
|
||||
VARYING vec4 vtxColor; \n\
|
||||
VARYING vec2 texCoord[1]; \n\
|
||||
\n\
|
||||
void main() \n\
|
||||
{ \n\
|
||||
float angleRadians = radians(angleDegrees); \n\
|
||||
\n\
|
||||
mat2 projection = mat2( vec2(2.0/viewSize.x, 0.0), \n\
|
||||
vec2( 0.0, 2.0/viewSize.y)); \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\
|
||||
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\
|
||||
"};
|
||||
|
||||
|
@ -5016,7 +5026,11 @@ void OGLVideoOutput::_UpdateOrder()
|
|||
|
||||
void OGLVideoOutput::_UpdateRotation()
|
||||
{
|
||||
this->GetDisplayLayer()->SetNeedsUpdateRotationScale();
|
||||
for (size_t i = 0; i < _layerList->size(); i++)
|
||||
{
|
||||
OGLVideoLayer *theLayer = (*_layerList)[i];
|
||||
theLayer->SetNeedsUpdateRotationScale();
|
||||
}
|
||||
}
|
||||
|
||||
void OGLVideoOutput::_UpdateClientSize()
|
||||
|
@ -5032,7 +5046,12 @@ void OGLVideoOutput::_UpdateClientSize()
|
|||
void OGLVideoOutput::_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()
|
||||
|
@ -5042,11 +5061,7 @@ void OGLVideoOutput::_UpdateViewport()
|
|||
for (size_t i = 0; i < _layerList->size(); i++)
|
||||
{
|
||||
OGLVideoLayer *theLayer = (*_layerList)[i];
|
||||
|
||||
if (theLayer->IsVisible())
|
||||
{
|
||||
theLayer->SetNeedsUpdateViewport();
|
||||
}
|
||||
theLayer->SetNeedsUpdateViewport();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5614,9 +5629,9 @@ OGLImage::OGLImage(OGLContextInfo *contextInfo, GLsizei imageWidth, GLsizei imag
|
|||
|
||||
const GLuint finalOutputProgramID = _finalOutputProgram->GetProgramID();
|
||||
glUseProgram(finalOutputProgramID);
|
||||
_uniformFinalOutputAngleDegrees = glGetUniformLocation(finalOutputProgramID, "angleDegrees");
|
||||
_uniformFinalOutputScalar = glGetUniformLocation(finalOutputProgramID, "scalar");
|
||||
_uniformFinalOutputViewSize = glGetUniformLocation(finalOutputProgramID, "viewSize");
|
||||
_uniformAngleDegrees = glGetUniformLocation(finalOutputProgramID, "angleDegrees");
|
||||
_uniformScalar = glGetUniformLocation(finalOutputProgramID, "scalar");
|
||||
_uniformViewSize = glGetUniformLocation(finalOutputProgramID, "viewSize");
|
||||
glUseProgram(0);
|
||||
}
|
||||
else
|
||||
|
@ -5753,9 +5768,9 @@ void OGLImage::UploadTransformationOGL()
|
|||
|
||||
if (this->_canUseShaderOutput)
|
||||
{
|
||||
glUniform2f(this->_uniformFinalOutputViewSize, w, h);
|
||||
glUniform1f(this->_uniformFinalOutputAngleDegrees, 0.0f);
|
||||
glUniform1f(this->_uniformFinalOutputScalar, s);
|
||||
glUniform2f(this->_uniformViewSize, w, h);
|
||||
glUniform1f(this->_uniformAngleDegrees, 0.0f);
|
||||
glUniform1f(this->_uniformScalar, s);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -6175,6 +6190,11 @@ void OGLVideoLayer::SetNeedsUpdateViewport()
|
|||
this->_needUpdateViewport = true;
|
||||
}
|
||||
|
||||
void OGLVideoLayer::SetNeedsUpdateRotationScale()
|
||||
{
|
||||
this->_needUpdateRotationScale = true;
|
||||
}
|
||||
|
||||
void OGLVideoLayer::SetNeedsUpdateVertices()
|
||||
{
|
||||
this->_needUpdateVertices = true;
|
||||
|
@ -6205,6 +6225,8 @@ OGLHUDLayer::OGLHUDLayer(OGLVideoOutput *oglVO)
|
|||
_program->SetVertexAndFragmentShaderOGL(HUDOutputVertShader_100, HUDOutputFragShader_110, true, oglVO->GetContextInfo()->IsUsingShader150());
|
||||
|
||||
glUseProgram(_program->GetProgramID());
|
||||
_uniformAngleDegrees = glGetUniformLocation(_program->GetProgramID(), "angleDegrees");
|
||||
_uniformScalar = glGetUniformLocation(_program->GetProgramID(), "scalar");
|
||||
_uniformViewSize = glGetUniformLocation(_program->GetProgramID(), "viewSize");
|
||||
glUseProgram(0);
|
||||
}
|
||||
|
@ -6230,10 +6252,10 @@ OGLHUDLayer::OGLHUDLayer(OGLVideoOutput *oglVO)
|
|||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
|
||||
|
||||
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);
|
||||
|
||||
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+1] = k+1;
|
||||
|
@ -6418,8 +6440,44 @@ void OGLHUDLayer::_UpdateVerticesOGL()
|
|||
|
||||
void OGLHUDLayer::RenderOGL()
|
||||
{
|
||||
const size_t length = this->_output->GetHUDString().length();
|
||||
if (length <= 1)
|
||||
size_t hudLength = this->_output->GetHUDString().length();
|
||||
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;
|
||||
}
|
||||
|
@ -6443,12 +6501,65 @@ void OGLHUDLayer::RenderOGL()
|
|||
glBindVertexArrayDESMUME(this->_vaoMainStatesID);
|
||||
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_MAG_FILTER, GL_NEAREST);
|
||||
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();
|
||||
if (textBoxScale >= (2.0/3.0))
|
||||
{
|
||||
|
@ -6462,7 +6573,7 @@ void OGLHUDLayer::RenderOGL()
|
|||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
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);
|
||||
glBindVertexArrayDESMUME(0);
|
||||
|
@ -6531,9 +6642,9 @@ OGLDisplayLayer::OGLDisplayLayer(OGLVideoOutput *oglVO)
|
|||
|
||||
const GLuint finalOutputProgramID = _finalOutputProgram->GetProgramID();
|
||||
glUseProgram(finalOutputProgramID);
|
||||
_uniformFinalOutputAngleDegrees = glGetUniformLocation(finalOutputProgramID, "angleDegrees");
|
||||
_uniformFinalOutputScalar = glGetUniformLocation(finalOutputProgramID, "scalar");
|
||||
_uniformFinalOutputViewSize = glGetUniformLocation(finalOutputProgramID, "viewSize");
|
||||
_uniformAngleDegrees = glGetUniformLocation(finalOutputProgramID, "angleDegrees");
|
||||
_uniformScalar = glGetUniformLocation(finalOutputProgramID, "scalar");
|
||||
_uniformViewSize = glGetUniformLocation(finalOutputProgramID, "viewSize");
|
||||
glUseProgram(0);
|
||||
}
|
||||
else
|
||||
|
@ -6589,23 +6700,16 @@ OGLDisplayLayer::~OGLDisplayLayer()
|
|||
}
|
||||
}
|
||||
|
||||
void OGLDisplayLayer::SetNeedsUpdateRotationScale()
|
||||
{
|
||||
this->_needUpdateRotationScale = true;
|
||||
this->_needUpdateVertices = true;
|
||||
}
|
||||
|
||||
void OGLDisplayLayer::_UpdateRotationScaleOGL()
|
||||
{
|
||||
const ClientDisplayViewProperties &cdv = this->_output->GetViewProperties();
|
||||
|
||||
const double r = cdv.rotation;
|
||||
const double s = cdv.viewScale;
|
||||
|
||||
if (this->_output->GetContextInfo()->IsShaderSupported())
|
||||
{
|
||||
glUniform1f(this->_uniformFinalOutputAngleDegrees, r);
|
||||
glUniform1f(this->_uniformFinalOutputScalar, s);
|
||||
glUniform1f(this->_uniformAngleDegrees, r);
|
||||
glUniform1f(this->_uniformScalar, s);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -7040,7 +7144,7 @@ void OGLDisplayLayer::RenderOGL()
|
|||
|
||||
if (this->_needUpdateViewport)
|
||||
{
|
||||
glUniform2f(this->_uniformFinalOutputViewSize, this->_output->GetViewportWidth(), this->_output->GetViewportHeight());
|
||||
glUniform2f(this->_uniformViewSize, this->_output->GetViewportWidth(), this->_output->GetViewportHeight());
|
||||
this->_needUpdateViewport = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -209,9 +209,9 @@ protected:
|
|||
GLuint _vboVertexID;
|
||||
GLuint _vboTexCoordID;
|
||||
|
||||
GLint _uniformFinalOutputAngleDegrees;
|
||||
GLint _uniformFinalOutputScalar;
|
||||
GLint _uniformFinalOutputViewSize;
|
||||
GLint _uniformAngleDegrees;
|
||||
GLint _uniformScalar;
|
||||
GLint _uniformViewSize;
|
||||
|
||||
void UploadVerticesOGL();
|
||||
void UploadTexCoordsOGL();
|
||||
|
@ -254,10 +254,15 @@ protected:
|
|||
bool _needUpdateRotationScale;
|
||||
bool _needUpdateVertices;
|
||||
|
||||
GLint _uniformAngleDegrees;
|
||||
GLint _uniformScalar;
|
||||
GLint _uniformViewSize;
|
||||
|
||||
public:
|
||||
virtual ~OGLVideoLayer() {};
|
||||
|
||||
void SetNeedsUpdateViewport();
|
||||
void SetNeedsUpdateRotationScale();
|
||||
void SetNeedsUpdateVertices();
|
||||
|
||||
virtual bool IsVisible();
|
||||
|
@ -271,7 +276,6 @@ class OGLHUDLayer : public OGLVideoLayer
|
|||
{
|
||||
protected:
|
||||
OGLShaderProgram *_program;
|
||||
GLint _uniformViewSize;
|
||||
|
||||
GLuint _vaoMainStatesID;
|
||||
GLuint _vboPositionVertexID;
|
||||
|
@ -305,10 +309,6 @@ protected:
|
|||
GLuint _vboVertexID;
|
||||
GLuint _vboTexCoordID;
|
||||
|
||||
GLint _uniformFinalOutputAngleDegrees;
|
||||
GLint _uniformFinalOutputScalar;
|
||||
GLint _uniformFinalOutputViewSize;
|
||||
|
||||
void _UpdateRotationScaleOGL();
|
||||
void _UpdateVerticesOGL();
|
||||
|
||||
|
@ -319,8 +319,6 @@ public:
|
|||
OGLDisplayLayer(OGLVideoOutput *oglVO);
|
||||
virtual ~OGLDisplayLayer();
|
||||
|
||||
void SetNeedsUpdateRotationScale();
|
||||
|
||||
OutputFilterTypeID SetOutputFilterOGL(const OutputFilterTypeID 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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -23,7 +23,7 @@
|
|||
#include "audiosamplegenerator.h"
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include "cocoa_globals.h"
|
||||
#include "ClientExecutionControl.h"
|
||||
|
||||
#define NUM_INTERNAL_NOISE_SAMPLES 32
|
||||
|
||||
|
|
|
@ -972,21 +972,8 @@ static void* RunCoreThread(void *arg)
|
|||
frameTime = execControl->GetFrameTime();
|
||||
frameJumpTarget = execControl->GetFrameJumpTargetApplied();
|
||||
|
||||
CocoaDSController *cdsController = [cdsCore cdsController];
|
||||
if (behavior != ExecutionBehavior_FrameJump)
|
||||
{
|
||||
[cdsController flush];
|
||||
}
|
||||
else
|
||||
{
|
||||
[cdsController flushEmpty];
|
||||
}
|
||||
|
||||
NDS_beginProcessingInput();
|
||||
FCEUMOV_HandlePlayback();
|
||||
NDS_endProcessingInput();
|
||||
FCEUMOV_HandleRecording();
|
||||
|
||||
execControl->ProcessInputs();
|
||||
execControl->ApplyInputs();
|
||||
execControl->ApplySettingsOnNDSExec();
|
||||
|
||||
// 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.
|
||||
if ((ndsFrameInfo.frameIndex & 0x07) == 0x07)
|
||||
{
|
||||
CocoaDSController *cdsController = [cdsCore cdsController];
|
||||
[cdsController updateMicLevel];
|
||||
[cdsController clearMicLevelMeasure];
|
||||
}
|
||||
|
|
|
@ -204,16 +204,6 @@
|
|||
#define ROMINFO_GAME_CODE_LENGTH 4
|
||||
#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_DEFAULT 1
|
||||
#define COCOA_DIALOG_OK 1
|
||||
|
@ -397,19 +387,6 @@ enum
|
|||
CORE3DLIST_OPENGL
|
||||
};
|
||||
|
||||
/*
|
||||
MICROPHONE MODE
|
||||
*/
|
||||
enum
|
||||
{
|
||||
MICMODE_NONE = 0,
|
||||
MICMODE_INTERNAL_NOISE,
|
||||
MICMODE_AUDIO_FILE,
|
||||
MICMODE_WHITE_NOISE,
|
||||
MICMODE_PHYSICAL,
|
||||
MICMODE_SINE_WAVE
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PADDLE_CONTROL_RELATIVE = 0,
|
||||
|
|
|
@ -28,16 +28,6 @@ struct CoreAudioInputDeviceInfo;
|
|||
class AudioGenerator;
|
||||
class AudioSampleBlockGenerator;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
bool isPressed;
|
||||
bool turbo;
|
||||
bool autohold;
|
||||
uint32_t turboPattern;
|
||||
uint8_t turboPatternStep;
|
||||
uint8_t turboPatternLength;
|
||||
} ClientInput;
|
||||
|
||||
@protocol CocoaDSControllerDelegate <NSObject>
|
||||
|
||||
@optional
|
||||
|
@ -53,13 +43,8 @@ typedef struct
|
|||
@interface CocoaDSController : NSObject
|
||||
{
|
||||
id <CocoaDSControllerDelegate> delegate;
|
||||
ClientExecutionControl *execControl;
|
||||
|
||||
ClientInput clientInput[NDSInputID_InputCount];
|
||||
BOOL autohold;
|
||||
BOOL _isAutoholdCleared;
|
||||
|
||||
NSPoint touchLocation;
|
||||
NSInteger paddleAdjust;
|
||||
NSInteger stylusPressure;
|
||||
|
||||
float micLevel;
|
||||
|
@ -67,23 +52,18 @@ typedef struct
|
|||
float _micLevelsRead;
|
||||
|
||||
BOOL hardwareMicMute;
|
||||
BOOL _useHardwareMic;
|
||||
size_t _availableMicSamples;
|
||||
NSInteger micMode;
|
||||
|
||||
AudioSampleBlockGenerator *selectedAudioFileGenerator;
|
||||
CoreAudioInput *CAInputDevice;
|
||||
AudioGenerator *softwareMicSampleGenerator;
|
||||
|
||||
NSString *hardwareMicInfoString;
|
||||
NSString *hardwareMicNameString;
|
||||
NSString *hardwareMicManufacturerString;
|
||||
NSString *hardwareMicSampleRateString;
|
||||
|
||||
OSSpinLock spinlockControllerState;
|
||||
}
|
||||
|
||||
@property (retain) id <CocoaDSControllerDelegate> delegate;
|
||||
@property (assign) ClientExecutionControl *execControl;
|
||||
@property (assign) BOOL autohold;
|
||||
@property (assign) NSInteger paddleAdjust;
|
||||
@property (assign) NSInteger stylusPressure;
|
||||
|
@ -96,9 +76,6 @@ typedef struct
|
|||
@property (assign) float hardwareMicGain;
|
||||
@property (assign) BOOL hardwareMicMute;
|
||||
@property (assign) BOOL hardwareMicPause;
|
||||
@property (assign) BOOL softwareMicState;
|
||||
@property (assign) NSInteger softwareMicMode;
|
||||
@property (assign) NSInteger micMode;
|
||||
@property (readonly) CoreAudioInput *CAInputDevice;
|
||||
@property (readonly) AudioGenerator *softwareMicSampleGenerator;
|
||||
@property (assign) AudioSampleBlockGenerator *selectedAudioFileGenerator;
|
||||
|
@ -107,13 +84,13 @@ typedef struct
|
|||
@property (retain) NSString *hardwareMicManufacturerString;
|
||||
@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 turbo:(const BOOL)isTurboEnabled turboPattern:(uint32_t)turboPattern turboPatternLength:(uint32_t)turboPatternLength;
|
||||
- (void) setTouchState:(BOOL)theState location:(const NSPoint)theLocation;
|
||||
- (void) setSineWaveGeneratorFrequency:(const double)freq;
|
||||
- (void) clearAutohold;
|
||||
- (void) flush;
|
||||
- (void) flushEmpty;
|
||||
- (void) reset;
|
||||
|
||||
- (void) clearMicLevelMeasure;
|
||||
|
|
|
@ -26,17 +26,13 @@
|
|||
#include "../../slot2.h"
|
||||
#undef BOOL
|
||||
|
||||
NullGenerator nullSampleGenerator;
|
||||
InternalNoiseGenerator internalNoiseGenerator;
|
||||
WhiteNoiseGenerator whiteNoiseGenerator;
|
||||
SineWaveGenerator sineWaveGenerator(250.0, MIC_SAMPLE_RATE);
|
||||
|
||||
|
||||
@implementation CocoaDSController
|
||||
|
||||
@synthesize delegate;
|
||||
@synthesize execControl;
|
||||
@dynamic autohold;
|
||||
@synthesize paddleAdjust;
|
||||
@dynamic paddleAdjust;
|
||||
@synthesize stylusPressure;
|
||||
@dynamic isHardwareMicAvailable;
|
||||
@dynamic isHardwareMicIdle;
|
||||
|
@ -47,12 +43,9 @@ SineWaveGenerator sineWaveGenerator(250.0, MIC_SAMPLE_RATE);
|
|||
@dynamic hardwareMicGain;
|
||||
@synthesize hardwareMicMute;
|
||||
@dynamic hardwareMicPause;
|
||||
@dynamic softwareMicState;
|
||||
@dynamic softwareMicMode;
|
||||
@synthesize micMode;
|
||||
@synthesize CAInputDevice;
|
||||
@synthesize softwareMicSampleGenerator;
|
||||
@synthesize selectedAudioFileGenerator;
|
||||
@dynamic softwareMicSampleGenerator;
|
||||
@dynamic selectedAudioFileGenerator;
|
||||
@synthesize hardwareMicInfoString;
|
||||
@synthesize hardwareMicNameString;
|
||||
@synthesize hardwareMicManufacturerString;
|
||||
|
@ -65,36 +58,18 @@ SineWaveGenerator sineWaveGenerator(250.0, MIC_SAMPLE_RATE);
|
|||
{
|
||||
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;
|
||||
spinlockControllerState = OS_SPINLOCK_INIT;
|
||||
autohold = NO;
|
||||
_isAutoholdCleared = YES;
|
||||
_useHardwareMic = NO;
|
||||
execControl = NULL;
|
||||
_availableMicSamples = 0;
|
||||
|
||||
micLevel = 0.0f;
|
||||
_micLevelTotal = 0.0f;
|
||||
_micLevelsRead = 0.0f;
|
||||
|
||||
micMode = MICMODE_NONE;
|
||||
selectedAudioFileGenerator = NULL;
|
||||
CAInputDevice = new CoreAudioInput;
|
||||
CAInputDevice->SetCallbackHardwareStateChanged(&CAHardwareStateChangedCallback, self, NULL);
|
||||
CAInputDevice->SetCallbackHardwareGainChanged(&CAHardwareGainChangedCallback, self, NULL);
|
||||
softwareMicSampleGenerator = &nullSampleGenerator;
|
||||
touchLocation = NSMakePoint(0.0f, 0.0f);
|
||||
paddleAdjust = 0;
|
||||
|
||||
hardwareMicInfoString = @"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;
|
||||
}
|
||||
|
||||
- (void) setSoftwareMicState:(BOOL)theState
|
||||
- (void) setSoftwareMicState:(BOOL)theState mode:(NSInteger)micMode
|
||||
{
|
||||
OSSpinLockLock(&spinlockControllerState);
|
||||
clientInput[NDSInputID_Microphone].isPressed = (theState) ? true : false;
|
||||
OSSpinLockUnlock(&spinlockControllerState);
|
||||
execControl->SetClientSoftwareMicState((theState) ? true : false, (MicrophoneMode)micMode);
|
||||
}
|
||||
|
||||
- (BOOL) softwareMicState
|
||||
{
|
||||
OSSpinLockLock(&spinlockControllerState);
|
||||
BOOL theState = (clientInput[NDSInputID_Microphone].isPressed) ? YES : NO;
|
||||
OSSpinLockUnlock(&spinlockControllerState);
|
||||
return theState;
|
||||
return (execControl->GetClientSoftwareMicState()) ? YES : NO;
|
||||
}
|
||||
|
||||
- (void) setSoftwareMicMode:(NSInteger)theMode
|
||||
- (AudioGenerator *) softwareMicSampleGenerator
|
||||
{
|
||||
OSSpinLockLock(&spinlockControllerState);
|
||||
micMode = theMode;
|
||||
OSSpinLockUnlock(&spinlockControllerState);
|
||||
return execControl->GetClientSoftwareMicSampleGenerator();
|
||||
}
|
||||
|
||||
- (NSInteger) softwareMicMode
|
||||
- (void) setSelectedAudioFileGenerator:(AudioSampleBlockGenerator *)audioGenerator
|
||||
{
|
||||
OSSpinLockLock(&spinlockControllerState);
|
||||
NSInteger theMode = micMode;
|
||||
OSSpinLockUnlock(&spinlockControllerState);
|
||||
return theMode;
|
||||
execControl->SetClientSelectedAudioFileGenerator(audioGenerator);
|
||||
}
|
||||
|
||||
- (AudioSampleBlockGenerator *) selectedAudioFileGenerator
|
||||
{
|
||||
return execControl->GetClientSelectedAudioFileGenerator();
|
||||
}
|
||||
|
||||
- (void) setAutohold:(BOOL)theState
|
||||
{
|
||||
OSSpinLockLock(&spinlockControllerState);
|
||||
|
||||
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);
|
||||
execControl->SetEnableAutohold((theState) ? true: false);
|
||||
}
|
||||
|
||||
- (BOOL) autohold
|
||||
{
|
||||
OSSpinLockLock(&spinlockControllerState);
|
||||
const BOOL theState = autohold;
|
||||
OSSpinLockUnlock(&spinlockControllerState);
|
||||
return theState;
|
||||
return (execControl->GetEnableAutohold()) ? YES : NO;
|
||||
}
|
||||
|
||||
- (void) setPaddleAdjust:(NSInteger)paddleAdjust
|
||||
{
|
||||
execControl->SetClientPaddleAdjust((int16_t)paddleAdjust);
|
||||
}
|
||||
|
||||
- (NSInteger) paddleAdjust
|
||||
{
|
||||
return (NSInteger)execControl->GetClientPaddleAdjust();
|
||||
}
|
||||
|
||||
- (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
|
||||
{
|
||||
if (controlID >= NDSInputID_InputCount)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
execControl->SetClientInputStateUsingID((NDSInputID)controlID,
|
||||
(theState) ? true : false,
|
||||
(isTurboEnabled) ? true : false,
|
||||
turboPattern,
|
||||
turboPatternLength);
|
||||
}
|
||||
|
||||
- (void) setTouchState:(BOOL)theState location:(const NSPoint)theLocation
|
||||
{
|
||||
OSSpinLockLock(&spinlockControllerState);
|
||||
clientInput[NDSInputID_Touch].isPressed = (theState) ? true : false;
|
||||
touchLocation = theLocation;
|
||||
OSSpinLockUnlock(&spinlockControllerState);
|
||||
execControl->SetClientTouchState((theState) ? true : false,
|
||||
(uint8_t)(theLocation.x + 0.3f),
|
||||
(uint8_t)(theLocation.y + 0.3f),
|
||||
(uint8_t)[self stylusPressure]);
|
||||
}
|
||||
|
||||
- (void) setSineWaveGeneratorFrequency:(const double)freq
|
||||
{
|
||||
sineWaveGenerator.setFrequency(freq);
|
||||
execControl->SetSineWaveFrequency(freq);
|
||||
}
|
||||
|
||||
- (void) clearAutohold
|
||||
{
|
||||
[self setAutohold:NO];
|
||||
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);
|
||||
execControl->ClearAutohold();
|
||||
}
|
||||
|
||||
- (void) reset
|
||||
{
|
||||
for (size_t i = 0; i < NDSInputID_InputCount; i++)
|
||||
{
|
||||
memset(clientInput, 0, sizeof(clientInput));
|
||||
}
|
||||
|
||||
[self setAutohold:NO];
|
||||
[self setMicLevel:0.0f];
|
||||
[self clearMicLevelMeasure];
|
||||
|
||||
_isAutoholdCleared = YES;
|
||||
_availableMicSamples = 0;
|
||||
_micLevelTotal = 0.0f;
|
||||
_micLevelsRead = 0.0f;
|
||||
}
|
||||
|
||||
- (void) clearMicLevelMeasure
|
||||
|
@ -549,7 +253,7 @@ SineWaveGenerator sineWaveGenerator(250.0, MIC_SAMPLE_RATE);
|
|||
|
||||
- (void) updateMicLevel
|
||||
{
|
||||
float avgMicLevel = _micLevelTotal / _micLevelsRead;
|
||||
float avgMicLevel = (_micLevelsRead != 0) ? _micLevelTotal / _micLevelsRead : 0.0f;
|
||||
|
||||
NSAutoreleasePool *tempPool = [[NSAutoreleasePool alloc] init];
|
||||
[self setMicLevel:avgMicLevel];
|
||||
|
@ -566,7 +270,7 @@ SineWaveGenerator sineWaveGenerator(250.0, MIC_SAMPLE_RATE);
|
|||
{
|
||||
uint8_t theSample = MIC_NULL_SAMPLE_VALUE;
|
||||
|
||||
if (_useHardwareMic && (caInput != NULL))
|
||||
if (!execControl->GetClientSoftwareMicStateApplied() && (caInput != NULL))
|
||||
{
|
||||
if (caInput->GetPauseState())
|
||||
{
|
||||
|
|
|
@ -148,12 +148,16 @@
|
|||
@property (assign) BOOL isHUDLagFrameCountVisible;
|
||||
@property (assign) BOOL isHUDCPULoadAverageVisible;
|
||||
@property (assign) BOOL isHUDRealTimeClockVisible;
|
||||
@property (assign) BOOL isHUDInputVisible;
|
||||
@property (assign) uint32_t hudColorVideoFPS;
|
||||
@property (assign) uint32_t hudColorRender3DFPS;
|
||||
@property (assign) uint32_t hudColorFrameIndex;
|
||||
@property (assign) uint32_t hudColorLagFrameCount;
|
||||
@property (assign) uint32_t hudColorCPULoadAverage;
|
||||
@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 displayTouchVideoSource;
|
||||
@property (assign) BOOL useVerticalSync;
|
||||
|
@ -168,5 +172,6 @@
|
|||
- (void) handleRedraw;
|
||||
|
||||
- (void) setScaleFactor:(float)theScaleFactor;
|
||||
- (void) hudUpdate;
|
||||
|
||||
@end
|
||||
|
|
|
@ -741,12 +741,16 @@
|
|||
@dynamic isHUDLagFrameCountVisible;
|
||||
@dynamic isHUDCPULoadAverageVisible;
|
||||
@dynamic isHUDRealTimeClockVisible;
|
||||
@dynamic isHUDInputVisible;
|
||||
@dynamic hudColorVideoFPS;
|
||||
@dynamic hudColorRender3DFPS;
|
||||
@dynamic hudColorFrameIndex;
|
||||
@dynamic hudColorLagFrameCount;
|
||||
@dynamic hudColorCPULoadAverage;
|
||||
@dynamic hudColorRTC;
|
||||
@dynamic hudColorInputPendingAndApplied;
|
||||
@dynamic hudColorInputAppliedOnly;
|
||||
@dynamic hudColorInputPendingOnly;
|
||||
@dynamic useVerticalSync;
|
||||
@dynamic videoFiltersPreferGPU;
|
||||
@dynamic sourceDeposterize;
|
||||
|
@ -901,6 +905,22 @@
|
|||
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
|
||||
{
|
||||
OSSpinLockLock(&spinlockIsHUDVisible);
|
||||
|
@ -997,6 +1017,54 @@
|
|||
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
|
||||
{
|
||||
OSSpinLockLock(&spinlockDisplayVideoSource);
|
||||
|
@ -1136,16 +1204,7 @@
|
|||
- (void) handleEmuFrameProcessed
|
||||
{
|
||||
[super handleEmuFrameProcessed];
|
||||
|
||||
OSSpinLockLock(&spinlockReceivedFrameIndex);
|
||||
ClientFrameInfo clientFrameInfo;
|
||||
clientFrameInfo.videoFPS = _receivedFrameCount;
|
||||
OSSpinLockUnlock(&spinlockReceivedFrameIndex);
|
||||
|
||||
OSSpinLockLock(&spinlockNDSFrameInfo);
|
||||
_cdv->SetHUDInfo(clientFrameInfo, _ndsFrameInfo);
|
||||
OSSpinLockUnlock(&spinlockNDSFrameInfo);
|
||||
|
||||
[self hudUpdate];
|
||||
_cdv->HandleEmulatorFrameEndEvent();
|
||||
}
|
||||
|
||||
|
@ -1187,4 +1246,16 @@
|
|||
OSSpinLockUnlock(&spinlockIsHUDVisible);
|
||||
}
|
||||
|
||||
- (void) hudUpdate
|
||||
{
|
||||
OSSpinLockLock(&spinlockReceivedFrameIndex);
|
||||
ClientFrameInfo clientFrameInfo;
|
||||
clientFrameInfo.videoFPS = _receivedFrameCount;
|
||||
OSSpinLockUnlock(&spinlockReceivedFrameIndex);
|
||||
|
||||
OSSpinLockLock(&spinlockNDSFrameInfo);
|
||||
_cdv->SetHUDInfo(clientFrameInfo, _ndsFrameInfo);
|
||||
OSSpinLockUnlock(&spinlockNDSFrameInfo);
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -18,9 +18,11 @@
|
|||
#include "coreaudiosound.h"
|
||||
|
||||
#include <CoreAudio/CoreAudio.h>
|
||||
#include "cocoa_globals.h"
|
||||
#include "ClientExecutionControl.h"
|
||||
#include "utilities.h"
|
||||
|
||||
#import "cocoa_globals.h"
|
||||
|
||||
//#define FORCE_AUDIOCOMPONENT_10_5
|
||||
|
||||
CoreAudioInput::CoreAudioInput()
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
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 "../../emufile.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
|
||||
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
|
||||
cdsController = [[[[CocoaDSController alloc] init] retain] autorelease];
|
||||
[cdsController setMicMode:MICMODE_INTERNAL_NOISE];
|
||||
[cdsController setMicMode:MicrophoneMode_InternalNoise];
|
||||
|
||||
// Set up the cheat system
|
||||
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 isHUDCPULoadAverageVisible;
|
||||
@property (assign) BOOL isHUDRealTimeClockVisible;
|
||||
@property (assign) BOOL isHUDInputVisible;
|
||||
@property (assign) NSColor *hudColorVideoFPS;
|
||||
@property (assign) NSColor *hudColorRender3DFPS;
|
||||
@property (assign) NSColor *hudColorFrameIndex;
|
||||
@property (assign) NSColor *hudColorLagFrameCount;
|
||||
@property (assign) NSColor *hudColorCPULoadAverage;
|
||||
@property (assign) NSColor *hudColorRTC;
|
||||
@property (assign) NSColor *hudColorInputPendingAndApplied;
|
||||
@property (assign) NSColor *hudColorInputAppliedOnly;
|
||||
@property (assign) NSColor *hudColorInputPendingOnly;
|
||||
@property (assign) NSInteger displayMainVideoSource;
|
||||
@property (assign) NSInteger displayTouchVideoSource;
|
||||
@property (assign) BOOL useVerticalSync;
|
||||
|
@ -206,9 +210,9 @@ class OGLVideoOutput;
|
|||
- (IBAction) toggleShowHUDRender3DFPS:(id)sender;
|
||||
- (IBAction) toggleShowHUDFrameIndex:(id)sender;
|
||||
- (IBAction) toggleShowHUDLagFrameCount:(id)sender;
|
||||
- (IBAction) toggleShowHUDInput:(id)sender;
|
||||
- (IBAction) toggleShowHUDCPULoadAverage:(id)sender;
|
||||
- (IBAction) toggleShowHUDRealTimeClock:(id)sender;
|
||||
- (IBAction) toggleShowHUDInput:(id)sender;
|
||||
- (IBAction) toggleNDSDisplays:(id)sender;
|
||||
- (IBAction) toggleKeepMinDisplaySizeAtNormal:(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] setIsHUDCPULoadAverageVisible:[[NSUserDefaults standardUserDefaults] boolForKey:@"HUD_ShowCPULoadAverage"]];
|
||||
[[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] 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]];
|
||||
}
|
||||
|
||||
- (IBAction) toggleShowHUDInput:(id)sender
|
||||
{
|
||||
//[[self view] setIsHUDInputVisible:![[self view] isHUDInputVisible]];
|
||||
}
|
||||
|
||||
- (IBAction) toggleShowHUDCPULoadAverage:(id)sender
|
||||
{
|
||||
[[self view] setIsHUDCPULoadAverageVisible:![[self view] isHUDCPULoadAverageVisible]];
|
||||
|
@ -846,6 +840,11 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
|
|||
[[self view] setIsHUDRealTimeClockVisible:![[self view] isHUDRealTimeClockVisible]];
|
||||
}
|
||||
|
||||
- (IBAction) toggleShowHUDInput:(id)sender
|
||||
{
|
||||
[[self view] setIsHUDInputVisible:![[self view] isHUDInputVisible]];
|
||||
}
|
||||
|
||||
- (IBAction) toggleKeepMinDisplaySizeAtNormal:(id)sender
|
||||
{
|
||||
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] isHUDCPULoadAverageVisible] forKey:@"HUD_ShowCPULoadAverage"];
|
||||
[[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] 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] hudColorCPULoadAverage]] forKey:@"HUD_Color_CPULoadAverage"];
|
||||
[[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];
|
||||
}
|
||||
|
@ -1296,6 +1297,13 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
|
|||
[(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:))
|
||||
{
|
||||
if ([(id)theItem isMemberOfClass:[NSMenuItem class]])
|
||||
|
@ -1682,12 +1690,16 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
|
|||
@dynamic isHUDLagFrameCountVisible;
|
||||
@dynamic isHUDCPULoadAverageVisible;
|
||||
@dynamic isHUDRealTimeClockVisible;
|
||||
@dynamic isHUDInputVisible;
|
||||
@dynamic hudColorVideoFPS;
|
||||
@dynamic hudColorRender3DFPS;
|
||||
@dynamic hudColorFrameIndex;
|
||||
@dynamic hudColorLagFrameCount;
|
||||
@dynamic hudColorCPULoadAverage;
|
||||
@dynamic hudColorRTC;
|
||||
@dynamic hudColorInputPendingAndApplied;
|
||||
@dynamic hudColorInputAppliedOnly;
|
||||
@dynamic hudColorInputPendingOnly;
|
||||
@dynamic displayMainVideoSource;
|
||||
@dynamic displayTouchVideoSource;
|
||||
@dynamic useVerticalSync;
|
||||
|
@ -1821,6 +1833,16 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
|
|||
return [[self cdsVideoOutput] isHUDRealTimeClockVisible];
|
||||
}
|
||||
|
||||
- (void) setIsHUDInputVisible:(BOOL)theState
|
||||
{
|
||||
[[self cdsVideoOutput] setIsHUDInputVisible:theState];
|
||||
}
|
||||
|
||||
- (BOOL) isHUDInputVisible
|
||||
{
|
||||
return [[self cdsVideoOutput] isHUDInputVisible];
|
||||
}
|
||||
|
||||
- (void) setHudColorVideoFPS:(NSColor *)theColor
|
||||
{
|
||||
[[self cdsVideoOutput] setHudColorVideoFPS:[CocoaDSUtil RGBA8888FromNSColor:theColor]];
|
||||
|
@ -1881,6 +1903,36 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
|
|||
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
|
||||
{
|
||||
[[self cdsVideoOutput] setDisplayMainVideoSource:displaySourceID];
|
||||
|
|
|
@ -1041,6 +1041,17 @@
|
|||
|
||||
CocoaDSCore *cdsCore = (CocoaDSCore *)[cdsCoreController content];
|
||||
[[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
|
||||
|
@ -1055,6 +1066,17 @@
|
|||
|
||||
CocoaDSCore *cdsCore = (CocoaDSCore *)[cdsCoreController content];
|
||||
[[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
|
||||
|
@ -1068,6 +1090,17 @@
|
|||
{
|
||||
CocoaDSCore *cdsCore = (CocoaDSCore *)[cdsCoreController content];
|
||||
[[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];
|
||||
|
||||
const NSInteger micMode = cmdAttr.intValue[1];
|
||||
[cdsController setSoftwareMicState:theState];
|
||||
[cdsController setSoftwareMicMode:micMode];
|
||||
[cdsController setSoftwareMicState:theState mode:micMode];
|
||||
|
||||
const float sineWaveFrequency = cmdAttr.floatValue[0];
|
||||
[cdsController setSineWaveGeneratorFrequency:sineWaveFrequency];
|
||||
|
|
|
@ -1141,7 +1141,7 @@ static std::unordered_map<unsigned short, std::string> keyboardNameTable; // Key
|
|||
cmdDSControlTouch.useInputForIntCoord = true;
|
||||
|
||||
CommandAttributes cmdDSControlMic = NewCommandAttributesForDSControl("Microphone", NDSInputID_Microphone);
|
||||
cmdDSControlMic.intValue[1] = MICMODE_INTERNAL_NOISE;
|
||||
cmdDSControlMic.intValue[1] = MicrophoneMode_InternalNoise;
|
||||
cmdDSControlMic.floatValue[0] = 250.0f;
|
||||
|
||||
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)
|
||||
{
|
||||
const NSInteger micMode = [(NSNumber *)[deviceInfo valueForKey:@"intValue1"] integerValue];
|
||||
const MicrophoneMode micMode = (MicrophoneMode)[(NSNumber *)[deviceInfo valueForKey:@"intValue1"] integerValue];
|
||||
switch (micMode)
|
||||
{
|
||||
case MICMODE_NONE:
|
||||
case MicrophoneMode_None:
|
||||
inputSummary = NSSTRING_INPUTPREF_MIC_NONE;
|
||||
break;
|
||||
|
||||
case MICMODE_INTERNAL_NOISE:
|
||||
case MicrophoneMode_InternalNoise:
|
||||
inputSummary = NSSTRING_INPUTPREF_MIC_INTERNAL_NOISE;
|
||||
break;
|
||||
|
||||
case MICMODE_AUDIO_FILE:
|
||||
case MicrophoneMode_AudioFile:
|
||||
inputSummary = (NSString *)[deviceInfo valueForKey:@"object1"];
|
||||
if (inputSummary == nil)
|
||||
{
|
||||
|
@ -1704,15 +1704,15 @@ static std::unordered_map<unsigned short, std::string> keyboardNameTable; // Key
|
|||
}
|
||||
break;
|
||||
|
||||
case MICMODE_WHITE_NOISE:
|
||||
case MicrophoneMode_WhiteNoise:
|
||||
inputSummary = NSSTRING_INPUTPREF_MIC_WHITE_NOISE;
|
||||
break;
|
||||
|
||||
case MICMODE_SINE_WAVE:
|
||||
case MicrophoneMode_SineWave:
|
||||
inputSummary = [NSString stringWithFormat:NSSTRING_INPUTPREF_MIC_SINE_WAVE, [(NSNumber *)[deviceInfo valueForKey:@"floatValue0"] floatValue]];
|
||||
break;
|
||||
|
||||
case MICMODE_PHYSICAL:
|
||||
case MicrophoneMode_Physical:
|
||||
inputSummary = @"Physical:";
|
||||
break;
|
||||
|
||||
|
|
|
@ -117,16 +117,18 @@
|
|||
[[[hudPipelineDesc colorAttachments] objectAtIndexedSubscript:0] setSourceAlphaBlendFactor:MTLBlendFactorSourceAlpha];
|
||||
[[[hudPipelineDesc colorAttachments] objectAtIndexedSubscript:0] setDestinationRGBBlendFactor: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];
|
||||
|
||||
[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];
|
||||
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+1] = k+1;
|
||||
|
@ -136,7 +138,7 @@
|
|||
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][1] = nil;
|
||||
|
@ -1451,18 +1453,27 @@
|
|||
{
|
||||
NSAutoreleasePool *renderAutoreleasePool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
dispatch_semaphore_wait(availableResources, DISPATCH_TIME_FOREVER);
|
||||
|
||||
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];
|
||||
if (texture == nil)
|
||||
{
|
||||
dispatch_semaphore_signal(availableResources);
|
||||
[renderAutoreleasePool release];
|
||||
return;
|
||||
}
|
||||
|
||||
const NDSDisplayInfo &displayInfo = _cdv->GetEmuDisplayInfo();
|
||||
|
||||
dispatch_semaphore_wait(availableResources, DISPATCH_TIME_FOREVER);
|
||||
|
||||
[[self colorAttachment0Desc] setTexture:texture];
|
||||
|
||||
id<MTLCommandBuffer> cb = [[sharedData commandQueue] commandBufferWithUnretainedReferences];
|
||||
|
@ -1586,7 +1597,43 @@
|
|||
}
|
||||
|
||||
// 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->HUDNeedsUpdate())
|
||||
|
@ -1603,6 +1650,8 @@
|
|||
_cdv->ClearHUDNeedsUpdate();
|
||||
}
|
||||
|
||||
uint8_t isScreenOverlay = 0;
|
||||
|
||||
[ce setRenderPipelineState:[sharedData hudPipeline]];
|
||||
[ce setVertexBuffer:_hudVtxPositionBuffer offset:0 atIndex:0];
|
||||
[ce setVertexBuffer:_hudVtxColorBuffer offset:0 atIndex:1];
|
||||
|
@ -1610,7 +1659,30 @@
|
|||
[ce setVertexBuffer:_cdvPropertiesBuffer offset:0 atIndex:3];
|
||||
[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 drawIndexedPrimitives:MTLPrimitiveTypeTriangle
|
||||
indexCount:6
|
||||
|
@ -1618,10 +1690,10 @@
|
|||
indexBuffer:[sharedData hudIndexBuffer]
|
||||
indexBufferOffset:0];
|
||||
|
||||
// Next, draw each character inside the box.
|
||||
// Finally, draw each character inside the box.
|
||||
[ce setFragmentSamplerState:[sharedData samplerHUDText] atIndex:0];
|
||||
[ce drawIndexedPrimitives:MTLPrimitiveTypeTriangle
|
||||
indexCount:(hudLength - 1) * 6
|
||||
indexCount:(_cdv->GetHUDString().length() - 1) * 6
|
||||
indexType:MTLIndexTypeUInt16
|
||||
indexBuffer:[sharedData hudIndexBuffer]
|
||||
indexBufferOffset:6 * sizeof(uint16_t)];
|
||||
|
|
|
@ -25,7 +25,6 @@ struct HUDVtx
|
|||
float4 position [[position]];
|
||||
float4 color;
|
||||
float2 texCoord;
|
||||
bool isBox;
|
||||
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 float2 *inTexCoord [[buffer(2)]],
|
||||
const constant DisplayViewShaderProperties &viewProps [[buffer(3)]],
|
||||
const constant uint8_t &isScreenOverlay [[buffer(4)]],
|
||||
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),
|
||||
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;
|
||||
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.texCoord = inTexCoord[vid];
|
||||
outVtx.isBox = (vid < 4);
|
||||
outVtx.lowerHUDMipMapLevel = (viewProps.lowerHUDMipMapLevel == 1);
|
||||
|
||||
return outVtx;
|
||||
|
|
|
@ -194,6 +194,7 @@
|
|||
CocoaDSController *newController = [[[CocoaDSController alloc] init] autorelease];
|
||||
[newCore setCdsController:newController];
|
||||
[newController setDelegate:emuControl];
|
||||
[newController setExecControl:[newCore execControl]];
|
||||
[newController setHardwareMicEnabled:YES];
|
||||
|
||||
// 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 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"];
|
||||
// TODO: Show HUD Input.
|
||||
//const BOOL hudShowInput = [(NSNumber *)[windowProperties valueForKey:@"hudShowInput"] boolValue];
|
||||
const BOOL hudShowInput = ([windowProperties objectForKey:@"hudShowInput"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudShowInput"] boolValue] : [[NSUserDefaults standardUserDefaults] boolForKey:@"HUD_ShowInput"];
|
||||
|
||||
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"];
|
||||
|
@ -616,6 +616,9 @@
|
|||
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 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 BOOL useVerticalSync = ([windowProperties objectForKey:@"useVerticalSync"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"useVerticalSync"] boolValue] : YES;
|
||||
|
@ -661,6 +664,7 @@
|
|||
[[windowController view] setIsHUDLagFrameCountVisible:hudShowLagFrameCount];
|
||||
[[windowController view] setIsHUDCPULoadAverageVisible:hudShowCPULoadAverage];
|
||||
[[windowController view] setIsHUDRealTimeClockVisible:hudShowRTC];
|
||||
[[windowController view] setIsHUDInputVisible:hudShowInput];
|
||||
|
||||
[[windowController view] setHudColorVideoFPS:[CocoaDSUtil NSColorFromRGBA8888:(uint32_t)hudColorVideoFPS]];
|
||||
[[windowController view] setHudColorRender3DFPS:[CocoaDSUtil NSColorFromRGBA8888:(uint32_t)hudColorRender3DFPS]];
|
||||
|
@ -668,6 +672,9 @@
|
|||
[[windowController view] setHudColorLagFrameCount:[CocoaDSUtil NSColorFromRGBA8888:(uint32_t)hudColorLagFrameCount]];
|
||||
[[windowController view] setHudColorCPULoadAverage:[CocoaDSUtil NSColorFromRGBA8888:(uint32_t)hudColorCPULoadAverage]];
|
||||
[[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)];
|
||||
|
||||
|
@ -740,12 +747,16 @@
|
|||
[NSNumber numberWithBool:[[windowController view] isHUDLagFrameCountVisible]], @"hudShowLagFrameCount",
|
||||
[NSNumber numberWithBool:[[windowController view] isHUDCPULoadAverageVisible]], @"hudShowCPULoadAverage",
|
||||
[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] hudColorRender3DFPS]]], @"hudColorRender3DFPS",
|
||||
[NSNumber numberWithUnsignedInteger:[CocoaDSUtil RGBA8888FromNSColor:[[windowController view] hudColorFrameIndex]]], @"hudColorFrameIndex",
|
||||
[NSNumber numberWithUnsignedInteger:[CocoaDSUtil RGBA8888FromNSColor:[[windowController view] hudColorLagFrameCount]]], @"hudColorLagFrameCount",
|
||||
[NSNumber numberWithUnsignedInteger:[CocoaDSUtil RGBA8888FromNSColor:[[windowController view] hudColorCPULoadAverage]]], @"hudColorCPULoadAverage",
|
||||
[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 masterStatusBarState]], @"isShowingStatusBar",
|
||||
[NSNumber numberWithBool:[windowController isFullScreen]], @"isInFullScreenMode",
|
||||
|
|
Loading…
Reference in New Issue