mirror of
https://github.com/libretro/Mesen.git
synced 2024-11-24 09:39:44 +00:00
255 lines
11 KiB
C++
255 lines
11 KiB
C++
#include "stdafx.h"
|
|
#include "VideoHud.h"
|
|
#include "ControlManager.h"
|
|
#include "BaseControlDevice.h"
|
|
#include "ControlDeviceState.h"
|
|
#include "StandardController.h"
|
|
#include "FourScore.h"
|
|
#include "Zapper.h"
|
|
#include "MovieManager.h"
|
|
#include "Console.h"
|
|
|
|
void VideoHud::DrawHud(shared_ptr<Console> console, uint32_t *outputBuffer, FrameInfo frameInfo, OverscanDimensions overscan)
|
|
{
|
|
uint32_t displayCount = 0;
|
|
InputDisplaySettings settings = console->GetSettings()->GetInputDisplaySettings();
|
|
|
|
vector<ControlDeviceState> states = console->GetControlManager()->GetPortStates();
|
|
for(int inputPort = 0; inputPort < 4; inputPort++) {
|
|
if((settings.VisiblePorts >> inputPort) & 0x01) {
|
|
if(DisplayControllerInput(console, states[inputPort], inputPort, outputBuffer, frameInfo, overscan, displayCount)) {
|
|
displayCount++;
|
|
}
|
|
}
|
|
}
|
|
|
|
DrawMovieIcons(console, outputBuffer, frameInfo, overscan);
|
|
}
|
|
|
|
bool VideoHud::DisplayControllerInput(shared_ptr<Console> console, ControlDeviceState &state, int inputPort, uint32_t *outputBuffer, FrameInfo &frameInfo, OverscanDimensions &overscan, uint32_t displayIndex)
|
|
{
|
|
bool axisInverted = (console->GetSettings()->GetScreenRotation() % 180) != 0;
|
|
int scale = frameInfo.Width / (axisInverted ? overscan.GetScreenHeight() : overscan.GetScreenWidth());
|
|
uint32_t* rgbaBuffer = outputBuffer;
|
|
|
|
InputDisplaySettings settings = console->GetSettings()->GetInputDisplaySettings();
|
|
uint32_t yStart, xStart;
|
|
switch(settings.DisplayPosition) {
|
|
case InputDisplayPosition::TopLeft:
|
|
xStart = 3 * scale + (settings.DisplayHorizontally ? displayIndex * 40 * scale : 0);
|
|
yStart = 5 * scale + (settings.DisplayHorizontally ? 0 : displayIndex * 14 * scale);
|
|
break;
|
|
case InputDisplayPosition::TopRight:
|
|
xStart = frameInfo.Width - 40 * scale - (settings.DisplayHorizontally ? displayIndex * 40 * scale : 0);
|
|
yStart = 5 * scale + (settings.DisplayHorizontally ? 0 : displayIndex * 14 * scale);
|
|
break;
|
|
case InputDisplayPosition::BottomLeft:
|
|
xStart = 3 * scale + (settings.DisplayHorizontally ? displayIndex * 40 * scale : 0);
|
|
yStart = frameInfo.Height - 15 * scale - (settings.DisplayHorizontally ? 0 : displayIndex * 14 * scale);
|
|
break;
|
|
default:
|
|
case InputDisplayPosition::BottomRight:
|
|
xStart = frameInfo.Width - 40 * scale - (settings.DisplayHorizontally ? displayIndex * 40 * scale : 0);
|
|
yStart = frameInfo.Height - 15 * scale - (settings.DisplayHorizontally ? 0 : displayIndex * 14 * scale);
|
|
break;
|
|
}
|
|
|
|
int32_t buttonState = -1;
|
|
|
|
shared_ptr<BaseControlDevice> device = ControlManager::CreateControllerDevice(console->GetSettings()->GetControllerType(inputPort), 0, console);
|
|
if(!device) {
|
|
return false;
|
|
}
|
|
|
|
device->SetRawState(state);
|
|
|
|
shared_ptr<StandardController> controller = std::dynamic_pointer_cast<StandardController>(device);
|
|
if(controller) {
|
|
buttonState = controller->ToByte();
|
|
}
|
|
|
|
if(buttonState >= 0) {
|
|
for(int y = 0; y < 13 * scale; y++) {
|
|
for(int x = 0; x < 38 * scale; x++) {
|
|
uint32_t bufferPos = (yStart + y)*frameInfo.Width + (xStart + x);
|
|
uint32_t gridValue = _gamePads[inputPort][y / scale * 38 + x / scale];
|
|
if(gridValue > 0) {
|
|
if((buttonState >> (gridValue - 1)) & 0x01) {
|
|
BlendColors(rgbaBuffer + bufferPos, 0xEFFFFFFF);
|
|
} else {
|
|
BlendColors(rgbaBuffer + bufferPos, 0xEF111111);
|
|
}
|
|
} else {
|
|
BlendColors(rgbaBuffer + bufferPos, 0xBFAAAAAA);
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
shared_ptr<Zapper> zapper = std::dynamic_pointer_cast<Zapper>(device);
|
|
if(zapper) {
|
|
MousePosition pos = zapper->GetCoordinates();
|
|
if(pos.X != -1 && pos.Y != -1) {
|
|
for(int i = -1; i <= 1; i++) {
|
|
int y = (pos.Y - overscan.Top) * scale + i;
|
|
if(y < 0 || y >(int)frameInfo.Height) continue;
|
|
|
|
for(int j = -1; j <= 1; j++) {
|
|
int x = (pos.X - overscan.Left) * scale + j;
|
|
if(x < 0 || x > (int)frameInfo.Width) continue;
|
|
|
|
uint32_t bufferPos = y*frameInfo.Width + x;
|
|
BlendColors(rgbaBuffer + bufferPos, 0xFFFF0000);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void VideoHud::DrawMovieIcons(shared_ptr<Console> console, uint32_t *outputBuffer, FrameInfo &frameInfo, OverscanDimensions &overscan)
|
|
{
|
|
if(console->GetSettings()->CheckFlag(EmulationFlags::DisplayMovieIcons) && (MovieManager::Playing() || MovieManager::Recording())) {
|
|
InputDisplaySettings settings = console->GetSettings()->GetInputDisplaySettings();
|
|
uint32_t xOffset = settings.VisiblePorts > 0 && settings.DisplayPosition == InputDisplayPosition::TopRight ? 50 : 27;
|
|
uint32_t* rgbaBuffer = (uint32_t*)outputBuffer;
|
|
int scale = frameInfo.Width / overscan.GetScreenWidth();
|
|
uint32_t yStart = 15 * scale;
|
|
uint32_t xStart = (frameInfo.Width - xOffset) * scale;
|
|
if(MovieManager::Playing()) {
|
|
for(int y = 0; y < 12 * scale; y++) {
|
|
for(int x = 0; x < 12 * scale; x++) {
|
|
uint32_t bufferPos = (yStart + y)*frameInfo.Width + (xStart + x);
|
|
uint32_t gridValue = _playIcon[y / scale * 12 + x / scale];
|
|
if(gridValue == 1) {
|
|
BlendColors(rgbaBuffer + bufferPos, 0xEF00CF00);
|
|
} else if(gridValue == 2) {
|
|
BlendColors(rgbaBuffer + bufferPos, 0xEF009F00);
|
|
} else if(gridValue == 3) {
|
|
BlendColors(rgbaBuffer + bufferPos, 0xEF000000);
|
|
}
|
|
}
|
|
}
|
|
} else if(MovieManager::Recording()) {
|
|
for(int y = 0; y < 12 * scale; y++) {
|
|
for(int x = 0; x < 12 * scale; x++) {
|
|
uint32_t bufferPos = (yStart + y)*frameInfo.Width + (xStart + x);
|
|
uint32_t gridValue = _recordIcon[y / scale * 12 + x / scale];
|
|
if(gridValue == 1) {
|
|
BlendColors(rgbaBuffer + bufferPos, 0xEFCF0000);
|
|
} else if(gridValue == 2) {
|
|
BlendColors(rgbaBuffer + bufferPos, 0xEF9F0000);
|
|
} else if(gridValue == 3) {
|
|
BlendColors(rgbaBuffer + bufferPos, 0xEF000000);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void VideoHud::BlendColors(uint32_t* output, uint32_t input)
|
|
{
|
|
uint8_t inA = (input >> 24) & 0xFF;
|
|
uint8_t inR = (input >> 16) & 0xFF;
|
|
uint8_t inG = (input >> 8) & 0xFF;
|
|
uint8_t inB = input & 0xFF;
|
|
|
|
uint8_t invertedAlpha = 255 - inA;
|
|
uint8_t outB = (uint8_t)((inA * inB + invertedAlpha * (*output & 0xFF)) >> 8);
|
|
uint8_t outG = (uint8_t)((inA * inG + invertedAlpha * ((*output >> 8) & 0xFF)) >> 8);
|
|
uint8_t outR = (uint8_t)((inA * inR + invertedAlpha * ((*output >> 16) & 0xFF)) >> 8);
|
|
*output = 0xFF000000 | (outR << 16) | (outG << 8) | outB;
|
|
}
|
|
|
|
const vector<uint32_t> VideoHud::_playIcon = {
|
|
3,3,3,0,0,0,0,0,0,0,0,0,
|
|
3,1,1,3,3,0,0,0,0,0,0,0,
|
|
3,1,2,1,1,3,3,0,0,0,0,0,
|
|
3,1,2,2,2,1,1,3,3,0,0,0,
|
|
3,1,2,2,2,2,2,1,1,3,0,0,
|
|
3,1,2,2,2,2,2,2,2,1,3,0,
|
|
3,1,2,2,2,2,2,2,2,1,3,0,
|
|
3,1,2,2,2,2,2,1,1,3,0,0,
|
|
3,1,2,2,2,1,1,3,3,0,0,0,
|
|
3,1,2,1,1,3,3,0,0,0,0,0,
|
|
3,1,1,3,3,0,0,0,0,0,0,0,
|
|
3,3,3,0,0,0,0,0,0,0,0,0,
|
|
};
|
|
|
|
const vector<uint32_t> VideoHud::_recordIcon = {
|
|
0,0,0,0,0,0,0,0,0,0,0,0,
|
|
0,0,0,0,0,3,3,0,0,0,0,0,
|
|
0,0,0,3,3,1,1,3,3,0,0,0,
|
|
0,0,3,1,1,2,2,1,1,3,0,0,
|
|
0,0,3,1,2,2,2,2,1,3,0,0,
|
|
0,3,1,2,2,2,2,2,2,1,3,0,
|
|
0,3,1,2,2,2,2,2,2,1,3,0,
|
|
0,0,3,1,2,2,2,2,1,3,0,0,
|
|
0,0,3,1,1,2,2,1,1,3,0,0,
|
|
0,0,0,3,3,1,1,3,3,0,0,0,
|
|
0,0,0,0,0,3,3,0,0,0,0,0,
|
|
0,0,0,0,0,0,0,0,0,0,0,0,
|
|
};
|
|
|
|
const vector<uint32_t> VideoHud::_gamePads[4] = {
|
|
{ 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
|
|
9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,
|
|
9,0,0,0,0,5,5,5,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,
|
|
9,0,0,0,0,5,5,5,0,0,0,0,0,0,0,0,0,9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,
|
|
9,0,0,0,0,5,5,5,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,
|
|
9,0,7,7,7,9,9,9,8,8,8,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,
|
|
9,0,7,7,7,9,9,9,8,8,8,0,0,0,0,0,0,9,9,9,0,0,0,0,0,0,0,2,2,0,0,0,0,1,1,0,0,9,
|
|
9,0,7,7,7,9,9,9,8,8,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,0,0,1,1,1,1,0,9,
|
|
9,0,0,0,0,6,6,6,0,0,0,0,0,0,3,3,3,3,0,4,4,4,4,0,0,0,2,2,2,2,0,0,1,1,1,1,0,9,
|
|
9,0,0,0,0,6,6,6,0,0,0,0,0,0,3,3,3,3,0,4,4,4,4,0,0,0,0,2,2,0,0,0,0,1,1,0,0,9,
|
|
9,0,0,0,0,6,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,
|
|
9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,
|
|
9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9 },
|
|
|
|
{ 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
|
|
9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,
|
|
9,0,0,0,0,5,5,5,0,0,0,0,0,0,0,0,0,9,9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,
|
|
9,0,0,0,0,5,5,5,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,
|
|
9,0,0,0,0,5,5,5,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,
|
|
9,0,7,7,7,9,9,9,8,8,8,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,
|
|
9,0,7,7,7,9,9,9,8,8,8,0,0,0,0,0,0,9,9,9,0,0,0,0,0,0,0,2,2,0,0,0,0,1,1,0,0,9,
|
|
9,0,7,7,7,9,9,9,8,8,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,0,0,1,1,1,1,0,9,
|
|
9,0,0,0,0,6,6,6,0,0,0,0,0,0,3,3,3,3,0,4,4,4,4,0,0,0,2,2,2,2,0,0,1,1,1,1,0,9,
|
|
9,0,0,0,0,6,6,6,0,0,0,0,0,0,3,3,3,3,0,4,4,4,4,0,0,0,0,2,2,0,0,0,0,1,1,0,0,9,
|
|
9,0,0,0,0,6,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,
|
|
9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,
|
|
9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9 },
|
|
|
|
{ 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
|
|
9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,
|
|
9,0,0,0,0,5,5,5,0,0,0,0,0,0,0,0,0,9,9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,
|
|
9,0,0,0,0,5,5,5,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,
|
|
9,0,0,0,0,5,5,5,0,0,0,0,0,0,0,0,0,0,9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,
|
|
9,0,7,7,7,9,9,9,8,8,8,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,
|
|
9,0,7,7,7,9,9,9,8,8,8,0,0,0,0,0,0,9,9,9,0,0,0,0,0,0,0,2,2,0,0,0,0,1,1,0,0,9,
|
|
9,0,7,7,7,9,9,9,8,8,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,0,0,1,1,1,1,0,9,
|
|
9,0,0,0,0,6,6,6,0,0,0,0,0,0,3,3,3,3,0,4,4,4,4,0,0,0,2,2,2,2,0,0,1,1,1,1,0,9,
|
|
9,0,0,0,0,6,6,6,0,0,0,0,0,0,3,3,3,3,0,4,4,4,4,0,0,0,0,2,2,0,0,0,0,1,1,0,0,9,
|
|
9,0,0,0,0,6,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,
|
|
9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,
|
|
9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9 },
|
|
|
|
{ 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
|
|
9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,
|
|
9,0,0,0,0,5,5,5,0,0,0,0,0,0,0,0,0,9,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,
|
|
9,0,0,0,0,5,5,5,0,0,0,0,0,0,0,0,0,9,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,
|
|
9,0,0,0,0,5,5,5,0,0,0,0,0,0,0,0,0,9,9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,
|
|
9,0,7,7,7,9,9,9,8,8,8,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,
|
|
9,0,7,7,7,9,9,9,8,8,8,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,2,2,0,0,0,0,1,1,0,0,9,
|
|
9,0,7,7,7,9,9,9,8,8,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,0,0,1,1,1,1,0,9,
|
|
9,0,0,0,0,6,6,6,0,0,0,0,0,0,3,3,3,3,0,4,4,4,4,0,0,0,2,2,2,2,0,0,1,1,1,1,0,9,
|
|
9,0,0,0,0,6,6,6,0,0,0,0,0,0,3,3,3,3,0,4,4,4,4,0,0,0,0,2,2,0,0,0,0,1,1,0,0,9,
|
|
9,0,0,0,0,6,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,
|
|
9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,
|
|
9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9 }
|
|
};
|
|
|