RomInfoWidget auto detects controllers and displays results

This commit is contained in:
thrust26 2019-02-15 22:19:19 +01:00
parent ccee7e4dc6
commit 9fba356d8b
7 changed files with 72 additions and 37 deletions

View File

@ -562,7 +562,6 @@ void Console::changePhosphor(int direction)
{ {
int blend = atoi(myProperties.get(Display_PPBlend).c_str()); int blend = atoi(myProperties.get(Display_PPBlend).c_str());
if(direction == +1) // increase blend if(direction == +1) // increase blend
{ {
if(blend >= 100) if(blend >= 100)
@ -848,19 +847,24 @@ void Console::setControllers(const string& rommd5)
string right = myProperties.get(Controller_Right); string right = myProperties.get(Controller_Right);
uInt32 size = 0; uInt32 size = 0;
const uInt8* image = myCart->getImage(size); const uInt8* image = myCart->getImage(size);
const bool swappedPorts = myProperties.get(Console_SwapPorts) != "NO";
// try to detect controllers // try to detect controllers
if(image != nullptr || size != 0) if(image != nullptr || size != 0)
{ {
left = ControllerDetector::detect(image, size, left, Controller::Left, myOSystem.settings()); left = ControllerDetector::detect(image, size, left,
right = ControllerDetector::detect(image, size, right, Controller::Right, myOSystem.settings()); !swappedPorts ? Controller::Left : Controller::Right,
myOSystem.settings());
right = ControllerDetector::detect(image, size, right,
!swappedPorts ? Controller::Right : Controller::Left,
myOSystem.settings());
} }
unique_ptr<Controller> leftC = getControllerPort(rommd5, left, Controller::Left), unique_ptr<Controller> leftC = getControllerPort(rommd5, left, Controller::Left),
rightC = getControllerPort(rommd5, right, Controller::Right); rightC = getControllerPort(rommd5, right, Controller::Right);
// Swap the ports if necessary // Swap the ports if necessary
if(myProperties.get(Console_SwapPorts) == "NO") if(!swappedPorts)
{ {
myLeftControl = std::move(leftC); myLeftControl = std::move(leftC);
myRightControl = std::move(rightC); myRightControl = std::move(rightC);

View File

@ -393,7 +393,7 @@ bool ControllerDetector::usesPaddle(const uInt8* image, uInt32 size,
if(port == Controller::Left) if(port == Controller::Left)
{ {
// check for INPT0 access // check for INPT0 access
const int NUM_SIGS_0 = 13; const int NUM_SIGS_0 = 12;
const int SIG_SIZE_0 = 3; const int SIG_SIZE_0 = 3;
uInt8 signature_0[NUM_SIGS_0][SIG_SIZE_0] = { uInt8 signature_0[NUM_SIGS_0][SIG_SIZE_0] = {
//{ 0x24, 0x08, 0x10 }, // bit INPT0; bpl (many joystick games too!) //{ 0x24, 0x08, 0x10 }, // bit INPT0; bpl (many joystick games too!)
@ -409,7 +409,6 @@ bool ControllerDetector::usesPaddle(const uInt8* image, uInt32 size,
{ 0xb5, 0x38, 0x10 }, // lda INPT0|$30,x; bpl (Circus Atari, old code!) { 0xb5, 0x38, 0x10 }, // lda INPT0|$30,x; bpl (Circus Atari, old code!)
{ 0xb5, 0x38, 0x30 }, // lda INPT0|$30,x; bmi (no joystick games) { 0xb5, 0x38, 0x30 }, // lda INPT0|$30,x; bmi (no joystick games)
{ 0x68, 0x48, 0x10 }, // pla; pha; bpl (i.a. Bachelor Party) { 0x68, 0x48, 0x10 }, // pla; pha; bpl (i.a. Bachelor Party)
{ 0xa5, 0x3b, 0x30 }, // lda INPT3|$30; bmi (only Tac Scan, ports and paddles swapped)
{ 0xa5, 0x08, 0x4c }, // lda INPT0; jmp (only Backgammon) { 0xa5, 0x08, 0x4c }, // lda INPT0; jmp (only Backgammon)
{ 0xa4, 0x38, 0x30 }, // ldy INPT0; bmi (no joystick games) { 0xa4, 0x38, 0x30 }, // ldy INPT0; bmi (no joystick games)
}; };
@ -444,7 +443,7 @@ bool ControllerDetector::usesPaddle(const uInt8* image, uInt32 size,
else if(port == Controller::Right) else if(port == Controller::Right)
{ {
// check for INPT2 and indexed INPT0 access // check for INPT2 and indexed INPT0 access
const int NUM_SIGS_0 = 17; const int NUM_SIGS_0 = 18;
const int SIG_SIZE_0 = 3; const int SIG_SIZE_0 = 3;
uInt8 signature_0[NUM_SIGS_0][SIG_SIZE_0] = { uInt8 signature_0[NUM_SIGS_0][SIG_SIZE_0] = {
{ 0x24, 0x0a, 0x10 }, // bit INPT2; bpl (no joystick games) { 0x24, 0x0a, 0x10 }, // bit INPT2; bpl (no joystick games)
@ -464,6 +463,7 @@ bool ControllerDetector::usesPaddle(const uInt8* image, uInt32 size,
{ 0xb5, 0x38, 0x10 }, // lda INPT0|$30,x; bpl (Circus Atari, old code!) { 0xb5, 0x38, 0x10 }, // lda INPT0|$30,x; bpl (Circus Atari, old code!)
{ 0xb5, 0x38, 0x30 }, // lda INPT0|$30,x; bmi (no joystick games) { 0xb5, 0x38, 0x30 }, // lda INPT0|$30,x; bmi (no joystick games)
{ 0xa4, 0x3a, 0x30 }, // ldy INPT2|$30; bmi (no joystick games) { 0xa4, 0x3a, 0x30 }, // ldy INPT2|$30; bmi (no joystick games)
{ 0xa5, 0x3b, 0x30 }, // lda INPT3|$30; bmi (only Tac Scan, ports and paddles swapped)
}; };
const int NUM_SIGS_1 = 1; const int NUM_SIGS_1 = 1;
const int SIG_SIZE_1 = 4; const int SIG_SIZE_1 = 4;

View File

@ -282,6 +282,20 @@ class OSystem
*/ */
const FilesystemNode& romFile() const { return myRomFile; } const FilesystemNode& romFile() const { return myRomFile; }
/**
Open the given ROM and return an array containing its contents.
Also, the properties database is updated with a valid ROM name
for this ROM (if necessary).
@param rom The file node of the ROM to open (contains path)
@param md5 The md5 calculated from the ROM file
(will be recalculated if necessary)
@param size The amount of data read into the image array
@return Unique pointer to the array
*/
BytePtr openROM(const FilesystemNode& rom, string& md5, uInt32& size);
/** /**
Creates a new game console from the specified romfile, and correctly Creates a new game console from the specified romfile, and correctly
initializes the system state to start emulation of the Console. initializes the system state to start emulation of the Console.
@ -541,20 +555,6 @@ class OSystem
*/ */
void closeConsole(); void closeConsole();
/**
Open the given ROM and return an array containing its contents.
Also, the properties database is updated with a valid ROM name
for this ROM (if necessary).
@param rom The file node of the ROM to open (contains path)
@param md5 The md5 calculated from the ROM file
(will be recalculated if necessary)
@param size The amount of data read into the image array
@return Unique pointer to the array
*/
BytePtr openROM(const FilesystemNode& rom, string& md5, uInt32& size);
/** /**
Gets all possible info about the given console. Gets all possible info about the given console.

View File

@ -414,10 +414,15 @@ void GameInfoDialog::loadConsoleProperties(const Properties& props)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void GameInfoDialog::loadControllerProperties(const Properties& props) void GameInfoDialog::loadControllerProperties(const Properties& props)
{ {
bool swapPorts = props.get(Console_SwapPorts) == "YES";
myLeftPort->setSelected(props.get(Controller_Left), "AUTO"); myLeftPort->setSelected(props.get(Controller_Left), "AUTO");
if(instance().hasConsole() && myLeftPort->getSelectedTag().toString() == "AUTO") if(instance().hasConsole() && myLeftPort->getSelectedTag().toString() == "AUTO")
{ {
myLeftPortDetected->setLabel(instance().console().leftController().name() + " detected"); myLeftPortDetected->setLabel((!swapPorts
? instance().console().leftController().name()
: instance().console().rightController().name())
+ " detected");
} }
else else
myLeftPortDetected->setLabel(""); myLeftPortDetected->setLabel("");
@ -425,7 +430,10 @@ void GameInfoDialog::loadControllerProperties(const Properties& props)
myRightPort->setSelected(props.get(Controller_Right), "AUTO"); myRightPort->setSelected(props.get(Controller_Right), "AUTO");
if(instance().hasConsole() && myRightPort->getSelectedTag().toString() == "AUTO") if(instance().hasConsole() && myRightPort->getSelectedTag().toString() == "AUTO")
{ {
myRightPortDetected->setLabel(instance().console().rightController().name() + " detected"); myRightPortDetected->setLabel((!swapPorts
? instance().console().rightController().name()
: instance().console().leftController().name())
+ " detected");
} }
else else
myRightPortDetected->setLabel(""); myRightPortDetected->setLabel("");

View File

@ -249,7 +249,13 @@ void LauncherDialog::loadConfig()
Dialog::setFocus(getFocusList()[mySelectedItem]); Dialog::setFocus(getFocusList()[mySelectedItem]);
if(myRomInfoWidget) if(myRomInfoWidget)
myRomInfoWidget->loadConfig(); {
int item = myList->getSelected();
if(item < 0) return;
const FilesystemNode node(myGameList->path(item));
myRomInfoWidget->loadConfig(node);
}
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -339,7 +345,7 @@ void LauncherDialog::loadRomInfo()
Properties props; Properties props;
instance().propSet().getMD5WithInsert(node, myGameList->md5(item), props); instance().propSet().getMD5WithInsert(node, myGameList->md5(item), props);
myRomInfoWidget->setProperties(props); myRomInfoWidget->setProperties(props, node);
} }
else else
myRomInfoWidget->clearProperties(); myRomInfoWidget->clearProperties();

View File

@ -21,7 +21,7 @@
#include "FBSurface.hxx" #include "FBSurface.hxx"
#include "Font.hxx" #include "Font.hxx"
#include "OSystem.hxx" #include "OSystem.hxx"
#include "Settings.hxx" #include "ControllerDetector.hxx"
#include "Props.hxx" #include "Props.hxx"
#include "PNGLibrary.hxx" #include "PNGLibrary.hxx"
#include "Rect.hxx" #include "Rect.hxx"
@ -44,24 +44,24 @@ RomInfoWidget::RomInfoWidget(GuiObject* boss, const GUI::Font& font,
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void RomInfoWidget::loadConfig() void RomInfoWidget::loadConfig(const FilesystemNode& node)
{ {
// The ROM may have changed since we were last in the browser, either // The ROM may have changed since we were last in the browser, either
// by saving a different image or through a change in video renderer, // by saving a different image or through a change in video renderer,
// so we reload the properties // so we reload the properties
if(myHaveProperties) if(myHaveProperties)
parseProperties(); parseProperties(node);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void RomInfoWidget::setProperties(const Properties& props) void RomInfoWidget::setProperties(const Properties& props, const FilesystemNode& node)
{ {
myHaveProperties = true; myHaveProperties = true;
myProperties = props; myProperties = props;
// Decide whether the information should be shown immediately // Decide whether the information should be shown immediately
if(instance().eventHandler().state() == EventHandlerState::LAUNCHER) if(instance().eventHandler().state() == EventHandlerState::LAUNCHER)
parseProperties(); parseProperties(node);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -77,7 +77,7 @@ void RomInfoWidget::clearProperties()
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void RomInfoWidget::parseProperties() void RomInfoWidget::parseProperties(const FilesystemNode& node)
{ {
// Check if a surface has ever been created; if so, we use it // Check if a surface has ever been created; if so, we use it
// The surface will always be the maximum size, but sometimes we'll // The surface will always be the maximum size, but sometimes we'll
@ -125,9 +125,26 @@ void RomInfoWidget::parseProperties()
myRomInfo.push_back("Rarity: " + myProperties.get(Cartridge_Rarity)); myRomInfo.push_back("Rarity: " + myProperties.get(Cartridge_Rarity));
myRomInfo.push_back("Note: " + myProperties.get(Cartridge_Note)); myRomInfo.push_back("Note: " + myProperties.get(Cartridge_Note));
bool swappedPorts = myProperties.get(Console_SwapPorts) == "YES"; bool swappedPorts = myProperties.get(Console_SwapPorts) == "YES";
myRomInfo.push_back("Controllers: " + (!swappedPorts
? myProperties.get(Controller_Left) + " (left), " + myProperties.get(Controller_Right) + " (right)" string left = myProperties.get(Controller_Left);
: myProperties.get(Controller_Right) + " (left), " + myProperties.get(Controller_Left) + " (right)")); string right = myProperties.get(Controller_Right);
// load the image for auto detection
BytePtr image;
string md5 = myProperties.get(Cartridge_MD5);
uInt32 size = 0;
if(node.exists() && !node.isDirectory() && (image = instance().openROM(node, md5, size)) != nullptr)
{
left = ControllerDetector::detect(image.get(), size, left,
!swappedPorts ? Controller::Jack::Left : Controller::Jack::Right,
instance().settings());
right = ControllerDetector::detect(image.get(), size, right,
!swappedPorts ? Controller::Jack::Right : Controller::Jack::Left,
instance().settings());
}
myRomInfo.push_back("Controllers: " + (left + " (left), " + right + " (right)"));
#if 0 #if 0
myRomInfo.push_back("YStart/Height: " + myProperties.get(Display_YStart) + myRomInfo.push_back("YStart/Height: " + myProperties.get(Display_YStart) +
" " + myProperties.get(Display_Height)); " " + myProperties.get(Display_Height));

View File

@ -34,15 +34,15 @@ class RomInfoWidget : public Widget
int x, int y, int w, int h); int x, int y, int w, int h);
virtual ~RomInfoWidget() = default; virtual ~RomInfoWidget() = default;
void setProperties(const Properties& props); void setProperties(const Properties& props, const FilesystemNode& node);
void clearProperties(); void clearProperties();
void loadConfig() override; void loadConfig(const FilesystemNode& node);
protected: protected:
void drawWidget(bool hilite) override; void drawWidget(bool hilite) override;
private: private:
void parseProperties(); void parseProperties(const FilesystemNode& node);
private: private:
// Surface pointer holding the PNG image // Surface pointer holding the PNG image